Merge change 5750 into donut
* changes:
Add a new checkin server flag for Vending Machine client server ping frequency for pending downloads.
diff --git a/api/current.xml b/api/current.xml
index 673d053..1287f59 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3419,39 +3419,6 @@
visibility="public"
>
</field>
-<field name="donut_resource_pad23"
- type="int"
- transient="false"
- volatile="false"
- value="16843401"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad24"
- type="int"
- transient="false"
- volatile="false"
- value="16843400"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad25"
- type="int"
- transient="false"
- volatile="false"
- value="16843399"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="donut_resource_pad3"
type="int"
transient="false"
@@ -6730,6 +6697,17 @@
visibility="public"
>
</field>
+<field name="progressBarStyleInverse"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843399"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="progressBarStyleLarge"
type="int"
transient="false"
@@ -6741,6 +6719,17 @@
visibility="public"
>
</field>
+<field name="progressBarStyleLargeInverse"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843401"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="progressBarStyleSmall"
type="int"
transient="false"
@@ -6752,6 +6741,17 @@
visibility="public"
>
</field>
+<field name="progressBarStyleSmallInverse"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843400"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="progressBarStyleSmallTitle"
type="int"
transient="false"
@@ -15156,6 +15156,17 @@
visibility="public"
>
</field>
+<field name="Widget_ProgressBar_Inverse"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973915"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_ProgressBar_Large"
type="int"
transient="false"
@@ -15167,6 +15178,17 @@
visibility="public"
>
</field>
+<field name="Widget_ProgressBar_Large_Inverse"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973916"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_ProgressBar_Small"
type="int"
transient="false"
@@ -15178,6 +15200,17 @@
visibility="public"
>
</field>
+<field name="Widget_ProgressBar_Small_Inverse"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16973917"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_RatingBar"
type="int"
transient="false"
@@ -15409,39 +15442,6 @@
visibility="public"
>
</field>
-<field name="donut_resource_pad20"
- type="int"
- transient="false"
- volatile="false"
- value="16973917"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad21"
- type="int"
- transient="false"
- volatile="false"
- value="16973916"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad22"
- type="int"
- transient="false"
- volatile="false"
- value="16973915"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="donut_resource_pad3"
type="int"
transient="false"
@@ -31346,6 +31346,17 @@
visibility="public"
>
</field>
+<field name="ACTION_BATTERY_OKAY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.intent.action.BATTERY_OKAY""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_BOOT_COMPLETED"
type="java.lang.String"
transient="false"
@@ -56678,6 +56689,47 @@
</package>
<package name="android.graphics.drawable"
>
+<interface name="Animatable"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="isRunning"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="start"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="stop"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</interface>
<class name="AnimationDrawable"
extends="android.graphics.drawable.DrawableContainer"
abstract="false"
@@ -56686,6 +56738,8 @@
deprecated="not deprecated"
visibility="public"
>
+<implements name="android.graphics.drawable.Animatable">
+</implements>
<implements name="java.lang.Runnable">
</implements>
<constructor name="AnimationDrawable"
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 105d4d2..022fe5a 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -410,11 +410,14 @@
// pass the buffered ISurface to the camera service
status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
{
- LOGD("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
+ LOGD("setPreviewDisplay(%p) (pid %d)",
+ ((surface == NULL) ? NULL : surface.get()), getCallingPid());
Mutex::Autolock lock(mLock);
status_t result = checkPid();
if (result != NO_ERROR) return result;
+
Mutex::Autolock surfaceLock(mSurfaceLock);
+ result = NO_ERROR;
// asBinder() is safe on NULL (returns NULL)
if (surface->asBinder() != mSurface->asBinder()) {
if (mSurface != 0 && !mUseOverlay) {
@@ -422,8 +425,17 @@
mSurface->unregisterBuffers();
}
mSurface = surface;
+ // If preview has been already started, set overlay or register preview
+ // buffers now.
+ if (mHardware->previewEnabled()) {
+ if (mUseOverlay) {
+ result = setOverlay();
+ } else if (mSurface != 0) {
+ result = registerPreviewBuffers();
+ }
+ }
}
- return NO_ERROR;
+ return result;
}
// set the preview callback flag to affect how the received frames from
@@ -436,7 +448,7 @@
mPreviewCallbackFlag = callback_flag;
}
-// start preview mode, must call setPreviewDisplay first
+// start preview mode
status_t CameraService::Client::startCameraMode(camera_mode mode)
{
int callingPid = getCallingPid();
@@ -456,16 +468,18 @@
return INVALID_OPERATION;
}
- if (mSurface == 0) {
- LOGE("setPreviewDisplay must be called before startCameraMode!");
- return INVALID_OPERATION;
- }
-
switch(mode) {
case CAMERA_RECORDING_MODE:
+ if (mSurface == 0) {
+ LOGE("setPreviewDisplay must be called before startRecordingMode.");
+ return INVALID_OPERATION;
+ }
return startRecordingMode();
default: // CAMERA_PREVIEW_MODE
+ if (mSurface == 0) {
+ LOGD("mSurface is not set yet.");
+ }
return startPreviewMode();
}
}
@@ -498,6 +512,62 @@
return ret;
}
+status_t CameraService::Client::setOverlay()
+{
+ LOGD("setOverlay");
+ int w, h;
+ CameraParameters params(mHardware->getParameters());
+ params.getPreviewSize(&w, &h);
+
+ const char *format = params.getPreviewFormat();
+ int fmt;
+ if (!strcmp(format, "yuv422i"))
+ fmt = OVERLAY_FORMAT_YCbCr_422_I;
+ else if (!strcmp(format, "rgb565"))
+ fmt = OVERLAY_FORMAT_RGB_565;
+ else {
+ LOGE("Invalid preview format for overlays");
+ return -EINVAL;
+ }
+
+ status_t ret = NO_ERROR;
+ if (mSurface != 0) {
+ sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt);
+ ret = mHardware->setOverlay(new Overlay(ref));
+ } else {
+ ret = mHardware->setOverlay(NULL);
+ }
+ if (ret != NO_ERROR) {
+ LOGE("mHardware->setOverlay() failed with status %d\n", ret);
+ }
+ return ret;
+}
+
+status_t CameraService::Client::registerPreviewBuffers()
+{
+ int w, h;
+ CameraParameters params(mHardware->getParameters());
+ params.getPreviewSize(&w, &h);
+
+ uint32_t transform = 0;
+ if (params.getOrientation() ==
+ CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
+ LOGV("portrait mode");
+ transform = ISurface::BufferHeap::ROT_90;
+ }
+ ISurface::BufferHeap buffers(w, h, w, h,
+ PIXEL_FORMAT_YCbCr_420_SP,
+ transform,
+ 0,
+ mHardware->getPreviewHeap());
+
+ status_t ret = mSurface->registerBuffers(buffers);
+ if (ret != NO_ERROR) {
+ LOGE("registerBuffers failed with status %d", ret);
+ }
+ return ret;
+}
+
status_t CameraService::Client::startPreviewMode()
{
LOGD("startPreviewMode (pid %d)", getCallingPid());
@@ -511,55 +581,24 @@
#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
debug_frame_cnt = 0;
#endif
- status_t ret = UNKNOWN_ERROR;
- int w, h;
- CameraParameters params(mHardware->getParameters());
- params.getPreviewSize(&w, &h);
+ status_t ret = NO_ERROR;
if (mUseOverlay) {
- const char *format = params.getPreviewFormat();
- int fmt;
- LOGD("Use Overlays");
- if (!strcmp(format, "yuv422i"))
- fmt = OVERLAY_FORMAT_YCbCr_422_I;
- else if (!strcmp(format, "rgb565"))
- fmt = OVERLAY_FORMAT_RGB_565;
- else {
- LOGE("Invalid preview format for overlays");
- return -EINVAL;
+ // If preview display has been set, set overlay now.
+ if (mSurface != 0) {
+ ret = setOverlay();
}
- sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt);
- ret = mHardware->setOverlay(new Overlay(ref));
- if (ret != NO_ERROR) {
- LOGE("mHardware->setOverlay() failed with status %d\n", ret);
- return ret;
- }
+ if (ret != NO_ERROR) return ret;
ret = mHardware->startPreview(NULL, mCameraService.get());
- if (ret != NO_ERROR)
- LOGE("mHardware->startPreview() failed with status %d\n", ret);
-
} else {
ret = mHardware->startPreview(previewCallback,
mCameraService.get());
- if (ret == NO_ERROR) {
-
- mSurface->unregisterBuffers();
-
- uint32_t transform = 0;
- if (params.getOrientation() ==
- CameraParameters::CAMERA_ORIENTATION_PORTRAIT) {
- LOGV("portrait mode");
- transform = ISurface::BufferHeap::ROT_90;
- }
- ISurface::BufferHeap buffers(w, h, w, h,
- PIXEL_FORMAT_YCbCr_420_SP,
- transform,
- 0,
- mHardware->getPreviewHeap());
-
- mSurface->registerBuffers(buffers);
- } else {
- LOGE("mHardware->startPreview() failed with status %d", ret);
+ if (ret != NO_ERROR) return ret;
+ // If preview display has been set, register preview buffers now.
+ if (mSurface != 0) {
+ // Unregister here because the surface registered with raw heap.
+ mSurface->unregisterBuffers();
+ ret = registerPreviewBuffers();
}
}
return ret;
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 8b8b54c..0f07673 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -157,6 +157,8 @@
status_t startCameraMode(camera_mode mode);
status_t startPreviewMode();
status_t startRecordingMode();
+ status_t setOverlay();
+ status_t registerPreviewBuffers();
// Ensures atomicity among the public methods
mutable Mutex mLock;
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 6fe4896..44d1eaa 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -34,6 +34,7 @@
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Animatable;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
@@ -422,11 +423,11 @@
if (working) {
mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
null, null, mWorkingSpinner, null);
-// mWorkingSpinner.start();
+ ((Animatable) mWorkingSpinner).start();
} else {
mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
null, null, null, null);
-// mWorkingSpinner.stop();
+ ((Animatable) mWorkingSpinner).stop();
}
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6fe5506..6b723bc 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1290,6 +1290,13 @@
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
/**
+ * Broadcast Action: Indicates the battery is now okay after being low.
+ * This will be sent after {@link #ACTION_BATTERY_LOW} once the battery has
+ * gone back up to an okay state.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_BATTERY_OKAY = "android.intent.action.BATTERY_OKAY";
+ /**
* Broadcast Action: External power has been connected to the device.
* This is intended for applications that wish to register specifically to this notification.
* Unlike ACTION_BATTERY_CHANGED, applications will be woken for this and so do not have to
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 09fbc97..3ce951f 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -155,7 +155,11 @@
* @throws IOException if the method fails.
*/
public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
- setPreviewDisplay(holder.getSurface());
+ if (holder != null) {
+ setPreviewDisplay(holder.getSurface());
+ } else {
+ setPreviewDisplay((Surface)null);
+ }
}
private native final void setPreviewDisplay(Surface surface);
diff --git a/core/java/android/net/http/RequestHandle.java b/core/java/android/net/http/RequestHandle.java
index c4ee5b0..6a97951 100644
--- a/core/java/android/net/http/RequestHandle.java
+++ b/core/java/android/net/http/RequestHandle.java
@@ -159,11 +159,11 @@
e.printStackTrace();
}
- // update the "cookie" header based on the redirected url
- mHeaders.remove("cookie");
+ // update the "Cookie" header based on the redirected url
+ mHeaders.remove("Cookie");
String cookie = CookieManager.getInstance().getCookie(mUri);
if (cookie != null && cookie.length() > 0) {
- mHeaders.put("cookie", cookie);
+ mHeaders.put("Cookie", cookie);
}
if ((statusCode == 302 || statusCode == 303) && mMethod.equals("POST")) {
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 51d1951..bc7b5be 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -344,7 +344,10 @@
// Check if file exists with a FileInputStream
FileInputStream stream = new FileInputStream(imagePath);
try {
- return insertImage(cr, BitmapFactory.decodeFile(imagePath), name, description);
+ Bitmap bm = BitmapFactory.decodeFile(imagePath);
+ String ret = insertImage(cr, bm, name, description);
+ bm.recycle();
+ return ret;
} finally {
try {
stream.close();
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index 6f1b160..66ab021 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -364,7 +364,7 @@
String cookie = CookieManager.getInstance().getCookie(
mListener.getWebAddress());
if (cookie != null && cookie.length() > 0) {
- mHeaders.put("cookie", cookie);
+ mHeaders.put("Cookie", cookie);
}
}
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 441414a..2c9e71e 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -30,6 +30,7 @@
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
+import android.graphics.drawable.Animatable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.graphics.drawable.shapes.Shape;
import android.util.AttributeSet;
@@ -683,7 +684,7 @@
return;
}
- if (mIndeterminateDrawable instanceof AnimationDrawable) {
+ if (mIndeterminateDrawable instanceof Animatable) {
mShouldStartAnimationDrawable = true;
mAnimation = null;
} else {
@@ -708,8 +709,8 @@
void stopAnimation() {
mAnimation = null;
mTransformation = null;
- if (mIndeterminateDrawable instanceof AnimationDrawable) {
- ((AnimationDrawable) mIndeterminateDrawable).stop();
+ if (mIndeterminateDrawable instanceof Animatable) {
+ ((Animatable) mIndeterminateDrawable).stop();
mShouldStartAnimationDrawable = false;
}
}
@@ -818,8 +819,8 @@
}
d.draw(canvas);
canvas.restore();
- if (mShouldStartAnimationDrawable && d instanceof AnimationDrawable) {
- ((AnimationDrawable) d).start();
+ if (mShouldStartAnimationDrawable && d instanceof Animatable) {
+ ((Animatable) d).start();
mShouldStartAnimationDrawable = false;
}
}
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 8e48b38..3dcc09f 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -171,6 +171,10 @@
// VM pointer will be NULL if object is released
Mutex::Autolock _l(mLock);
JNIEnv *env = AndroidRuntime::getJNIEnv();
+ if (mCameraJObjectWeak == NULL) {
+ LOGW("callback on dead camera object");
+ return;
+ }
// return data based on callback type
switch(msgType) {
@@ -262,7 +266,10 @@
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
- sp<Surface> surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
+ sp<Surface> surface = NULL;
+ if (jSurface != NULL) {
+ surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
+ }
if (camera->setPreviewDisplay(surface) != NO_ERROR) {
jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");
}
diff --git a/core/res/res/drawable/progress_large.xml b/core/res/res/drawable/progress_large.xml
index 4669104..4f016bc 100644
--- a/core/res/res/drawable/progress_large.xml
+++ b/core/res/res/drawable/progress_large.xml
@@ -1,45 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
-->
-
-
-<rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:pivotX="50%" android:pivotY="50%"
- android:fromDegrees="0" android:toDegrees="360">
-
- <shape
- android:shape="ring"
- android:innerRadiusRatio="3"
- android:thicknessRatio="8"
- android:useLevel="false">
-
- <size
- android:width="76dip"
- android:height="76dip"
- />
-
- <gradient
- android:type="sweep"
- android:useLevel="false"
- android:startColor="#4c737373"
- android:centerColor="#4c737373"
- android:centerY="0.50"
- android:endColor="#ffffd300"
- />
-
- </shape>
-
-</rotate>
-
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/spinner_black_76"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:framesCount="12"
+ android:frameDuration="100" />
diff --git a/core/res/res/drawable/progress_large_white.xml b/core/res/res/drawable/progress_large_white.xml
new file mode 100644
index 0000000..c690ed4
--- /dev/null
+++ b/core/res/res/drawable/progress_large_white.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
+-->
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/spinner_white_76"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:framesCount="12"
+ android:frameDuration="100" />
diff --git a/core/res/res/drawable/progress_medium.xml b/core/res/res/drawable/progress_medium.xml
index 92aebb5..eb1bd50 100644
--- a/core/res/res/drawable/progress_medium.xml
+++ b/core/res/res/drawable/progress_medium.xml
@@ -1,43 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
-->
-
-<rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:pivotX="50%" android:pivotY="50%"
- android:fromDegrees="0" android:toDegrees="360">
-
- <shape
- android:shape="ring"
- android:innerRadiusRatio="3"
- android:thicknessRatio="8"
- android:useLevel="false">
-
- <size
- android:width="48dip"
- android:height="48dip"
- />
-
- <gradient
- android:type="sweep"
- android:useLevel="false"
- android:startColor="#4c737373"
- android:centerColor="#4c737373"
- android:centerY="0.50"
- android:endColor="#ffffd300"
- />
-
- </shape>
-
-</rotate>
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/spinner_black_48"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:framesCount="12"
+ android:frameDuration="100" />
diff --git a/core/res/res/drawable/progress_medium_white.xml b/core/res/res/drawable/progress_medium_white.xml
new file mode 100644
index 0000000..b4f9b31
--- /dev/null
+++ b/core/res/res/drawable/progress_medium_white.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
+-->
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/spinner_white_48"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:framesCount="12"
+ android:frameDuration="100" />
diff --git a/core/res/res/drawable/progress_small.xml b/core/res/res/drawable/progress_small.xml
index e5b0021..e0ee5e4 100644
--- a/core/res/res/drawable/progress_small.xml
+++ b/core/res/res/drawable/progress_small.xml
@@ -1,45 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
-->
-
-
-<rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:pivotX="50%" android:pivotY="50%"
- android:fromDegrees="0" android:toDegrees="360">
-
- <!-- An extra pixel is added on both ratios for stroke -->
- <shape
- android:shape="ring"
- android:innerRadiusRatio="3.2"
- android:thicknessRatio="5.333"
- android:useLevel="false">
-
- <size
- android:width="16dip"
- android:height="16dip"
- />
-
- <gradient
- android:type="sweep"
- android:useLevel="false"
- android:startColor="#4c737373"
- android:centerColor="#4c737373"
- android:centerY="0.50"
- android:endColor="#ffffd300"
- />
-
- </shape>
-
-</rotate>
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/spinner_black_16"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:framesCount="12"
+ android:frameDuration="100" />
diff --git a/core/res/res/drawable/progress_small_titlebar.xml b/core/res/res/drawable/progress_small_titlebar.xml
index cf8e41cb..8cfba86 100644
--- a/core/res/res/drawable/progress_small_titlebar.xml
+++ b/core/res/res/drawable/progress_small_titlebar.xml
@@ -1,45 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 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.
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
-->
-
-
-<rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:pivotX="50%" android:pivotY="50%"
- android:fromDegrees="0" android:toDegrees="360">
-
- <!-- An extra pixel is added on both ratios for stroke -->
- <shape
- android:shape="ring"
- android:innerRadiusRatio="3.2"
- android:thicknessRatio="5.333"
- android:useLevel="false">
-
- <size
- android:width="16dip"
- android:height="16dip"
- />
-
- <gradient
- android:type="sweep"
- android:useLevel="false"
- android:startColor="#ff666666"
- android:centerColor="#ff666666"
- android:centerY="0.50"
- android:endColor="#ffffd300"
- />
-
- </shape>
-
-</rotate>
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/spinner_white_16"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:framesCount="12"
+ android:frameDuration="100" />
diff --git a/core/res/res/drawable/progress_small_white.xml b/core/res/res/drawable/progress_small_white.xml
new file mode 100644
index 0000000..8cfba86
--- /dev/null
+++ b/core/res/res/drawable/progress_small_white.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
+-->
+<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/spinner_white_16"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:framesCount="12"
+ android:frameDuration="100" />
diff --git a/core/res/res/drawable/spinner_black_16.png b/core/res/res/drawable/spinner_black_16.png
new file mode 100644
index 0000000..5ee33ce
--- /dev/null
+++ b/core/res/res/drawable/spinner_black_16.png
Binary files differ
diff --git a/core/res/res/drawable/spinner_black_48.png b/core/res/res/drawable/spinner_black_48.png
new file mode 100644
index 0000000..3a68192
--- /dev/null
+++ b/core/res/res/drawable/spinner_black_48.png
Binary files differ
diff --git a/core/res/res/drawable/spinner_black_76.png b/core/res/res/drawable/spinner_black_76.png
new file mode 100644
index 0000000..ec57460
--- /dev/null
+++ b/core/res/res/drawable/spinner_black_76.png
Binary files differ
diff --git a/core/res/res/drawable/spinner_white_16.png b/core/res/res/drawable/spinner_white_16.png
new file mode 100644
index 0000000..dd2e1fd
--- /dev/null
+++ b/core/res/res/drawable/spinner_white_16.png
Binary files differ
diff --git a/core/res/res/drawable/spinner_white_48.png b/core/res/res/drawable/spinner_white_48.png
new file mode 100644
index 0000000..d25a33e
--- /dev/null
+++ b/core/res/res/drawable/spinner_white_48.png
Binary files differ
diff --git a/core/res/res/drawable/spinner_white_76.png b/core/res/res/drawable/spinner_white_76.png
new file mode 100644
index 0000000..f53e8ff
--- /dev/null
+++ b/core/res/res/drawable/spinner_white_76.png
Binary files differ
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d070107..3e93b02 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -350,6 +350,12 @@
<attr name="progressBarStyleSmallTitle" format="reference" />
<!-- Large ProgressBar style. This is a large circular progress bar. -->
<attr name="progressBarStyleLarge" format="reference" />
+ <!-- Inverse ProgressBar style. This is a medium circular progress bar. -->
+ <attr name="progressBarStyleInverse" format="reference" />
+ <!-- Small inverse ProgressBar style. This is a small circular progress bar. -->
+ <attr name="progressBarStyleSmallInverse" format="reference" />
+ <!-- Large inverse ProgressBar style. This is a large circular progress bar. -->
+ <attr name="progressBarStyleLargeInverse" format="reference" />
<!-- Default SeekBar style. -->
<attr name="seekBarStyle" format="reference" />
<!-- Default RatingBar style. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 14d8dbe..2121669 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1120,11 +1120,17 @@
<public type="attr" name="smallScreens" />
<public type="attr" name="normalScreens" />
<public type="attr" name="largeScreens" />
+ <public type="attr" name="progressBarStyleInverse" />
+ <public type="attr" name="progressBarStyleSmallInverse" />
+ <public type="attr" name="progressBarStyleLargeInverse" />
<public-padding type="attr" name="donut_resource_pad" end="0x0101029f" />
<public-padding type="id" name="donut_resource_pad" end="0x01020040" />
+ <public type="style" name="Widget.ProgressBar.Inverse" id="0x0103005b" />
+ <public type="style" name="Widget.ProgressBar.Large.Inverse" id="0x0103005c" />
+ <public type="style" name="Widget.ProgressBar.Small.Inverse" id="0x0103005d" />
<public-padding type="style" name="donut_resource_pad" end="0x01030070" />
<public-padding type="string" name="donut_resource_pad" end="0x01040030" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9f1ed40..1ce9c76 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1786,6 +1786,11 @@
<!-- See EXTMEDIA_FORMAT. This is the button text to format the sd card. -->
<string name="extmedia_format_button_format">Format</string>
+ <!-- Title of notification shown when ADB is actively connected to the phone. -->
+ <string name="adb_active_notification_title">USB debugging connected</string>
+ <!-- Message of notification shown when ADB is actively connected to the phone. -->
+ <string name="adb_active_notification_message">A computer is connected to your phone.</string>
+
<!-- Used to replace %s in urls retreived from the signin server with locales. For Some -->
<!-- devices we don't support all the locales we ship to and need to replace the '%s' with a -->
<!-- locale string based on mcc values. By default (0-length string) we don't replace the %s -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 648a7dd..7d235ec 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -243,7 +243,7 @@
<style name="Widget.ProgressBar">
<item name="android:indeterminateOnly">true</item>
- <item name="android:indeterminateDrawable">@android:drawable/progress_medium</item>
+ <item name="android:indeterminateDrawable">@android:drawable/progress_medium_white</item>
<item name="android:indeterminateBehavior">repeat</item>
<item name="android:indeterminateDuration">3500</item>
<item name="android:minWidth">48dip</item>
@@ -253,7 +253,7 @@
</style>
<style name="Widget.ProgressBar.Large">
- <item name="android:indeterminateDrawable">@android:drawable/progress_large</item>
+ <item name="android:indeterminateDrawable">@android:drawable/progress_large_white</item>
<item name="android:minWidth">76dip</item>
<item name="android:maxWidth">76dip</item>
<item name="android:minHeight">76dip</item>
@@ -261,13 +261,25 @@
</style>
<style name="Widget.ProgressBar.Small">
- <item name="android:indeterminateDrawable">@android:drawable/progress_small</item>
+ <item name="android:indeterminateDrawable">@android:drawable/progress_small_white</item>
<item name="android:minWidth">16dip</item>
<item name="android:maxWidth">16dip</item>
<item name="android:minHeight">16dip</item>
<item name="android:maxHeight">16dip</item>
</style>
+ <style name="Widget.ProgressBar.Inverse">
+ <item name="android:indeterminateDrawable">@android:drawable/progress_medium</item>
+ </style>
+
+ <style name="Widget.ProgressBar.Large.Inverse">
+ <item name="android:indeterminateDrawable">@android:drawable/progress_large</item>
+ </style>
+
+ <style name="Widget.ProgressBar.Small.Inverse">
+ <item name="android:indeterminateDrawable">@android:drawable/progress_small</item>
+ </style>
+
<style name="Widget.ProgressBar.Small.Title">
<item name="android:indeterminateDrawable">@android:drawable/progress_small_titlebar</item>
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index f37d514..bd6e1df 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -154,6 +154,9 @@
<item name="progressBarStyleSmall">@android:style/Widget.ProgressBar.Small</item>
<item name="progressBarStyleSmallTitle">@android:style/Widget.ProgressBar.Small.Title</item>
<item name="progressBarStyleLarge">@android:style/Widget.ProgressBar.Large</item>
+ <item name="progressBarStyleInverse">@android:style/Widget.ProgressBar.Inverse</item>
+ <item name="progressBarStyleSmallInverse">@android:style/Widget.ProgressBar.Small.Inverse</item>
+ <item name="progressBarStyleLargeInverse">@android:style/Widget.ProgressBar.Large.Inverse</item>
<item name="seekBarStyle">@android:style/Widget.SeekBar</item>
<item name="ratingBarStyle">@android:style/Widget.RatingBar</item>
<item name="ratingBarStyleIndicator">@android:style/Widget.RatingBar.Indicator</item>
@@ -233,6 +236,13 @@
<item name="listViewStyle">@android:style/Widget.ListView.White</item>
<item name="listDivider">@drawable/divider_horizontal_bright</item>
<item name="listSeparatorTextViewStyle">@android:style/Widget.TextView.ListSeparator.White</item>
+
+ <item name="progressBarStyle">@android:style/Widget.ProgressBar.Inverse</item>
+ <item name="progressBarStyleSmall">@android:style/Widget.ProgressBar.Small.Inverse</item>
+ <item name="progressBarStyleLarge">@android:style/Widget.ProgressBar.Large.Inverse</item>
+ <item name="progressBarStyleInverse">@android:style/Widget.ProgressBar</item>
+ <item name="progressBarStyleSmallInverse">@android:style/Widget.ProgressBar.Small</item>
+ <item name="progressBarStyleLargeInverse">@android:style/Widget.ProgressBar.Large</item>
</style>
<!-- Variant of the light theme with no title bar -->
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 2b24ef2..778c903 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -57,7 +57,9 @@
mBitmap = patch.mBitmap;
mChunk = patch.mChunk;
mSrcName = patch.mSrcName;
- mPaint = new Paint(patch.mPaint);
+ if (patch.mPaint != null) {
+ mPaint = new Paint(patch.mPaint);
+ }
validateNinePatchChunk(mBitmap.ni(), mChunk);
}
@@ -120,7 +122,6 @@
public native static boolean isNinePatchChunk(byte[] chunk);
- private final Rect mRect = new Rect();
private final Bitmap mBitmap;
private final byte[] mChunk;
private Paint mPaint;
diff --git a/graphics/java/android/graphics/drawable/Animatable.java b/graphics/java/android/graphics/drawable/Animatable.java
new file mode 100644
index 0000000..9dc62c3
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/Animatable.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+/**
+ * Interface that drawables suporting animations should implement.
+ */
+public interface Animatable {
+ /**
+ * Starts the drawable's animation.
+ */
+ void start();
+
+ /**
+ * Stops the drawable's animation.
+ */
+ void stop();
+
+ /**
+ * Indicates whether the animation is running.
+ *
+ * @return True if the animation is running, false otherwise.
+ */
+ boolean isRunning();
+}
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index 08d295d..ac96f20 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -35,11 +35,14 @@
/**
* @hide
*/
-public class AnimatedRotateDrawable extends Drawable implements Drawable.Callback, Runnable {
+public class AnimatedRotateDrawable extends Drawable implements Drawable.Callback, Runnable,
+ Animatable {
+
private AnimatedRotateState mState;
private boolean mMutated;
private float mCurrentDegrees;
private float mIncrement;
+ private boolean mRunning;
public AnimatedRotateDrawable() {
this(null);
@@ -80,10 +83,24 @@
drawable.draw(canvas);
canvas.restoreToCount(saveCount);
-
- nextFrame();
}
-
+
+ public void start() {
+ if (!mRunning) {
+ mRunning = true;
+ nextFrame();
+ }
+ }
+
+ public void stop() {
+ mRunning = false;
+ unscheduleSelf(this);
+ }
+
+ public boolean isRunning() {
+ return mRunning;
+ }
+
private void nextFrame() {
unscheduleSelf(this);
scheduleSelf(this, SystemClock.uptimeMillis() + mState.mFrameDuration);
@@ -96,8 +113,8 @@
if (mCurrentDegrees > (360.0f - mIncrement)) {
mCurrentDegrees = 0.0f;
}
- nextFrame();
invalidateSelf();
+ nextFrame();
}
@Override
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index bab1703..68718c9 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -71,7 +71,7 @@
* @attr ref android.R.styleable#AnimationDrawableItem_duration
* @attr ref android.R.styleable#AnimationDrawableItem_drawable
*/
-public class AnimationDrawable extends DrawableContainer implements Runnable {
+public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
private final AnimationState mAnimationState;
private int mCurFrame = -1;
private boolean mMutated;
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index bb22dab..a481ce7 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -149,21 +149,21 @@
status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
{
LOGV("setPreviewDisplay");
- if (surface == 0) {
- LOGE("app passed NULL surface");
- return NO_INIT;
- }
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
- return c->setPreviewDisplay(surface->getISurface());
+ if (surface != 0) {
+ return c->setPreviewDisplay(surface->getISurface());
+ } else {
+ LOGD("app passed NULL surface");
+ return c->setPreviewDisplay(0);
+ }
}
status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
{
LOGV("setPreviewDisplay");
if (surface == 0) {
- LOGE("app passed NULL surface");
- return NO_INIT;
+ LOGD("app passed NULL surface");
}
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
@@ -171,7 +171,7 @@
}
-// start preview mode, must call setPreviewDisplay first
+// start preview mode
status_t Camera::startPreview()
{
LOGV("startPreview");
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index fd3a4ba..e76967d 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -501,4 +501,6 @@
"http://sridharg.googlejunta.com/yslau/stress_media/mp3_regular.mp3";
public static final String STREAM_MPEG4_QVGA_128k =
"http://sridharg.googlejunta.com/yslau/stress_media/mpeg4_qvga_24fps.3gp";
+ public static final int STREAM_H264_480_360_1411k_DURATION = 46000;
+ public static final int VIDEO_H263_AAC_DURATION = 501000;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
index 12eacd3..ae9e102 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
@@ -19,6 +19,7 @@
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.MediaRecorderStressTest;
+import com.android.mediaframeworktest.stress.MediaPlayerStressTest;
import junit.framework.TestSuite;
@@ -28,6 +29,7 @@
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MediaRecorderStressTest.class);
+ suite.addTestSuite(MediaPlayerStressTest.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
new file mode 100644
index 0000000..5e213d7
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 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.mediaframeworktest.stress;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+
+import android.hardware.Camera;
+import android.media.MediaPlayer;
+import android.media.MediaRecorder;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import com.android.mediaframeworktest.MediaNames;
+
+import java.util.Random;
+
+/**
+ * Junit / Instrumentation test case for the media player
+ */
+public class MediaPlayerStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private String TAG = "MediaPlayerStressTest";
+ private MediaRecorder mRecorder;
+ private Camera mCamera;
+
+ private static final int NUMBER_OF_RANDOM_REPOSITION_AND_PLAY = 10;
+ private static final int NUMBER_OF_RANDOM_REPOSITION_AND_PLAY_SHORT = 5;
+ private static final int NUMBER_OF_STRESS_LOOPS = 1000;
+ private static final int PLAYBACK_END_TOLERANCE = 5000;
+ private static final int WAIT_UNTIL_PLAYBACK_FINISH = 515000 ;
+
+ public MediaPlayerStressTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ protected void setUp() throws Exception {
+ getActivity();
+ super.setUp();
+ }
+
+ @LargeTest
+ public void testStressHWDecoderRelease() throws Exception {
+ SurfaceHolder mSurfaceHolder;
+ long randomseed = System.currentTimeMillis();
+ Random generator = new Random(randomseed);
+ Log.v(TAG, "Random seed: " + randomseed);
+ int video_duration = MediaNames.STREAM_H264_480_360_1411k_DURATION;
+ int random_play_time;
+
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ try {
+ for (int i = 0; i < NUMBER_OF_STRESS_LOOPS; i++) {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(MediaNames.STREAM_H264_480_360_1411k);
+ mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
+ mp.prepare();
+ mp.start();
+ // seek and play
+ for (int j = 0; j < generator.nextInt(10); j++) {
+ random_play_time =
+ generator.nextInt(MediaNames.STREAM_H264_480_360_1411k_DURATION / 2);
+ Log.v(TAG, "Play time = " + random_play_time);
+ Thread.sleep(random_play_time);
+ int seek_time = MediaNames.STREAM_H264_480_360_1411k_DURATION / 2;
+ Log.v(TAG, "Seek time = " + seek_time);
+ mp.seekTo(seek_time);
+ }
+ mp.release();
+ }
+
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+
+ @LargeTest
+ public void testStressGetCurrentPosition() throws Exception {
+ SurfaceHolder mSurfaceHolder;
+ long randomseed = System.currentTimeMillis();
+ Random generator = new Random(randomseed);
+ Log.v(TAG, "Random seed: " + randomseed);
+ int video_duration = MediaNames.VIDEO_H263_AAC_DURATION;
+ int random_play_time = 0;
+ int random_seek_time = 0;
+
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ try {
+ for (int i = 0; i < NUMBER_OF_STRESS_LOOPS; i++) {
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(MediaNames.VIDEO_H263_AMR);
+ mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
+ mp.prepare();
+ mp.start();
+ // Random seek and play
+ for (int j = 0; j < generator.nextInt(10); j++) {
+ random_play_time =
+ generator.nextInt(video_duration / 2);
+ Log.v(TAG, "Play time = " + random_play_time);
+ Thread.sleep(random_play_time);
+ random_seek_time =
+ generator.nextInt(video_duration / 2);
+ Log.v(TAG, "Seek time = " + random_seek_time);
+ mp.seekTo(random_seek_time);
+ }
+ //wait until the movie finish and check the current position
+ //Make sure the wait time is long enough
+ long wait_until_playback_finish = video_duration - random_seek_time + PLAYBACK_END_TOLERANCE * 2;
+ Thread.sleep(wait_until_playback_finish);
+ Log.v(TAG, "CurrentPosition = " + mp.getCurrentPosition());
+ if ( mp.isPlaying() || mp.getCurrentPosition() > (video_duration + PLAYBACK_END_TOLERANCE)){
+ assertTrue("Current PlayTime greater than duration", false);
+ }
+ mp.release();
+ }
+
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+}
+
diff --git a/packages/TtsService/AndroidManifest.xml b/packages/TtsService/AndroidManifest.xml
index 1dc25c6..fab2534 100755
--- a/packages/TtsService/AndroidManifest.xml
+++ b/packages/TtsService/AndroidManifest.xml
@@ -12,4 +12,5 @@
</service>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 69ba062..a55b704 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -199,6 +199,7 @@
if (wav == NULL) {
delete pForAfter;
LOGV("Null: speech has completed");
+ return TTS_CALLBACK_HALT;
}
if (bufferSize > 0){
fwrite(wav, 1, bufferSize, pForAfter->outputFile);
@@ -213,8 +214,12 @@
// this struct was allocated in the original android_tts_SynthProxy_speak call,
// all processing matching this call is now done.
LOGV("Speech synthesis done.");
- delete pForAfter;
- pForAfter = NULL;
+ if (pForAfter->usageMode == USAGEMODE_PLAY_IMMEDIATELY) {
+ // only delete for direct playback. When writing to a file, we still have work to do
+ // in android_tts_SynthProxy_synthesizeToFile. The struct will be deleted there.
+ delete pForAfter;
+ pForAfter = NULL;
+ }
return TTS_CALLBACK_HALT;
}
@@ -397,7 +402,6 @@
}
-// TODO: Refactor this to get rid of any assumptions about sample rate, etc.
static void
android_tts_SynthProxy_synthesizeToFile(JNIEnv *env, jobject thiz, jint jniData,
jstring textJavaString, jstring filenameJavaString)
@@ -408,6 +412,21 @@
}
SynthProxyJniStorage* pSynthData = (SynthProxyJniStorage*)jniData;
+ if (!pSynthData->mNativeSynthInterface) {
+ LOGE("android_tts_SynthProxy_synthesizeToFile(): invalid engine handle");
+ return;
+ }
+
+ // Retrieve audio parameters before writing the file header
+ AudioSystem::audio_format encoding = DEFAULT_TTS_FORMAT;
+ uint32_t rate = DEFAULT_TTS_RATE;
+ int channels = DEFAULT_TTS_NB_CHANNELS;
+ pSynthData->mNativeSynthInterface->setAudioFormat(encoding, rate, channels);
+
+ if ((encoding != AudioSystem::PCM_16_BIT) && (encoding != AudioSystem::PCM_8_BIT)) {
+ LOGE("android_tts_SynthProxy_synthesizeToFile(): engine uses invalid format");
+ return;
+ }
const char *filenameNativeString =
env->GetStringUTFChars(filenameJavaString, 0);
@@ -419,6 +438,12 @@
pForAfter->outputFile = fopen(filenameNativeString, "wb");
+ if (pForAfter->outputFile == NULL) {
+ LOGE("android_tts_SynthProxy_synthesizeToFile(): error creating output file");
+ delete pForAfter;
+ return;
+ }
+
// Write 44 blank bytes for WAV header, then come back and fill them in
// after we've written the audio data
char header[44];
@@ -427,10 +452,8 @@
unsigned int unique_identifier;
// TODO check return codes
- if (pSynthData->mNativeSynthInterface) {
- pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer, pSynthData->mBufferSize,
- (void *)pForAfter);
- }
+ pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer,
+ pSynthData->mBufferSize, (void *)pForAfter);
long filelen = ftell(pForAfter->outputFile);
@@ -452,12 +475,14 @@
((uint32_t *)(&header[16]))[0] = 16; // size of fmt
+ int sampleSizeInByte = (encoding == AudioSystem::PCM_16_BIT ? 2 : 1);
+
((unsigned short *)(&header[20]))[0] = 1; // format
- ((unsigned short *)(&header[22]))[0] = 1; // channels
- ((uint32_t *)(&header[24]))[0] = 22050; // samplerate
- ((uint32_t *)(&header[28]))[0] = 44100; // byterate
- ((unsigned short *)(&header[32]))[0] = 2; // block align
- ((unsigned short *)(&header[34]))[0] = 16; // bits per sample
+ ((unsigned short *)(&header[22]))[0] = channels; // channels
+ ((uint32_t *)(&header[24]))[0] = rate; // samplerate
+ ((uint32_t *)(&header[28]))[0] = rate * sampleSizeInByte * channels;// byterate
+ ((unsigned short *)(&header[32]))[0] = sampleSizeInByte * channels; // block align
+ ((unsigned short *)(&header[34]))[0] = sampleSizeInByte * 8; // bits per sample
header[36] = 'd';
header[37] = 'a';
@@ -473,6 +498,9 @@
fflush(pForAfter->outputFile);
fclose(pForAfter->outputFile);
+ delete pForAfter;
+ pForAfter = NULL;
+
env->ReleaseStringUTFChars(textJavaString, textNativeString);
env->ReleaseStringUTFChars(filenameJavaString, filenameNativeString);
}
@@ -500,8 +528,8 @@
if (pSynthData->mNativeSynthInterface) {
const char *textNativeString = env->GetStringUTFChars(textJavaString, 0);
- pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer, pSynthData->mBufferSize,
- (void *)pForAfter);
+ pSynthData->mNativeSynthInterface->synthesizeText(textNativeString, pSynthData->mBuffer,
+ pSynthData->mBufferSize, (void *)pForAfter);
env->ReleaseStringUTFChars(textJavaString, textNativeString);
}
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 4a2808b..854138c 100644
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -25,15 +25,20 @@
import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.Notification;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentQueryMap;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.media.AsyncPlayer;
import android.media.AudioManager;
import android.net.Uri;
@@ -88,6 +93,12 @@
private NotificationRecord mVibrateNotification;
private Vibrator mVibrator = new Vibrator();
+ // adb
+ private int mBatteryPlugged;
+ private boolean mAdbEnabled = false;
+ private boolean mAdbNotificationShown = false;
+ private Notification mAdbNotification;
+
private ArrayList<NotificationRecord> mNotificationList;
private ArrayList<ToastRecord> mToastQueue;
@@ -297,6 +308,9 @@
mBatteryFull = batteryFull;
updateLights();
}
+
+ mBatteryPlugged = intent.getIntExtra("plugged", 0);
+ updateAdbNotification();
} else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
|| action.equals(Intent.ACTION_PACKAGE_RESTARTED)) {
Uri uri = intent.getData();
@@ -312,6 +326,31 @@
}
};
+ class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.ADB_ENABLED), false, this);
+ update();
+ }
+
+ @Override public void onChange(boolean selfChange) {
+ update();
+ }
+
+ public void update() {
+ ContentResolver resolver = mContext.getContentResolver();
+ mAdbEnabled = Settings.Secure.getInt(resolver,
+ Settings.Secure.ADB_ENABLED, 0) != 0;
+ updateAdbNotification();
+ }
+ }
+ private final SettingsObserver mSettingsObserver;
+
NotificationManagerService(Context context, StatusBarService statusBar,
HardwareService hardware)
{
@@ -333,6 +372,9 @@
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
mContext.registerReceiver(mIntentReceiver, filter);
+
+ mSettingsObserver = new SettingsObserver(mHandler);
+ mSettingsObserver.observe();
}
// Toasts
@@ -892,6 +934,62 @@
return -1;
}
+ // This is here instead of StatusBarPolicy because it is an important
+ // security feature that we don't want people customizing the platform
+ // to accidentally lose.
+ private void updateAdbNotification() {
+ if (mAdbEnabled && mBatteryPlugged == BatteryManager.BATTERY_PLUGGED_USB) {
+ if (!mAdbNotificationShown) {
+ NotificationManager notificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager != null) {
+ Resources r = mContext.getResources();
+ CharSequence title = r.getText(
+ com.android.internal.R.string.adb_active_notification_title);
+ CharSequence message = r.getText(
+ com.android.internal.R.string.adb_active_notification_message);
+
+ if (mAdbNotification == null) {
+ mAdbNotification = new Notification();
+ mAdbNotification.icon = com.android.internal.R.drawable.stat_sys_warning;
+ mAdbNotification.when = 0;
+ mAdbNotification.flags = Notification.FLAG_ONGOING_EVENT;
+ mAdbNotification.tickerText = title;
+ mAdbNotification.defaults |= Notification.DEFAULT_SOUND;
+ }
+
+ Intent intent = new Intent(
+ Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+ // Note: we are hard-coding the component because this is
+ // an important security UI that we don't want anyone
+ // intercepting.
+ intent.setComponent(new ComponentName("com.android.settings",
+ "com.android.settings.DevelopmentSettings"));
+ PendingIntent pi = PendingIntent.getActivity(mContext, 0,
+ intent, 0);
+
+ mAdbNotification.setLatestEventInfo(mContext, title, message, pi);
+
+ mAdbNotificationShown = true;
+ notificationManager.notify(
+ com.android.internal.R.string.adb_active_notification_title,
+ mAdbNotification);
+ }
+ }
+
+ } else if (mAdbNotificationShown) {
+ NotificationManager notificationManager = (NotificationManager) mContext
+ .getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager != null) {
+ mAdbNotificationShown = false;
+ notificationManager.cancel(
+ com.android.internal.R.string.adb_active_notification_title);
+ }
+ }
+ }
+
// ======================================================================
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/services/java/com/android/server/PackageManagerBackupAgent.java b/services/java/com/android/server/PackageManagerBackupAgent.java
index 16f14e8..a1b4c268 100644
--- a/services/java/com/android/server/PackageManagerBackupAgent.java
+++ b/services/java/com/android/server/PackageManagerBackupAgent.java
@@ -59,7 +59,14 @@
private List<PackageInfo> mAllPackages;
private PackageManager mPackageManager;
+ // version & signature info of each app in a restore set
private HashMap<String, Metadata> mRestoredSignatures;
+ // The version info of each backed-up app as read from the state file
+ private HashMap<String, Metadata> mStateVersions = new HashMap<String, Metadata>();
+
+ private final HashSet<String> mExisting = new HashSet<String>();
+ private int mStoredSdkVersion;
+ private String mStoredIncrementalVersion;
public class Metadata {
public int versionCode;
@@ -96,24 +103,39 @@
ByteArrayOutputStream bufStream = new ByteArrayOutputStream(); // we'll reuse these
DataOutputStream outWriter = new DataOutputStream(bufStream);
- HashSet<String> existing = parseStateFile(oldState);
+ parseStateFile(oldState);
+
+ // If the stored version string differs, we need to re-backup all
+ // of the metadata. We force this by removing everything from the
+ // "already backed up" map built by parseStateFile().
+ if (mStoredIncrementalVersion == null
+ || !mStoredIncrementalVersion.equals(Build.VERSION.INCREMENTAL)) {
+ Log.i(TAG, "Previous metadata " + mStoredIncrementalVersion + " mismatch vs "
+ + Build.VERSION.INCREMENTAL + " - rewriting");
+ mExisting.clear();
+ }
try {
/*
* Global metadata:
*
- * int version -- the SDK version of the OS itself on the device
- * that produced this backup set. Used to reject
- * backups from later OSes onto earlier ones.
+ * int SDKversion -- the SDK version of the OS itself on the device
+ * that produced this backup set. Used to reject
+ * backups from later OSes onto earlier ones.
+ * String incremental -- the incremental release name of the OS stored in
+ * the backup set.
*/
- if (!existing.contains(GLOBAL_METADATA_KEY)) {
+ if (!mExisting.contains(GLOBAL_METADATA_KEY)) {
if (DEBUG) Log.v(TAG, "Storing global metadata key");
outWriter.writeInt(Build.VERSION.SDK_INT);
+ outWriter.writeUTF(Build.VERSION.INCREMENTAL);
byte[] metadata = bufStream.toByteArray();
data.writeEntityHeader(GLOBAL_METADATA_KEY, metadata.length);
data.writeEntityData(metadata, metadata.length);
} else {
if (DEBUG) Log.v(TAG, "Global metadata key already stored");
+ // don't consider it to have been skipped/deleted
+ mExisting.remove(GLOBAL_METADATA_KEY);
}
// For each app we have on device, see if we've backed it up yet. If not,
@@ -123,11 +145,36 @@
if (packName.equals(GLOBAL_METADATA_KEY)) {
// We've already handled the metadata key; skip it here
continue;
- } else if (!existing.contains(packName)) {
- // We haven't stored this app's signatures yet, so we do that now
+ } else {
+ PackageInfo info = null;
try {
- PackageInfo info = mPackageManager.getPackageInfo(packName,
+ info = mPackageManager.getPackageInfo(packName,
PackageManager.GET_SIGNATURES);
+ } catch (NameNotFoundException e) {
+ // Weird; we just found it, and now are told it doesn't exist.
+ // Treat it as having been removed from the device.
+ mExisting.add(packName);
+ continue;
+ }
+
+ boolean doBackup = false;
+ if (!mExisting.contains(packName)) {
+ // We haven't backed up this app before
+ doBackup = true;
+ } else {
+ // We *have* backed this one up before. Check whether the version
+ // of the backup matches the version of the current app; if they
+ // don't match, the app has been updated and we need to store its
+ // metadata again. In either case, take it out of mExisting so that
+ // we don't consider it deleted later.
+ if (info.versionCode != mStateVersions.get(packName).versionCode) {
+ doBackup = true;
+ }
+ mExisting.remove(packName);
+ }
+
+ if (doBackup) {
+ // We need to store this app's metadata
/*
* Metadata for each package:
*
@@ -135,7 +182,7 @@
* byte[] signatures -- [len] flattened Signature[] of the package
*/
- // marshall the version code in a canonical form
+ // marshal the version code in a canonical form
bufStream.reset();
outWriter.writeInt(info.versionCode);
byte[] versionBuf = bufStream.toByteArray();
@@ -153,18 +200,6 @@
data.writeEntityHeader(packName, versionBuf.length + sigs.length);
data.writeEntityData(versionBuf, versionBuf.length);
data.writeEntityData(sigs, sigs.length);
- } catch (NameNotFoundException e) {
- // Weird; we just found it, and now are told it doesn't exist.
- // Treat it as having been removed from the device.
- existing.add(packName);
- }
- } else {
- // We've already backed up this app. Remove it from the set so
- // we can tell at the end what has disappeared from the device.
- // !!! TODO: take out the debugging message
- if (DEBUG) Log.v(TAG, "= already backed up metadata for " + packName);
- if (!existing.remove(packName)) {
- Log.d(TAG, "*** failed to remove " + packName + " from package set!");
}
}
}
@@ -172,7 +207,7 @@
// At this point, the only entries in 'existing' are apps that were
// mentioned in the saved state file, but appear to no longer be present
// on the device. Write a deletion entity for them.
- for (String app : existing) {
+ for (String app : mExisting) {
// !!! TODO: take out this msg
if (DEBUG) Log.v(TAG, "- removing metadata for deleted pkg " + app);
try {
@@ -215,17 +250,21 @@
DataInputStream in = new DataInputStream(baStream);
if (key.equals(GLOBAL_METADATA_KEY)) {
- storedSystemVersion = in.readInt();
+ int storedSdkVersion = in.readInt();
if (DEBUG) Log.v(TAG, " storedSystemVersion = " + storedSystemVersion);
if (storedSystemVersion > Build.VERSION.SDK_INT) {
// returning before setting the sig map means we rejected the restore set
Log.w(TAG, "Restore set was from a later version of Android; not restoring");
return;
}
+ mStoredSdkVersion = storedSdkVersion;
+ mStoredIncrementalVersion = in.readUTF();
// !!! TODO: remove this debugging output
if (DEBUG) {
Log.i(TAG, "Restore set version " + storedSystemVersion
- + " is compatible with OS version " + Build.VERSION.SDK_INT);
+ + " is compatible with OS version " + Build.VERSION.SDK_INT
+ + " (" + mStoredIncrementalVersion + " vs "
+ + Build.VERSION.INCREMENTAL + ")");
}
} else {
// it's a file metadata record
@@ -302,31 +341,45 @@
}
// Util: parse out an existing state file into a usable structure
- private HashSet<String> parseStateFile(ParcelFileDescriptor stateFile) {
- HashSet<String> set = new HashSet<String>();
+ private void parseStateFile(ParcelFileDescriptor stateFile) {
+ mExisting.clear();
+ mStateVersions.clear();
+ mStoredSdkVersion = 0;
+ mStoredIncrementalVersion = null;
+
// The state file is just the list of app names we have stored signatures for
+ // with the exception of the metadata block, to which is also appended the
+ // version numbers corresponding with the last time we wrote this PM block.
+ // If they mismatch the current system, we'll re-store the metadata key.
FileInputStream instream = new FileInputStream(stateFile.getFileDescriptor());
DataInputStream in = new DataInputStream(instream);
int bufSize = 256;
byte[] buf = new byte[bufSize];
try {
- int nameSize = in.readInt();
- if (bufSize < nameSize) {
- bufSize = nameSize + 32;
- buf = new byte[bufSize];
+ String pkg = in.readUTF();
+ if (pkg.equals(GLOBAL_METADATA_KEY)) {
+ mStoredSdkVersion = in.readInt();
+ mStoredIncrementalVersion = in.readUTF();
+ mExisting.add(GLOBAL_METADATA_KEY);
+ } else {
+ Log.e(TAG, "No global metadata in state file!");
+ return;
}
- in.read(buf, 0, nameSize);
- String pkg = new String(buf, 0, nameSize);
- set.add(pkg);
+
+ // The global metadata was first; now read all the apps
+ while (true) {
+ pkg = in.readUTF();
+ int versionCode = in.readInt();
+ mExisting.add(pkg);
+ mStateVersions.put(pkg, new Metadata(versionCode, null));
+ }
} catch (EOFException eof) {
// safe; we're done
} catch (IOException e) {
// whoops, bad state file. abort.
- Log.e(TAG, "Unable to read Package Manager state file");
- return null;
+ Log.e(TAG, "Unable to read Package Manager state file: " + e);
}
- return set;
}
// Util: write out our new backup state file
@@ -336,15 +389,14 @@
try {
// by the time we get here we know we've stored the global metadata record
- byte[] metaNameBuf = GLOBAL_METADATA_KEY.getBytes();
- out.writeInt(metaNameBuf.length);
- out.write(metaNameBuf);
+ out.writeUTF(GLOBAL_METADATA_KEY);
+ out.writeInt(Build.VERSION.SDK_INT);
+ out.writeUTF(Build.VERSION.INCREMENTAL);
// now write all the app names too
for (PackageInfo pkg : pkgs) {
- byte[] pkgNameBuf = pkg.packageName.getBytes();
- out.writeInt(pkgNameBuf.length);
- out.write(pkgNameBuf);
+ out.writeUTF(pkg.packageName);
+ out.writeInt(pkg.versionCode);
}
} catch (IOException e) {
Log.e(TAG, "Unable to write package manager state file!");
diff --git a/services/java/com/android/server/status/StatusBarPolicy.java b/services/java/com/android/server/status/StatusBarPolicy.java
index dd3d38c..7a8d4e5e 100644
--- a/services/java/com/android/server/status/StatusBarPolicy.java
+++ b/services/java/com/android/server/status/StatusBarPolicy.java
@@ -99,7 +99,7 @@
private IBinder mBatteryIcon;
private IconData mBatteryData;
private boolean mBatteryFirst = true;
- private boolean mBatteryPlugged;
+ private int mBatteryPlugged;
private int mBatteryLevel;
private int mBatteryThreshold = 0; // index into mBatteryThresholds
private int[] mBatteryThresholds = new int[] { 20, 15, -1 };
@@ -108,6 +108,7 @@
private View mBatteryView;
private int mBatteryViewSequence;
private boolean mBatteryShowLowOnEndCall = false;
+ private boolean mSentLowBatteryBroadcast = false;
private static final boolean SHOW_LOW_BATTERY_WARNING = true;
// phone
@@ -581,7 +582,7 @@
mBatteryData.iconLevel = intent.getIntExtra("level", 0);
mService.updateIcon(mBatteryIcon, mBatteryData, null);
- boolean plugged = intent.getIntExtra("plugged", 0) != 0;
+ int plugged = intent.getIntExtra("plugged", 0);
int level = intent.getIntExtra("level", -1);
if (false) {
Log.d(TAG, "updateBattery level=" + level
@@ -592,7 +593,7 @@
+ " mBatteryFirst=" + mBatteryFirst);
}
- boolean oldPlugged = mBatteryPlugged;
+ int oldPlugged = mBatteryPlugged;
int oldThreshold = mBatteryThreshold;
pickNextBatteryLevel(level);
@@ -619,11 +620,12 @@
Log.d(TAG, "plugged=" + plugged + " oldPlugged=" + oldPlugged + " level=" + level
+ " mBatteryThreshold=" + mBatteryThreshold + " oldThreshold=" + oldThreshold);
}
- if (!plugged
- && ((oldPlugged && level < mBatteryThresholds[BATTERY_THRESHOLD_WARNING])
+ if (plugged == 0
+ && ((oldPlugged != 0 && level < mBatteryThresholds[BATTERY_THRESHOLD_WARNING])
|| (mBatteryThreshold > oldThreshold
&& mBatteryThreshold > BATTERY_THRESHOLD_WARNING))) {
// Broadcast the low battery warning
+ mSentLowBatteryBroadcast = true;
mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_LOW));
if (SHOW_LOW_BATTERY_WARNING) {
@@ -639,7 +641,11 @@
mBatteryShowLowOnEndCall = true;
}
}
- } else if (mBatteryThreshold == BATTERY_THRESHOLD_CLOSE_WARNING) {
+ } else if (mBatteryThreshold < BATTERY_THRESHOLD_WARNING) {
+ if (mSentLowBatteryBroadcast == true) {
+ mSentLowBatteryBroadcast = false;
+ mContext.sendBroadcast(new Intent(Intent.ACTION_BATTERY_OKAY));
+ }
if (SHOW_LOW_BATTERY_WARNING) {
if (mLowBatteryDialog != null) {
mLowBatteryDialog.dismiss();
@@ -763,7 +769,7 @@
}
if (mPhoneState == TelephonyManager.CALL_STATE_IDLE) {
if (mBatteryShowLowOnEndCall) {
- if (!mBatteryPlugged) {
+ if (mBatteryPlugged == 0) {
showLowBatteryWarning();
}
mBatteryShowLowOnEndCall = false;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index e00ee83..c33d4b6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -1398,7 +1398,7 @@
protected void onVoiceCallEnded() {
if (state == State.CONNECTED) {
- if (mGsmPhone.mSST.isConcurrentVoiceAndData()) {
+ if (!mGsmPhone.mSST.isConcurrentVoiceAndData()) {
startNetStatPoll();
phone.notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
} else {
diff --git a/test-runner/android/test/MoreAsserts.java b/test-runner/android/test/MoreAsserts.java
index 2e74644..9e0d018 100644
--- a/test-runner/android/test/MoreAsserts.java
+++ b/test-runner/android/test/MoreAsserts.java
@@ -24,6 +24,7 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.ArrayList;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -316,8 +317,11 @@
*/
public static void assertContentsInOrder(
String message, Iterable<?> actual, Object... expected) {
- Assert.assertEquals(message,
- Arrays.asList(expected), Lists.newArrayList(actual));
+ ArrayList actualList = new ArrayList();
+ for (Object o : actual) {
+ actualList.add(o);
+ }
+ Assert.assertEquals(message, Arrays.asList(expected), actualList);
}
/**
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index c792e8e..cbcac6c 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -16,18 +16,15 @@
package com.android.dumprendertree;
+import dalvik.system.VMRuntime;
+
import android.app.Instrumentation;
import android.content.Intent;
-
-import android.util.Log;
-
import android.os.Bundle;
import android.os.Debug;
-import android.os.Debug.MemoryInfo;
+import android.os.Process;
import android.test.ActivityInstrumentationTestCase2;
-
-import com.android.dumprendertree.TestShellActivity;
-import com.android.dumprendertree.TestShellCallback;
+import android.util.Log;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -70,9 +67,7 @@
TestShellActivity activity = (TestShellActivity) getActivity();
Log.v(LOGTAG, "About to run tests, calling gc first...");
- Runtime.getRuntime().runFinalization();
- Runtime.getRuntime().gc();
- Runtime.getRuntime().gc();
+ freeMem();
// Run tests
runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);
@@ -83,46 +78,73 @@
activity.finish();
}
+ private void freeMem() {
+ Log.v(LOGTAG, "freeMem: calling gc/finalization...");
+ final VMRuntime runtime = VMRuntime.getRuntime();
+
+ runtime.gcSoftReferences();
+ runtime.runFinalizationSync();
+ runtime.gcSoftReferences();
+ runtime.runFinalizationSync();
+ runtime.gcSoftReferences();
+ runtime.runFinalizationSync();
+ Runtime.getRuntime().runFinalization();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().gc();
+
+ }
+
+ private void printRow(PrintStream ps, String format, Object...objs) {
+ ps.println(String.format(format, objs));
+ }
+
private void dumpMemoryInfo() {
try {
- Log.v(LOGTAG, "About to dump meminfo, calling gc first...");
- Runtime.getRuntime().runFinalization();
- Runtime.getRuntime().gc();
- Runtime.getRuntime().gc();
-
+ freeMem();
Log.v(LOGTAG, "Dumping memory information.");
FileOutputStream out = new FileOutputStream(LOAD_TEST_RESULT, true);
PrintStream ps = new PrintStream(out);
- MemoryInfo mi = new MemoryInfo();
- Debug.getMemoryInfo(mi);
-
- //try to fake the dumpsys format
- //this will eventually be changed to XML
- String format = "%15s:%9d%9d%9d%9d";
- String pss =
- String.format(format, "(Pss)",
- mi.nativePss, mi.dalvikPss, mi.otherPss,
- mi.nativePss + mi.dalvikPss + mi.otherPss);
- String sd =
- String.format(format, "(shared dirty)",
- mi.nativeSharedDirty, mi.dalvikSharedDirty, mi.otherSharedDirty,
- mi.nativeSharedDirty + mi.dalvikSharedDirty + mi.otherSharedDirty);
- String pd =
- String.format(format, "(priv dirty)",
- mi.nativePrivateDirty, mi.dalvikPrivateDirty, mi.otherPrivateDirty,
- mi.nativePrivateDirty + mi.dalvikPrivateDirty + mi.otherPrivateDirty);
-
ps.print("\n\n\n");
- ps.println("** MEMINFO in pid 0 [com.android.dumprendertree] **");
- ps.println(" native dalvik other total");
- ps.println(" size: 12060 5255 N/A 17315");
- ps.println(" allocated: 12060 5255 N/A 17315");
- ps.println(" free: 12060 5255 N/A 17315");
- ps.println(pss);
- ps.println(sd);
- ps.println(pd);
+ ps.println("** MEMINFO in pid " + Process.myPid()
+ + " [com.android.dumprendertree] **");
+ String formatString = "%17s %8s %8s %8s %8s";
+
+ long nativeMax = Debug.getNativeHeapSize() / 1024;
+ long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
+ long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
+ Runtime runtime = Runtime.getRuntime();
+ long dalvikMax = runtime.totalMemory() / 1024;
+ long dalvikFree = runtime.freeMemory() / 1024;
+ long dalvikAllocated = dalvikMax - dalvikFree;
+
+
+ Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
+ Debug.getMemoryInfo(memInfo);
+
+ final int nativeShared = memInfo.nativeSharedDirty;
+ final int dalvikShared = memInfo.dalvikSharedDirty;
+ final int otherShared = memInfo.otherSharedDirty;
+
+ final int nativePrivate = memInfo.nativePrivateDirty;
+ final int dalvikPrivate = memInfo.dalvikPrivateDirty;
+ final int otherPrivate = memInfo.otherPrivateDirty;
+
+ printRow(ps, formatString, "", "native", "dalvik", "other", "total");
+ printRow(ps, formatString, "size:", nativeMax, dalvikMax, "N/A", nativeMax + dalvikMax);
+ printRow(ps, formatString, "allocated:", nativeAllocated, dalvikAllocated, "N/A",
+ nativeAllocated + dalvikAllocated);
+ printRow(ps, formatString, "free:", nativeFree, dalvikFree, "N/A",
+ nativeFree + dalvikFree);
+
+ printRow(ps, formatString, "(Pss):", memInfo.nativePss, memInfo.dalvikPss,
+ memInfo.otherPss, memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss);
+
+ printRow(ps, formatString, "(shared dirty):", nativeShared, dalvikShared, otherShared,
+ nativeShared + dalvikShared + otherShared);
+ printRow(ps, formatString, "(priv dirty):", nativePrivate, dalvikPrivate, otherPrivate,
+ nativePrivate + dalvikPrivate + otherPrivate);
ps.print("\n\n\n");
ps.flush();
ps.close();
@@ -142,7 +164,7 @@
LoadTestsAutoTest.this.notifyAll();
}
}
-
+
public void timedOut(String url) {
}
});