Merge "Update switch call and accept call." into gingerbread
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 19e578f..f72de67 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1166,6 +1166,14 @@
*/
public static final String FOCUS_MODE_EDOF = "edof";
+ /**
+ * Continuous auto focus mode. The camera continuously tries to focus.
+ * This is ideal for shooting video or shooting photo of moving object.
+ * Auto focus starts when the parameter is set. Applications should not
+ * call {@link #autoFocus(AutoFocusCallback)} in this mode.
+ */
+ public static final String FOCUS_MODE_CONTINUOUS = "continuous";
+
// Indices for focus distance array.
/**
* The array index of near focus distance for use with
@@ -1186,16 +1194,6 @@
public static final int FOCUS_DISTANCE_FAR_INDEX = 2;
/**
- * Continuous focus mode. The camera continuously tries to focus. This
- * is ideal for shooting video or shooting photo of moving object.
- * Continuous focus starts when {@link #autoFocus(AutoFocusCallback)} is
- * called. Continuous focus stops when {@link #cancelAutoFocus()} is
- * called. AutoFocusCallback will be only called once as soon as the
- * picture is in focus.
- */
- public static final String FOCUS_MODE_CONTINUOUS = "continuous";
-
- /**
* The camera determines the exposure by giving more weight to the
* central part of the scene.
*/
@@ -1942,15 +1940,15 @@
/**
* Gets the current focus mode setting.
*
- * @return current focus mode. If the camera does not support
- * auto-focus, this should return {@link #FOCUS_MODE_FIXED}. If
- * the focus mode is not FOCUS_MODE_FIXED or {@link
- * #FOCUS_MODE_INFINITY}, applications should call {@link
- * #autoFocus(AutoFocusCallback)} to start the focus.
+ * @return current focus mode. This method will always return a non-null
+ * value. Applications should call {@link
+ * #autoFocus(AutoFocusCallback)} to start the focus if focus
+ * mode is FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
* @see #FOCUS_MODE_AUTO
* @see #FOCUS_MODE_INFINITY
* @see #FOCUS_MODE_MACRO
* @see #FOCUS_MODE_FIXED
+ * @see #FOCUS_MODE_CONTINUOUS
*/
public String getFocusMode() {
return get(KEY_FOCUS_MODE);
@@ -2152,8 +2150,14 @@
* #autoFocus(AutoFocusCallback)}, {@link #cancelAutoFocus}, or {@link
* #startPreview()}. Applications can call {@link #getParameters()}
* and this method anytime to get the latest focus distances. If the
- * focus mode is FOCUS_MODE_CONTINUOUS and autofocus has started, focus
- * distances may change from time to time.
+ * focus mode is FOCUS_MODE_CONTINUOUS, focus distances may change from
+ * time to time.
+ *
+ * This method is intended to estimate the distance between the camera
+ * and the subject. After autofocus, the subject distance may be within
+ * near and far focus distance. However, the precision depends on the
+ * camera hardware, autofocus algorithm, the focus area, and the scene.
+ * The error can be large and it should be only used as a reference.
*
* Far focus distance >= optimal focus distance >= near focus distance.
* If the focus distance is infinity, the value will be
diff --git a/docs/html/resources/community-groups.jd b/docs/html/resources/community-groups.jd
index 72bdf7a..651edbc 100644
--- a/docs/html/resources/community-groups.jd
+++ b/docs/html/resources/community-groups.jd
@@ -87,27 +87,27 @@
<h3 id="ApplicationDeveloperLists">Application developer mailing lists</h3>
<ul>
<li><strong><a href="http://groups.google.com/group/android-developers">android-developers</a></strong>
-(<a href="mailto:android-developers-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-developers/subscribe">subscribe</a>)<br>
You're now an experienced Android application developer. You've grasped the basics of Android app development, you're comfortable using the SDK, now you want to move to advanced topics. Get help here with troubleshooting applications, advice on implementation, and strategies for improving your application's performance and user experience. This is the not the right place to discuss user issues (use android-discuss for that) or beginner questions with the Android SDK (use android-beginners for that).
</li>
<li><strong><a href="http://groups.google.com/group/android-discuss">android-discuss</a></strong>
-(<a href="mailto:android-discuss-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-discuss/subscribe">subscribe</a>)<br>
The "water cooler" of Android discussion. You can discuss just about anything Android-related here, ideas for the Android platform, announcements about your applications, discussions about Android devices, community resources... As long as your discussion is related to Android, it's on-topic here. However, if you have a discussion here that could belong on another list, you are probably not reaching all of your target audience here and may want to consider shifting to a more targeted list.
</li>
<li><strong><a href="http://groups.google.com/group/android-ndk">android-ndk</a></strong>
-(<a href="mailto:android-ndk-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-ndk/subscribe">subscribe</a>)<br>
A place for discussing the Android NDK and topics related to using native code in Android applications.
</li>
<li><strong><a href="http://groups.google.com/group/android-security-discuss">android-security-discuss</a></strong>
-(<a href="mailto:android-security-discuss-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-security-discuss/subscribe">subscribe</a>)<br>
A place for open discussion on secure development, emerging security concerns, and best practices for and by android developers. Please don't disclose vulnerabilities directly on this list, you'd be putting all Android users at risk.
</li>
<li><strong><a href="http://groups.google.com/group/android-security-announce">android-security-announce</a></strong>
-(<a href="mailto:android-security-announce-subscribe@googlegroups.com">subscribe via email</a>)<br>
+(<a href="http://groups.google.com/group/android-security-announce/subscribe">subscribe</a>)<br>
A low-volume group for security-related announcements by the Android Security Team.
</li>
</ul>
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index e12a694..6a5d254 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -171,10 +171,9 @@
// Supported flash modes.
// Example value: "auto,on,off". Read only.
static const char KEY_SUPPORTED_FLASH_MODES[];
- // Current focus mode. If the camera does not support auto-focus, the value
- // should be FOCUS_MODE_FIXED. If the focus mode is not FOCUS_MODE_FIXED or
- // or FOCUS_MODE_INFINITY, applications should call
- // CameraHardwareInterface.autoFocus to start the focus.
+ // Current focus mode. This will not be empty. Applications should call
+ // CameraHardwareInterface.autoFocus to start the focus if focus mode is
+ // FOCUS_MODE_AUTO or FOCUS_MODE_MACRO.
// Example value: "auto" or FOCUS_MODE_XXX constants. Read/write.
static const char KEY_FOCUS_MODE[];
// Supported focus modes.
@@ -231,11 +230,16 @@
// be in focus. The object is sharpest at the optimal focus distance. The
// depth of field is the far focus distance minus near focus distance.
//
- // Applications can read this parameter anytime to get the latest focus
- // distances. If the focus mode is FOCUS_MODE_EDOF, the values may be all
- // 0, which means focus distance is not applicable. If the focus mode is
- // FOCUS_MODE_CONTINUOUS and autofocus has started, focus distances may
- // change from time to time.
+ // Focus distances may change after starting auto focus, canceling auto
+ // focus, or starting the preview. Applications can read this anytime to get
+ // the latest focus distances. If the focus mode is FOCUS_MODE_CONTINUOUS,
+ // focus distances may change from time to time.
+ //
+ // This is intended to estimate the distance between the camera and the
+ // subject. After autofocus, the subject distance may be within near and far
+ // focus distance. However, the precision depends on the camera hardware,
+ // autofocus algorithm, the focus area, and the scene. The error can be
+ // large and it should be only used as a reference.
//
// Far focus distance > optimal focus distance > near focus distance. If
// the far focus distance is infinity, the value should be "Infinity" (case
@@ -348,10 +352,10 @@
// continuously. Applications should not call
// CameraHardwareInterface.autoFocus in this mode.
static const char FOCUS_MODE_EDOF[];
- // Continuous focus mode. The camera continuously tries to focus. This is
- // ideal for shooting video or shooting photo of moving object. Continuous
- // focus starts when CameraHardwareInterface.autoFocus is called. Focus
- // callback will be only called once as soon as the picture is in focus.
+ // Continuous auto focus mode. The camera continuously tries to focus. This
+ // is ideal for shooting video or shooting photo of moving object. Auto
+ // focus starts when the parameter is set. Applications should not call
+ // CameraHardwareInterface.autoFocus in this mode.
static const char FOCUS_MODE_CONTINUOUS[];
// The camera determines the exposure by giving more weight to the
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index c113ffe..f69b8ad 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -318,6 +318,15 @@
jobject surface = env->GetObjectField(thiz, fields.surface);
if (surface != NULL) {
const sp<Surface> native_surface = get_surface(env, surface);
+
+ // The application may misbehave and
+ // the preview surface becomes unavailable
+ if (native_surface.get() == 0) {
+ LOGE("Application lost the surface");
+ jniThrowException(env, "java/io/IOException", "invalid preview surface");
+ return;
+ }
+
LOGI("prepare: surface=%p (identity=%d)", native_surface.get(), native_surface->getIdentity());
if (process_media_recorder_call(env, mr->setPreviewSurface(native_surface), "java/lang/RuntimeException", "setPreviewSurface failed.")) {
return;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index efdad43..f2653cf 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1216,7 +1216,7 @@
MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
return setDataSource_l(extractor);
- } else if (!strcmp("rtsp://gtalk", mUri.string())) {
+ } else if (!strncmp("rtsp://gtalk/", mUri.string(), 13)) {
if (mLooper == NULL) {
mLooper = new ALooper;
mLooper->start(
@@ -1225,6 +1225,22 @@
PRIORITY_HIGHEST);
}
+ const char *startOfCodecString = &mUri.string()[13];
+ const char *startOfSlash1 = strchr(startOfCodecString, '/');
+ if (startOfSlash1 == NULL) {
+ return BAD_VALUE;
+ }
+ const char *startOfWidthString = &startOfSlash1[1];
+ const char *startOfSlash2 = strchr(startOfWidthString, '/');
+ if (startOfSlash2 == NULL) {
+ return BAD_VALUE;
+ }
+ const char *startOfHeightString = &startOfSlash2[1];
+
+ String8 codecString(startOfCodecString, startOfSlash1 - startOfCodecString);
+ String8 widthString(startOfWidthString, startOfSlash2 - startOfWidthString);
+ String8 heightString(startOfHeightString);
+
#if 0
mRTPPusher = new UDPPusher("/data/misc/rtpout.bin", 5434);
mLooper->registerHandler(mRTPPusher);
@@ -1251,8 +1267,8 @@
"a=rtpmap:97 AMR/8000/1\r\n"
"a=fmtp:97 octet-align\r\n";
#elif 1
- // My GTalk H.264 SDP
- static const char *raw =
+ String8 sdp;
+ sdp.appendFormat(
"v=0\r\n"
"o=- 64 233572944 IN IP4 127.0.0.0\r\n"
"s=QuickTime\r\n"
@@ -1262,24 +1278,16 @@
"m=video 5434 RTP/AVP 97\r\n"
"c=IN IP4 127.0.0.1\r\n"
"b=AS:30\r\n"
- "a=rtpmap:97 H264/90000\r\n"
- "a=cliprect:0,0,200,320\r\n"
- "a=framesize:97 320-200\r\n";
-#else
- // GTalk H263 SDP
- static const char *raw =
- "v=0\r\n"
- "o=- 64 233572944 IN IP4 127.0.0.0\r\n"
- "s=QuickTime\r\n"
- "t=0 0\r\n"
- "a=range:npt=0-315\r\n"
- "a=isma-compliance:2,2.0,2\r\n"
- "m=video 5434 RTP/AVP 98\r\n"
- "c=IN IP4 127.0.0.1\r\n"
- "b=AS:30\r\n"
- "a=rtpmap:98 H263-1998/90000\r\n"
- "a=cliprect:0,0,200,320\r\n"
- "a=framesize:98 320-200\r\n";
+ "a=rtpmap:97 %s/90000\r\n"
+ "a=cliprect:0,0,%s,%s\r\n"
+ "a=framesize:97 %s-%s\r\n",
+
+ codecString.string(),
+ heightString.string(), widthString.string(),
+ widthString.string(), heightString.string()
+ );
+ const char *raw = sdp.string();
+
#endif
sp<ASessionDescription> desc = new ASessionDescription;
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
index 0d89e02..389180c 100644
--- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
@@ -98,6 +98,7 @@
: mSource(source),
mMeta(meta),
mNumInputFrames(-1),
+ mPrevTimestampUs(-1),
mStarted(false),
mInputBuffer(NULL),
mInputFrameData(NULL),
@@ -391,8 +392,6 @@
if (err != OK) {
LOGE("Failed to read input video frame: %d", err);
outputBuffer->release();
- mInputBuffer->release();
- mInputBuffer = NULL;
return err;
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
index 5ea5859..a011137 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
@@ -69,6 +69,7 @@
mMeta(meta),
mNumInputFrames(-1),
mNextModTimeUs(0),
+ mPrevTimestampUs(-1),
mStarted(false),
mInputBuffer(NULL),
mInputFrameData(NULL),
@@ -292,8 +293,6 @@
if (OK != mSource->read(&mInputBuffer, options)) {
LOGE("Failed to read from data source");
outputBuffer->release();
- mInputBuffer->release();
- mInputBuffer = NULL;
return UNKNOWN_ERROR;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 8ca880b..0291d78 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -34,7 +34,7 @@
// ---------------------------------------------------------------------------
HWComposer::HWComposer()
- : mModule(0), mHwc(0), mList(0),
+ : mModule(0), mHwc(0), mList(0), mCapacity(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
{
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
@@ -63,10 +63,13 @@
}
status_t HWComposer::createWorkList(size_t numLayers) {
- if (mHwc && (!mList || mList->numHwLayers < numLayers)) {
- free(mList);
- size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
- mList = (hwc_layer_list_t*)malloc(size);
+ if (mHwc) {
+ if (!mList || mCapacity < numLayers) {
+ free(mList);
+ size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
+ mList = (hwc_layer_list_t*)malloc(size);
+ mCapacity = numLayers;
+ }
mList->flags = HWC_GEOMETRY_CHANGED;
mList->numHwLayers = numLayers;
}
@@ -84,12 +87,12 @@
return (status_t)err;
}
-HWComposer::iterator HWComposer::begin() {
- return mList ? &(mList->hwLayers[0]) : NULL;
+size_t HWComposer::getNumLayers() const {
+ return mList ? mList->numHwLayers : 0;
}
-HWComposer::iterator HWComposer::end() {
- return mList ? &(mList->hwLayers[mList->numHwLayers]) : NULL;
+hwc_layer_t* HWComposer::getLayers() const {
+ return mList ? mList->hwLayers : 0;
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 729f23b..c5d5c2b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -49,16 +49,14 @@
status_t commit() const;
- typedef hwc_layer_t const * const_iterator;
- typedef hwc_layer_t* iterator;
-
- iterator begin();
- iterator end();
+ size_t getNumLayers() const;
+ hwc_layer_t* getLayers() const;
private:
hw_module_t const* mModule;
hwc_composer_device_t* mHwc;
hwc_layer_list_t* mList;
+ size_t mCapacity;
hwc_display_t mDpy;
hwc_surface_t mSur;
};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 47bb4c1..006bb10 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -755,10 +755,9 @@
const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
const size_t count = currentLayers.size();
hwc.createWorkList(count);
- HWComposer::iterator cur(hwc.begin());
- HWComposer::iterator last(hwc.end());
- for (size_t i=0 ; (i<count) && (cur!=last) ; ++i, ++cur) {
- currentLayers[i]->setGeometry(cur);
+ hwc_layer_t* const cur(hwc.getLayers());
+ for (size_t i=0 ; cur && i<count ; i++) {
+ currentLayers[i]->setGeometry(&cur[i]);
}
}
}
@@ -829,47 +828,41 @@
status_t err = NO_ERROR;
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
- const size_t count = layers.size();
+ size_t count = layers.size();
const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer());
- HWComposer::iterator cur(hwc.begin());
- HWComposer::iterator last(hwc.end());
+ hwc_layer_t* const cur(hwc.getLayers());
- // update the per-frame h/w composer data for each layer
- if (cur != last) {
- for (size_t i=0 ; i<count && cur!=last ; ++i, ++cur) {
- layers[i]->setPerFrameData(cur);
+ LOGE_IF(cur && hwc.getNumLayers() != count,
+ "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
+ hwc.getNumLayers(), count);
+
+ // just to be extra-safe, use the smallest count
+ count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
+
+ /*
+ * update the per-frame h/w composer data for each layer
+ * and build the transparent region of the FB
+ */
+ Region transparent;
+ if (cur) {
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(layers[i]);
+ layer->setPerFrameData(&cur[i]);
+ if (cur[i].hints & HWC_HINT_CLEAR_FB) {
+ if (!(layer->needsBlending())) {
+ transparent.orSelf(layer->visibleRegionScreen);
+ }
+ }
}
err = hwc.prepare();
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
}
- // and then, render the layers targeted at the framebuffer
- Region transparent(hw.bounds());
- for (size_t i=0 ; i<count ; ++i) {
-
- // see if we need to skip this layer
- if (!err && cur != last) {
- if (!((cur->compositionType == HWC_FRAMEBUFFER) ||
- (cur->flags & HWC_SKIP_LAYER))) {
- ++cur;
- continue;
- }
- ++cur;
- }
-
- // draw the layer into the framebuffer
- const sp<LayerBase>& layer(layers[i]);
- transparent.subtractSelf(layer->visibleRegionScreen);
- const Region clip(dirty.intersect(layer->visibleRegionScreen));
- if (!clip.isEmpty()) {
- layer->draw(clip);
- }
- }
-
- // finally clear everything we didn't draw as a result of calling
- // prepare (this leaves the FB transparent).
+ /*
+ * clear the area of the FB that need to be transparent
+ */
transparent.andSelf(dirty);
if (!transparent.isEmpty()) {
glClearColor(0,0,0,0);
@@ -883,6 +876,25 @@
glClear(GL_COLOR_BUFFER_BIT);
}
}
+
+
+ /*
+ * and then, render the layers targeted at the framebuffer
+ */
+ for (size_t i=0 ; i<count ; i++) {
+ if (cur) {
+ if (!(cur[i].compositionType == HWC_FRAMEBUFFER) ||
+ cur[i].flags & HWC_SKIP_LAYER) {
+ // skip layers handled by the HAL
+ continue;
+ }
+ }
+ const sp<LayerBase>& layer(layers[i]);
+ const Region clip(dirty.intersect(layer->visibleRegionScreen));
+ if (!clip.isEmpty()) {
+ layer->draw(clip);
+ }
+ }
}
void SurfaceFlinger::unlockClients()