Merge "DropBoxManager.Entry implements Closeable" into gingerbread
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 9e7eedf..912180b 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -195,7 +195,8 @@
public static final int KEYCODE_TAB = 61;
/** Key code constant: Space key. */
public static final int KEYCODE_SPACE = 62;
- /** Key code constant: Symbol modifier key. */
+ /** Key code constant: Symbol modifier key.
+ * Used to enter alternate symbols. */
public static final int KEYCODE_SYM = 63;
/** Key code constant: Explorer special function key.
* Used to launch a browser application. */
@@ -205,7 +206,8 @@
public static final int KEYCODE_ENVELOPE = 65;
/** Key code constant: Enter key. */
public static final int KEYCODE_ENTER = 66;
- /** Key code constant: Delete key. */
+ /** Key code constant: Backspace key.
+ * Deletes characters before the insertion point. */
public static final int KEYCODE_DEL = 67;
/** Key code constant: '`' (backtick) key. */
public static final int KEYCODE_GRAVE = 68;
@@ -227,7 +229,10 @@
public static final int KEYCODE_SLASH = 76;
/** Key code constant: '@' key. */
public static final int KEYCODE_AT = 77;
- /** Key code constant: Number Lock modifier key. */
+ /** Key code constant: Number modifier key.
+ * Used to enter numeric symbols.
+ * This key is not Num Lock; it is more like {@link #KEYCODE_ALT_LEFT} and is
+ * interpreted as an ALT key by {@link android.text.method.MetaKeyKeyListener}. */
public static final int KEYCODE_NUM = 78;
/** Key code constant: Headset Hook key.
* Used to hang up calls and stop media. */
diff --git a/core/java/android/widget/EdgeGlow.java b/core/java/android/widget/EdgeGlow.java
index 1f7daab..7a990ad 100644
--- a/core/java/android/widget/EdgeGlow.java
+++ b/core/java/android/widget/EdgeGlow.java
@@ -91,6 +91,7 @@
// How much dragging should effect the height of the glow image.
// Number determined by user testing.
private static final int PULL_DISTANCE_GLOW_FACTOR = 5;
+ private static final float PULL_DISTANCE_ALPHA_GLOW_FACTOR = 0.8f;
private static final int VELOCITY_EDGE_FACTOR = 8;
private static final int VELOCITY_GLOW_FACTOR = 16;
@@ -144,8 +145,10 @@
mEdgeScaleY = mEdgeScaleYStart = Math.max(
HELD_EDGE_SCALE_Y, Math.min(distance * PULL_DISTANCE_EDGE_FACTOR, 1.f));
- mGlowAlpha = mGlowAlphaStart = Math.max(
- 0.5f, Math.min(mGlowAlpha + Math.abs(deltaDistance), MAX_ALPHA));
+ mGlowAlpha = mGlowAlphaStart = Math.min(
+ mGlowAlpha +
+ (Math.abs(deltaDistance) * PULL_DISTANCE_ALPHA_GLOW_FACTOR),
+ MAX_ALPHA);
float glowChange = Math.abs(deltaDistance);
if (deltaDistance > 0 && mPullDistance < 0) {
@@ -202,8 +205,8 @@
// The edge should always be at least partially visible, regardless
// of velocity.
- mEdgeAlphaStart = 0.5f;
- mEdgeScaleYStart = 0.2f;
+ mEdgeAlphaStart = 0.f;
+ mEdgeScaleY = mEdgeScaleYStart = 0.f;
// The glow depends more on the velocity, and therefore starts out
// nearly invisible.
mGlowAlphaStart = 0.5f;
@@ -213,7 +216,8 @@
// reflect the strength of the user's scrolling.
mEdgeAlphaFinish = Math.max(0, Math.min(velocity * VELOCITY_EDGE_FACTOR, 1));
// Edge should never get larger than the size of its asset.
- mEdgeScaleYFinish = 1.f;
+ mEdgeScaleYFinish = Math.max(
+ HELD_EDGE_SCALE_Y, Math.min(velocity * VELOCITY_EDGE_FACTOR, 1.f));
// Growth for the size of the glow should be quadratic to properly
// respond
@@ -281,10 +285,11 @@
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
+ // After absorb, the glow and edge should fade to nothing.
mEdgeAlphaFinish = 0.f;
- mEdgeScaleYFinish = mEdgeScaleY;
+ mEdgeScaleYFinish = 0.f;
mGlowAlphaFinish = 0.f;
- mGlowScaleYFinish = mGlowScaleY;
+ mGlowScaleYFinish = 0.f;
break;
case STATE_PULL:
mState = STATE_PULL_DECAY;
@@ -296,14 +301,21 @@
mGlowAlphaStart = mGlowAlpha;
mGlowScaleYStart = mGlowScaleY;
- // After a pull, the glow should fade to nothing.
+ // After pull, the glow and edge should fade to nothing.
mEdgeAlphaFinish = 0.f;
mEdgeScaleYFinish = 0.f;
mGlowAlphaFinish = 0.f;
mGlowScaleYFinish = 0.f;
break;
case STATE_PULL_DECAY:
- // Do nothing; wait for release
+ // When receding, we want edge to decrease more slowly
+ // than the glow.
+ float factor = mGlowScaleYFinish != 0 ? 1
+ / (mGlowScaleYFinish * mGlowScaleYFinish)
+ : Float.MAX_VALUE;
+ mEdgeScaleY = mEdgeScaleYStart +
+ (mEdgeScaleYFinish - mEdgeScaleYStart) *
+ interp * factor;
break;
case STATE_RECEDE:
mState = STATE_IDLE;
diff --git a/include/media/Metadata.h b/include/media/Metadata.h
index 241868a..9c915ce 100644
--- a/include/media/Metadata.h
+++ b/include/media/Metadata.h
@@ -91,6 +91,7 @@
static const Type kPauseAvailable = 29; // Boolean
static const Type kSeekBackwardAvailable = 30; // Boolean
static const Type kSeekForwardAvailable = 31; // Boolean
+ static const Type kSeekAvailable = 32; // Boolean
// @param p[inout] The parcel to append the metadata records
// to. The global metadata header should have been set already.
diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h
index 21338ca..16b0a4c 100644
--- a/include/media/stagefright/MediaExtractor.h
+++ b/include/media/stagefright/MediaExtractor.h
@@ -45,13 +45,14 @@
virtual sp<MetaData> getMetaData();
enum Flags {
- CAN_SEEK_BACKWARD = 1,
- CAN_SEEK_FORWARD = 2,
+ CAN_SEEK_BACKWARD = 1, // the "seek 10secs back button"
+ CAN_SEEK_FORWARD = 2, // the "seek 10secs forward button"
CAN_PAUSE = 4,
+ CAN_SEEK = 8, // the "seek bar"
};
// If subclasses do _not_ override this, the default is
- // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE
+ // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
virtual uint32_t flags() const;
protected:
diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java
index bd25da2..8d408c2 100644
--- a/media/java/android/media/Metadata.java
+++ b/media/java/android/media/Metadata.java
@@ -102,8 +102,9 @@
public static final int PAUSE_AVAILABLE = 29; // Boolean
public static final int SEEK_BACKWARD_AVAILABLE = 30; // Boolean
public static final int SEEK_FORWARD_AVAILABLE = 31; // Boolean
+ public static final int SEEK_AVAILABLE = 32; // Boolean
- private static final int LAST_SYSTEM = 31;
+ private static final int LAST_SYSTEM = 32;
private static final int FIRST_CUSTOM = 8192;
// Shorthands to set the MediaPlayer's metadata filter.
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 2c96d6d..6bded09 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -180,6 +180,10 @@
Metadata::kSeekForwardAvailable,
flags & MediaExtractor::CAN_SEEK_FORWARD);
+ metadata.appendBool(
+ Metadata::kSeekAvailable,
+ flags & MediaExtractor::CAN_SEEK);
+
return OK;
}
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 71d48b3..c0b1abe 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -15,7 +15,6 @@
*/
#include <media/stagefright/AMRWriter.h>
-
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
@@ -23,6 +22,8 @@
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/mediarecorder.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
namespace android {
@@ -194,6 +195,7 @@
int64_t maxTimestampUs = 0;
status_t err = OK;
+ prctl(PR_SET_NAME, (unsigned long)"AMRWriter", 0, 0, 0);
while (!mDone) {
MediaBuffer *buffer;
err = mSource->read(&buffer);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 8c17aab..53543b3 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -868,9 +868,7 @@
}
status_t AwesomePlayer::seekTo(int64_t timeUs) {
- if (mExtractorFlags
- & (MediaExtractor::CAN_SEEK_FORWARD
- | MediaExtractor::CAN_SEEK_BACKWARD)) {
+ if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
Mutex::Autolock autoLock(mLock);
return seekTo_l(timeUs);
}
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 6d00d7c..e53b0a0 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -20,8 +20,9 @@
#include <arpa/inet.h>
-#include <ctype.h>
#include <pthread.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaBuffer.h>
@@ -1104,6 +1105,7 @@
void MPEG4Writer::threadFunc() {
LOGV("threadFunc");
+ prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0);
while (!mDone) {
{
Mutex::Autolock autolock(mLock);
@@ -1632,6 +1634,11 @@
int64_t previousPausedDurationUs = 0;
int64_t timestampUs;
+ if (mIsAudio) {
+ prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
+ } else {
+ prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
+ }
sp<MetaData> meta_data;
mNumSamples = 0;
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 9bc94de..8a5fb11 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -41,7 +41,7 @@
}
uint32_t MediaExtractor::flags() const {
- return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE;
+ return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_PAUSE | CAN_SEEK;
}
// static
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index a8f1104..478e40c 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -18,6 +18,9 @@
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/MetaData.h>
namespace android {
@@ -41,10 +44,12 @@
br.skipBits(16);
parseUE(&br); // seq_parameter_set_id
+ unsigned chroma_format_idc = 1; // 4:2:0 chroma format
+
if (profile_idc == 100 || profile_idc == 110
|| profile_idc == 122 || profile_idc == 244
|| profile_idc == 44 || profile_idc == 83 || profile_idc == 86) {
- unsigned chroma_format_idc = parseUE(&br);
+ chroma_format_idc = parseUE(&br);
if (chroma_format_idc == 3) {
br.skipBits(1); // residual_colour_transform_flag
}
@@ -85,6 +90,212 @@
*height = (2 - frame_mbs_only_flag)
* (pic_height_in_map_units_minus1 * 16 + 16);
+
+ if (!frame_mbs_only_flag) {
+ br.getBits(1); // mb_adaptive_frame_field_flag
+ }
+
+ br.getBits(1); // direct_8x8_inference_flag
+
+ if (br.getBits(1)) { // frame_cropping_flag
+ unsigned frame_crop_left_offset = parseUE(&br);
+ unsigned frame_crop_right_offset = parseUE(&br);
+ unsigned frame_crop_top_offset = parseUE(&br);
+ unsigned frame_crop_bottom_offset = parseUE(&br);
+
+ unsigned cropUnitX, cropUnitY;
+ if (chroma_format_idc == 0 /* monochrome */) {
+ cropUnitX = 1;
+ cropUnitY = 2 - frame_mbs_only_flag;
+ } else {
+ unsigned subWidthC = (chroma_format_idc == 3) ? 1 : 2;
+ unsigned subHeightC = (chroma_format_idc == 1) ? 2 : 1;
+
+ cropUnitX = subWidthC;
+ cropUnitY = subHeightC * (2 - frame_mbs_only_flag);
+ }
+
+ LOGV("frame_crop = (%u, %u, %u, %u), cropUnitX = %u, cropUnitY = %u",
+ frame_crop_left_offset, frame_crop_right_offset,
+ frame_crop_top_offset, frame_crop_bottom_offset,
+ cropUnitX, cropUnitY);
+
+ *width -=
+ (frame_crop_left_offset + frame_crop_right_offset) * cropUnitX;
+ *height -=
+ (frame_crop_top_offset + frame_crop_bottom_offset) * cropUnitY;
+ }
+}
+
+status_t getNextNALUnit(
+ const uint8_t **_data, size_t *_size,
+ const uint8_t **nalStart, size_t *nalSize,
+ bool startCodeFollows) {
+ const uint8_t *data = *_data;
+ size_t size = *_size;
+
+ *nalStart = NULL;
+ *nalSize = 0;
+
+ if (size == 0) {
+ return -EAGAIN;
+ }
+
+ // Skip any number of leading 0x00.
+
+ size_t offset = 0;
+ while (offset < size && data[offset] == 0x00) {
+ ++offset;
+ }
+
+ if (offset == size) {
+ return -EAGAIN;
+ }
+
+ // A valid startcode consists of at least two 0x00 bytes followed by 0x01.
+
+ if (offset < 2 || data[offset] != 0x01) {
+ return ERROR_MALFORMED;
+ }
+
+ ++offset;
+
+ size_t startOffset = offset;
+
+ for (;;) {
+ while (offset < size && data[offset] != 0x01) {
+ ++offset;
+ }
+
+ if (offset == size) {
+ if (startCodeFollows) {
+ offset = size + 2;
+ break;
+ }
+
+ return -EAGAIN;
+ }
+
+ if (data[offset - 1] == 0x00 && data[offset - 2] == 0x00) {
+ break;
+ }
+
+ ++offset;
+ }
+
+ size_t endOffset = offset - 2;
+ while (data[endOffset - 1] == 0x00) {
+ --endOffset;
+ }
+
+ *nalStart = &data[startOffset];
+ *nalSize = endOffset - startOffset;
+
+ if (offset + 2 < size) {
+ *_data = &data[offset - 2];
+ *_size = size - offset + 2;
+ } else {
+ *_data = NULL;
+ *_size = 0;
+ }
+
+ return OK;
+}
+
+static sp<ABuffer> FindNAL(
+ const uint8_t *data, size_t size, unsigned nalType,
+ size_t *stopOffset) {
+ const uint8_t *nalStart;
+ size_t nalSize;
+ while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
+ if ((nalStart[0] & 0x1f) == nalType) {
+ sp<ABuffer> buffer = new ABuffer(nalSize);
+ memcpy(buffer->data(), nalStart, nalSize);
+ return buffer;
+ }
+ }
+
+ return NULL;
+}
+
+sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
+ const uint8_t *data = accessUnit->data();
+ size_t size = accessUnit->size();
+
+ sp<ABuffer> seqParamSet = FindNAL(data, size, 7, NULL);
+ if (seqParamSet == NULL) {
+ return NULL;
+ }
+
+ int32_t width, height;
+ FindAVCDimensions(seqParamSet, &width, &height);
+
+ size_t stopOffset;
+ sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
+ CHECK(picParamSet != NULL);
+
+ size_t csdSize =
+ 1 + 3 + 1 + 1
+ + 2 * 1 + seqParamSet->size()
+ + 1 + 2 * 1 + picParamSet->size();
+
+ sp<ABuffer> csd = new ABuffer(csdSize);
+ uint8_t *out = csd->data();
+
+ *out++ = 0x01; // configurationVersion
+ memcpy(out, seqParamSet->data() + 1, 3); // profile/level...
+ out += 3;
+ *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes
+ *out++ = 0xe0 | 1;
+
+ *out++ = seqParamSet->size() >> 8;
+ *out++ = seqParamSet->size() & 0xff;
+ memcpy(out, seqParamSet->data(), seqParamSet->size());
+ out += seqParamSet->size();
+
+ *out++ = 1;
+
+ *out++ = picParamSet->size() >> 8;
+ *out++ = picParamSet->size() & 0xff;
+ memcpy(out, picParamSet->data(), picParamSet->size());
+
+#if 0
+ LOGI("AVC seq param set");
+ hexdump(seqParamSet->data(), seqParamSet->size());
+#endif
+
+ sp<MetaData> meta = new MetaData;
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+
+ meta->setData(kKeyAVCC, 0, csd->data(), csd->size());
+ meta->setInt32(kKeyWidth, width);
+ meta->setInt32(kKeyHeight, height);
+
+ LOGI("found AVC codec config (%d x %d)", width, height);
+
+ return meta;
+}
+
+bool IsIDR(const sp<ABuffer> &buffer) {
+ const uint8_t *data = buffer->data();
+ size_t size = buffer->size();
+
+ bool foundIDR = false;
+
+ const uint8_t *nalStart;
+ size_t nalSize;
+ while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
+ CHECK_GT(nalSize, 0u);
+
+ unsigned nalType = nalStart[0] & 0x1f;
+
+ if (nalType == 5) {
+ foundIDR = true;
+ break;
+ }
+ }
+
+ return foundIDR;
}
} // namespace android
diff --git a/media/libstagefright/include/ARTSPController.h b/media/libstagefright/include/ARTSPController.h
index 300d8f7..c2f3090 100644
--- a/media/libstagefright/include/ARTSPController.h
+++ b/media/libstagefright/include/ARTSPController.h
@@ -46,6 +46,14 @@
void onMessageReceived(const sp<AMessage> &msg);
+ virtual uint32_t flags() const {
+ // Seeking 10secs forward or backward is a very expensive operation
+ // for rtsp, so let's not enable that.
+ // The user can always use the seek bar.
+
+ return CAN_PAUSE | CAN_SEEK;
+ }
+
protected:
virtual ~ARTSPController();
diff --git a/media/libstagefright/include/avc_utils.h b/media/libstagefright/include/avc_utils.h
index 6602852..62cfc36 100644
--- a/media/libstagefright/include/avc_utils.h
+++ b/media/libstagefright/include/avc_utils.h
@@ -29,6 +29,16 @@
unsigned parseUE(ABitReader *br);
+status_t getNextNALUnit(
+ const uint8_t **_data, size_t *_size,
+ const uint8_t **nalStart, size_t *nalSize,
+ bool startCodeFollows = false);
+
+struct MetaData;
+sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit);
+
+bool IsIDR(const sp<ABuffer> &accessUnit);
+
} // namespace android
#endif // AVC_UTILS_H_
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 4a75ee4..a13287e 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -40,81 +40,6 @@
return mFormat;
}
-static status_t getNextNALUnit(
- const uint8_t **_data, size_t *_size,
- const uint8_t **nalStart, size_t *nalSize,
- bool startCodeFollows = false) {
- const uint8_t *data = *_data;
- size_t size = *_size;
-
- *nalStart = NULL;
- *nalSize = 0;
-
- if (size == 0) {
- return -EAGAIN;
- }
-
- // Skip any number of leading 0x00.
-
- size_t offset = 0;
- while (offset < size && data[offset] == 0x00) {
- ++offset;
- }
-
- if (offset == size) {
- return -EAGAIN;
- }
-
- // A valid startcode consists of at least two 0x00 bytes followed by 0x01.
-
- if (offset < 2 || data[offset] != 0x01) {
- return ERROR_MALFORMED;
- }
-
- ++offset;
-
- size_t startOffset = offset;
-
- for (;;) {
- while (offset < size && data[offset] != 0x01) {
- ++offset;
- }
-
- if (offset == size) {
- if (startCodeFollows) {
- offset = size + 2;
- break;
- }
-
- return -EAGAIN;
- }
-
- if (data[offset - 1] == 0x00 && data[offset - 2] == 0x00) {
- break;
- }
-
- ++offset;
- }
-
- size_t endOffset = offset - 2;
- while (data[endOffset - 1] == 0x00) {
- --endOffset;
- }
-
- *nalStart = &data[startOffset];
- *nalSize = endOffset - startOffset;
-
- if (offset + 2 < size) {
- *_data = &data[offset - 2];
- *_size = size - offset + 2;
- } else {
- *_data = NULL;
- *_size = 0;
- }
-
- return OK;
-}
-
void ElementaryStreamQueue::clear() {
mBuffer->setRange(0, 0);
mFormat.clear();
@@ -433,79 +358,4 @@
return NULL;
}
-static sp<ABuffer> FindNAL(
- const uint8_t *data, size_t size, unsigned nalType,
- size_t *stopOffset) {
- const uint8_t *nalStart;
- size_t nalSize;
- while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
- if ((nalStart[0] & 0x1f) == nalType) {
- sp<ABuffer> buffer = new ABuffer(nalSize);
- memcpy(buffer->data(), nalStart, nalSize);
- return buffer;
- }
- }
-
- return NULL;
-}
-
-sp<MetaData> ElementaryStreamQueue::MakeAVCCodecSpecificData(
- const sp<ABuffer> &accessUnit) {
- const uint8_t *data = accessUnit->data();
- size_t size = accessUnit->size();
-
- sp<ABuffer> seqParamSet = FindNAL(data, size, 7, NULL);
- if (seqParamSet == NULL) {
- return NULL;
- }
-
- int32_t width, height;
- FindAVCDimensions(seqParamSet, &width, &height);
-
- size_t stopOffset;
- sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
- CHECK(picParamSet != NULL);
-
- size_t csdSize =
- 1 + 3 + 1 + 1
- + 2 * 1 + seqParamSet->size()
- + 1 + 2 * 1 + picParamSet->size();
-
- sp<ABuffer> csd = new ABuffer(csdSize);
- uint8_t *out = csd->data();
-
- *out++ = 0x01; // configurationVersion
- memcpy(out, seqParamSet->data() + 1, 3); // profile/level...
- out += 3;
- *out++ = (0x3f << 2) | 1; // lengthSize == 2 bytes
- *out++ = 0xe0 | 1;
-
- *out++ = seqParamSet->size() >> 8;
- *out++ = seqParamSet->size() & 0xff;
- memcpy(out, seqParamSet->data(), seqParamSet->size());
- out += seqParamSet->size();
-
- *out++ = 1;
-
- *out++ = picParamSet->size() >> 8;
- *out++ = picParamSet->size() & 0xff;
- memcpy(out, picParamSet->data(), picParamSet->size());
-
-#if 0
- LOGI("AVC seq param set");
- hexdump(seqParamSet->data(), seqParamSet->size());
-#endif
-
- sp<MetaData> meta = new MetaData;
- meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
-
- meta->setData(kKeyAVCC, 0, csd->data(), csd->size());
- meta->setInt32(kKeyWidth, width);
- meta->setInt32(kKeyHeight, height);
-
- LOGI("found AVC codec config (%d x %d)", width, height);
-
- return meta;
-}
-
} // namespace android
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 246c390..9eaf834 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -56,9 +56,6 @@
unsigned profile, unsigned sampling_freq_index,
unsigned channel_configuration);
- static sp<MetaData> MakeAVCCodecSpecificData(
- const sp<ABuffer> &accessUnit);
-
DISALLOW_EVIL_CONSTRUCTORS(ElementaryStreamQueue);
};
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 78754e6..10cc88b 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -490,6 +490,8 @@
: mInitCheck(NO_INIT),
mFormat(new MetaData),
mEOSResult(OK),
+ mIsAVC(false),
+ mScanForIDR(true),
mRTPTimeBase(0),
mNormalPlayTimeBaseUs(0),
mLastNormalPlayTimeUs(0) {
@@ -509,6 +511,8 @@
mInitCheck = OK;
if (!strncmp(desc.c_str(), "H264/", 5)) {
+ mIsAVC = true;
+
mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
int32_t width, height;
@@ -719,6 +723,20 @@
return;
}
+ if (mScanForIDR && mIsAVC) {
+ // This pretty piece of code ensures that the first access unit
+ // fed to the decoder after stream-start or seek is guaranteed to
+ // be an IDR frame. This is to workaround limitations of a certain
+ // hardware h.264 decoder that requires this to be the case.
+
+ if (!IsIDR(buffer)) {
+ LOGV("skipping AU while scanning for next IDR frame.");
+ return;
+ }
+
+ mScanForIDR = false;
+ }
+
Mutex::Autolock autoLock(mLock);
mBuffers.push_back(buffer);
mCondition.signal();
@@ -735,6 +753,8 @@
void APacketSource::flushQueue() {
Mutex::Autolock autoLock(mLock);
mBuffers.clear();
+
+ mScanForIDR = true;
}
int64_t APacketSource::getNormalPlayTimeUs() {
diff --git a/media/libstagefright/rtsp/APacketSource.h b/media/libstagefright/rtsp/APacketSource.h
index 076ddc47..7a77fc6 100644
--- a/media/libstagefright/rtsp/APacketSource.h
+++ b/media/libstagefright/rtsp/APacketSource.h
@@ -65,6 +65,9 @@
List<sp<ABuffer> > mBuffers;
status_t mEOSResult;
+ bool mIsAVC;
+ bool mScanForIDR;
+
uint32_t mClockRate;
uint32_t mRTPTimeBase;
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index a31b2b2..2c9cfd3 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -86,6 +86,7 @@
mFirstAccessUnitNTP(0),
mNumAccessUnitsReceived(0),
mCheckPending(false),
+ mCheckGeneration(0),
mTryTCPInterleaving(false),
mReceivedFirstRTCPPacket(false) {
mNetLooper->setName("rtsp net");
@@ -434,6 +435,13 @@
case 'chek':
{
+ int32_t generation;
+ CHECK(msg->findInt32("generation", &generation));
+ if (generation != mCheckGeneration) {
+ // This is an outdated message. Ignore.
+ break;
+ }
+
if (mNumAccessUnitsReceived == 0) {
LOGI("stream ended? aborting.");
(new AMessage('abor', id()))->post();
@@ -454,12 +462,7 @@
}
++mNumAccessUnitsReceived;
-
- if (!mCheckPending) {
- mCheckPending = true;
- sp<AMessage> check = new AMessage('chek', id());
- check->post(kAccessUnitTimeoutUs);
- }
+ postAccessUnitTimeoutCheck();
size_t trackIndex;
CHECK(msg->findSize("track-index", &trackIndex));
@@ -557,6 +560,11 @@
mSeekPending = true;
+ // Disable the access unit timeout until we resumed
+ // playback again.
+ mCheckPending = true;
+ ++mCheckGeneration;
+
AString request = "PAUSE ";
request.append(mSessionURL);
request.append(" RTSP/1.0\r\n");
@@ -612,6 +620,9 @@
LOGI("PLAY completed with result %d (%s)",
result, strerror(-result));
+ mCheckPending = false;
+ postAccessUnitTimeoutCheck();
+
if (result == OK) {
sp<RefBase> obj;
CHECK(msg->findObject("response", &obj));
@@ -674,6 +685,17 @@
}
}
+ void postAccessUnitTimeoutCheck() {
+ if (mCheckPending) {
+ return;
+ }
+
+ mCheckPending = true;
+ sp<AMessage> check = new AMessage('chek', id());
+ check->setInt32("generation", mCheckGeneration);
+ check->post(kAccessUnitTimeoutUs);
+ }
+
static void SplitString(
const AString &s, const char *separator, List<AString> *items) {
items->clear();
@@ -783,6 +805,7 @@
uint64_t mFirstAccessUnitNTP;
int64_t mNumAccessUnitsReceived;
bool mCheckPending;
+ int32_t mCheckGeneration;
bool mTryTCPInterleaving;
bool mReceivedFirstRTCPPacket;
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 361cd3b..84024b8 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -130,6 +130,7 @@
// Handler messages
private static final int MESSAGE_LOCATION_CHANGED = 1;
+ private static final int MESSAGE_PACKAGE_UPDATED = 2;
// wakelock variables
private final static String WAKELOCK_KEY = "LocationManagerService";
@@ -1826,6 +1827,19 @@
handleLocationChangedLocked(location, passive);
}
}
+ } else if (msg.what == MESSAGE_PACKAGE_UPDATED) {
+ String packageName = (String) msg.obj;
+ String packageDot = packageName + ".";
+
+ // reconnect to external providers after their packages have been updated
+ if (mNetworkLocationProvider != null &&
+ mNetworkLocationProviderPackageName.startsWith(packageDot)) {
+ mNetworkLocationProvider.reconnect();
+ }
+ if (mGeocodeProvider != null &&
+ mGeocodeProviderPackageName.startsWith(packageDot)) {
+ mGeocodeProvider.reconnect();
+ }
}
} catch (Exception e) {
// Log, don't crash!
@@ -1928,17 +1942,8 @@
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageUpdateFinished(String packageName, int uid) {
- String packageDot = packageName + ".";
-
- // reconnect to external providers after their packages have been updated
- if (mNetworkLocationProvider != null &&
- mNetworkLocationProviderPackageName.startsWith(packageDot)) {
- mNetworkLocationProvider.reconnect();
- }
- if (mGeocodeProvider != null &&
- mGeocodeProviderPackageName.startsWith(packageDot)) {
- mGeocodeProvider.reconnect();
- }
+ // Called by main thread; divert work to LocationWorker.
+ Message.obtain(mLocationHandler, MESSAGE_PACKAGE_UPDATED, packageName).sendToTarget();
}
};
diff --git a/services/java/com/android/server/location/GeocoderProxy.java b/services/java/com/android/server/location/GeocoderProxy.java
index d9b49fd..e3131fe 100644
--- a/services/java/com/android/server/location/GeocoderProxy.java
+++ b/services/java/com/android/server/location/GeocoderProxy.java
@@ -41,8 +41,8 @@
private final Context mContext;
private final Intent mIntent;
- private final Connection mServiceConnection = new Connection();
- private IGeocodeProvider mProvider;
+ private final Object mMutex = new Object(); // synchronizes access to mServiceConnection
+ private Connection mServiceConnection = new Connection(); // never null
public GeocoderProxy(Context context, String serviceName) {
mContext = context;
@@ -50,34 +50,48 @@
mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
+ /**
+ * When unbundled NetworkLocationService package is updated, we
+ * need to unbind from the old version and re-bind to the new one.
+ */
public void reconnect() {
- synchronized (mServiceConnection) {
+ synchronized (mMutex) {
mContext.unbindService(mServiceConnection);
+ mServiceConnection = new Connection();
mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
}
private class Connection implements ServiceConnection {
+
+ private IGeocodeProvider mProvider;
+
public void onServiceConnected(ComponentName className, IBinder service) {
Log.d(TAG, "onServiceConnected " + className);
- synchronized (mServiceConnection) {
+ synchronized (this) {
mProvider = IGeocodeProvider.Stub.asInterface(service);
}
}
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, "onServiceDisconnected " + className);
- synchronized (mServiceConnection) {
+ synchronized (this) {
mProvider = null;
}
}
+
+ public IGeocodeProvider getProvider() {
+ synchronized (this) {
+ return mProvider;
+ }
+ }
}
public String getFromLocation(double latitude, double longitude, int maxResults,
GeocoderParams params, List<Address> addrs) {
IGeocodeProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
+ synchronized (mMutex) {
+ provider = mServiceConnection.getProvider();
}
if (provider != null) {
try {
@@ -95,8 +109,8 @@
double upperRightLatitude, double upperRightLongitude, int maxResults,
GeocoderParams params, List<Address> addrs) {
IGeocodeProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
+ synchronized (mMutex) {
+ provider = mServiceConnection.getProvider();
}
if (provider != null) {
try {
diff --git a/services/java/com/android/server/location/LocationProviderProxy.java b/services/java/com/android/server/location/LocationProviderProxy.java
index ef2056b..1a1a170 100644
--- a/services/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/java/com/android/server/location/LocationProviderProxy.java
@@ -45,10 +45,10 @@
private final Context mContext;
private final String mName;
- private final String mServiceName;
- private ILocationProvider mProvider;
- private Handler mHandler;
- private final Connection mServiceConnection = new Connection();
+ private final Intent mIntent;
+ private final Handler mHandler;
+ private final Object mMutex = new Object(); // synchronizes access to non-final members
+ private Connection mServiceConnection = new Connection(); // never null
// cached values set by the location manager
private boolean mLocationTracking = false;
@@ -58,89 +58,105 @@
private int mNetworkState;
private NetworkInfo mNetworkInfo;
- // for caching requiresNetwork, requiresSatellite, etc.
- private DummyLocationProvider mCachedAttributes;
-
// constructor for proxying location providers implemented in a separate service
public LocationProviderProxy(Context context, String name, String serviceName,
Handler handler) {
mContext = context;
mName = name;
- mServiceName = serviceName;
+ mIntent = new Intent(serviceName);
mHandler = handler;
- mContext.bindService(new Intent(serviceName), mServiceConnection, Context.BIND_AUTO_CREATE);
+ mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
+ /**
+ * When unbundled NetworkLocationService package is updated, we
+ * need to unbind from the old version and re-bind to the new one.
+ */
public void reconnect() {
- synchronized (mServiceConnection) {
- // unbind first
+ synchronized (mMutex) {
mContext.unbindService(mServiceConnection);
- mContext.bindService(new Intent(mServiceName), mServiceConnection,
- Context.BIND_AUTO_CREATE);
+ mServiceConnection = new Connection();
+ mContext.bindService(mIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
}
}
- private class Connection implements ServiceConnection {
+ private class Connection implements ServiceConnection, Runnable {
+
+ private ILocationProvider mProvider;
+
+ // for caching requiresNetwork, requiresSatellite, etc.
+ private DummyLocationProvider mCachedAttributes; // synchronized by mMutex
+
public void onServiceConnected(ComponentName className, IBinder service) {
Log.d(TAG, "LocationProviderProxy.onServiceConnected " + className);
- synchronized (mServiceConnection) {
+ synchronized (this) {
mProvider = ILocationProvider.Stub.asInterface(service);
if (mProvider != null) {
- mHandler.post(mServiceConnectedTask);
+ mHandler.post(this);
}
}
}
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, "LocationProviderProxy.onServiceDisconnected " + className);
- synchronized (mServiceConnection) {
+ synchronized (this) {
mProvider = null;
}
}
- }
- private Runnable mServiceConnectedTask = new Runnable() {
+ public synchronized ILocationProvider getProvider() {
+ return mProvider;
+ }
+
+ public synchronized DummyLocationProvider getCachedAttributes() {
+ return mCachedAttributes;
+ }
+
public void run() {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
+ synchronized (mMutex) {
+ if (mServiceConnection != this) {
+ // This ServiceConnection no longer the one we want to bind to.
+ return;
+ }
+ ILocationProvider provider = getProvider();
if (provider == null) {
return;
}
- }
- if (mCachedAttributes == null) {
+ // resend previous values from the location manager if the service has restarted
try {
- mCachedAttributes = new DummyLocationProvider(mName, null);
- mCachedAttributes.setRequiresNetwork(provider.requiresNetwork());
- mCachedAttributes.setRequiresSatellite(provider.requiresSatellite());
- mCachedAttributes.setRequiresCell(provider.requiresCell());
- mCachedAttributes.setHasMonetaryCost(provider.hasMonetaryCost());
- mCachedAttributes.setSupportsAltitude(provider.supportsAltitude());
- mCachedAttributes.setSupportsSpeed(provider.supportsSpeed());
- mCachedAttributes.setSupportsBearing(provider.supportsBearing());
- mCachedAttributes.setPowerRequirement(provider.getPowerRequirement());
- mCachedAttributes.setAccuracy(provider.getAccuracy());
+ if (mEnabled) {
+ provider.enable();
+ }
+ if (mLocationTracking) {
+ provider.enableLocationTracking(true);
+ }
+ if (mMinTime >= 0) {
+ provider.setMinTime(mMinTime, mMinTimeSource);
+ }
+ if (mNetworkInfo != null) {
+ provider.updateNetworkState(mNetworkState, mNetworkInfo);
+ }
} catch (RemoteException e) {
- mCachedAttributes = null;
}
- }
- // resend previous values from the location manager if the service has restarted
- try {
- if (mEnabled) {
- provider.enable();
+ // init cache of parameters
+ if (mCachedAttributes == null) {
+ try {
+ mCachedAttributes = new DummyLocationProvider(mName, null);
+ mCachedAttributes.setRequiresNetwork(provider.requiresNetwork());
+ mCachedAttributes.setRequiresSatellite(provider.requiresSatellite());
+ mCachedAttributes.setRequiresCell(provider.requiresCell());
+ mCachedAttributes.setHasMonetaryCost(provider.hasMonetaryCost());
+ mCachedAttributes.setSupportsAltitude(provider.supportsAltitude());
+ mCachedAttributes.setSupportsSpeed(provider.supportsSpeed());
+ mCachedAttributes.setSupportsBearing(provider.supportsBearing());
+ mCachedAttributes.setPowerRequirement(provider.getPowerRequirement());
+ mCachedAttributes.setAccuracy(provider.getAccuracy());
+ } catch (RemoteException e) {
+ mCachedAttributes = null;
+ }
}
- if (mLocationTracking) {
- provider.enableLocationTracking(true);
- }
- if (mMinTime >= 0) {
- provider.setMinTime(mMinTime, mMinTimeSource);
- }
- if (mNetworkInfo != null) {
- provider.updateNetworkState(mNetworkState, mNetworkInfo);
- }
- } catch (RemoteException e) {
}
}
};
@@ -149,79 +165,101 @@
return mName;
}
+ private DummyLocationProvider getCachedAttributes() {
+ synchronized (mMutex) {
+ return mServiceConnection.getCachedAttributes();
+ }
+ }
+
public boolean requiresNetwork() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.requiresNetwork();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.requiresNetwork();
} else {
return false;
}
}
public boolean requiresSatellite() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.requiresSatellite();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.requiresSatellite();
} else {
return false;
}
}
public boolean requiresCell() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.requiresCell();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.requiresCell();
} else {
return false;
}
}
public boolean hasMonetaryCost() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.hasMonetaryCost();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.hasMonetaryCost();
} else {
return false;
}
}
public boolean supportsAltitude() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.supportsAltitude();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.supportsAltitude();
} else {
return false;
}
}
public boolean supportsSpeed() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.supportsSpeed();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.supportsSpeed();
} else {
return false;
}
}
public boolean supportsBearing() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.supportsBearing();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.supportsBearing();
} else {
return false;
}
}
public int getPowerRequirement() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.getPowerRequirement();
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.getPowerRequirement();
+ } else {
+ return -1;
+ }
+ }
+
+ public int getAccuracy() {
+ DummyLocationProvider cachedAttributes = getCachedAttributes();
+ if (cachedAttributes != null) {
+ return cachedAttributes.getAccuracy();
} else {
return -1;
}
}
public boolean meetsCriteria(Criteria criteria) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- return provider.meetsCriteria(criteria);
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ return provider.meetsCriteria(criteria);
+ } catch (RemoteException e) {
+ }
}
}
// default implementation if we lost connection to the provider
@@ -246,50 +284,42 @@
return true;
}
- public int getAccuracy() {
- if (mCachedAttributes != null) {
- return mCachedAttributes.getAccuracy();
- } else {
- return -1;
- }
- }
-
public void enable() {
- mEnabled = true;
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.enable();
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ mEnabled = true;
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.enable();
+ } catch (RemoteException e) {
+ }
}
}
}
public void disable() {
- mEnabled = false;
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.disable();
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ mEnabled = false;
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.disable();
+ } catch (RemoteException e) {
+ }
}
}
}
public boolean isEnabled() {
- return mEnabled;
+ synchronized (mMutex) {
+ return mEnabled;
+ }
}
public int getStatus(Bundle extras) {
ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
+ synchronized (mMutex) {
+ provider = mServiceConnection.getProvider();
}
if (provider != null) {
try {
@@ -301,9 +331,9 @@
}
public long getStatusUpdateTime() {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
+ ILocationProvider provider;
+ synchronized (mMutex) {
+ provider = mServiceConnection.getProvider();
}
if (provider != null) {
try {
@@ -315,32 +345,39 @@
}
public String getInternalState() {
- try {
- return mProvider.getInternalState();
- } catch (RemoteException e) {
- Log.e(TAG, "getInternalState failed", e);
- return null;
- }
- }
-
- public boolean isLocationTracking() {
- return mLocationTracking;
- }
-
- public void enableLocationTracking(boolean enable) {
- mLocationTracking = enable;
- if (!enable) {
- mMinTime = -1;
- mMinTimeSource.clear();
- }
ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
+ synchronized (mMutex) {
+ provider = mServiceConnection.getProvider();
}
if (provider != null) {
try {
- provider.enableLocationTracking(enable);
+ return provider.getInternalState();
} catch (RemoteException e) {
+ Log.e(TAG, "getInternalState failed", e);
+ }
+ }
+ return null;
+ }
+
+ public boolean isLocationTracking() {
+ synchronized (mMutex) {
+ return mLocationTracking;
+ }
+ }
+
+ public void enableLocationTracking(boolean enable) {
+ synchronized (mMutex) {
+ mLocationTracking = enable;
+ if (!enable) {
+ mMinTime = -1;
+ mMinTimeSource.clear();
+ }
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.enableLocationTracking(enable);
+ } catch (RemoteException e) {
+ }
}
}
}
@@ -350,88 +387,84 @@
}
public long getMinTime() {
- return mMinTime;
+ synchronized (mMutex) {
+ return mMinTime;
+ }
}
public void setMinTime(long minTime, WorkSource ws) {
- mMinTime = minTime;
- mMinTimeSource.set(ws);
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.setMinTime(minTime, ws);
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ mMinTime = minTime;
+ mMinTimeSource.set(ws);
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.setMinTime(minTime, ws);
+ } catch (RemoteException e) {
+ }
}
}
}
public void updateNetworkState(int state, NetworkInfo info) {
- mNetworkState = state;
- mNetworkInfo = info;
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.updateNetworkState(state, info);
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ mNetworkState = state;
+ mNetworkInfo = info;
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.updateNetworkState(state, info);
+ } catch (RemoteException e) {
+ }
}
}
}
public void updateLocation(Location location) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.updateLocation(location);
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.updateLocation(location);
+ } catch (RemoteException e) {
+ }
}
}
}
public boolean sendExtraCommand(String command, Bundle extras) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.sendExtraCommand(command, extras);
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ return provider.sendExtraCommand(command, extras);
+ } catch (RemoteException e) {
+ }
}
}
return false;
}
public void addListener(int uid) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.addListener(uid);
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.addListener(uid);
+ } catch (RemoteException e) {
+ }
}
}
}
public void removeListener(int uid) {
- ILocationProvider provider;
- synchronized (mServiceConnection) {
- provider = mProvider;
- }
- if (provider != null) {
- try {
- provider.removeListener(uid);
- } catch (RemoteException e) {
+ synchronized (mMutex) {
+ ILocationProvider provider = mServiceConnection.getProvider();
+ if (provider != null) {
+ try {
+ provider.removeListener(uid);
+ } catch (RemoteException e) {
+ }
}
}
}