summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp245
-rw-r--r--media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h18
-rw-r--r--media/libstagefright/rtsp/APacketSource.cpp83
-rw-r--r--media/libstagefright/rtsp/ARTPConnection.cpp8
-rw-r--r--media/libstagefright/rtsp/ARTPSource.cpp5
-rw-r--r--media/libstagefright/rtsp/MyHandler.h102
-rw-r--r--packages/SettingsProvider/res/values/defaults.xml2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java23
-rw-r--r--packages/SystemUI/res/values/defaults.xml58
-rw-r--r--tools/aapt/Bundle.h5
-rw-r--r--tools/aapt/Main.cpp9
-rw-r--r--tools/aapt/Resource.cpp7
12 files changed, 453 insertions, 112 deletions
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index 7dd3e3f1cd00..f68a35bc1ae7 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -18,29 +18,160 @@
#include "ARTPSource.h"
+#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/Utils.h>
+#include <ctype.h>
#include <stdint.h>
#define BE_VERBOSE 0
namespace android {
+static bool GetAttribute(const char *s, const char *key, AString *value) {
+ value->clear();
+
+ size_t keyLen = strlen(key);
+
+ for (;;) {
+ while (isspace(*s)) {
+ ++s;
+ }
+
+ const char *colonPos = strchr(s, ';');
+
+ size_t len =
+ (colonPos == NULL) ? strlen(s) : colonPos - s;
+
+ if (len >= keyLen + 1 && s[keyLen] == '='
+ && !strncasecmp(s, key, keyLen)) {
+ value->setTo(&s[keyLen + 1], len - keyLen - 1);
+ return true;
+ }
+
+ if (colonPos == NULL) {
+ return false;
+ }
+
+ s = colonPos + 1;
+ }
+}
+
+static bool GetIntegerAttribute(
+ const char *s, const char *key, unsigned *x) {
+ *x = 0;
+
+ AString val;
+ if (!GetAttribute(s, key, &val)) {
+ return false;
+ }
+
+ s = val.c_str();
+ char *end;
+ unsigned y = strtoul(s, &end, 10);
+
+ if (end == s || *end != '\0') {
+ return false;
+ }
+
+ *x = y;
+
+ return true;
+}
+
// static
-AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(const sp<AMessage> &notify)
+AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(
+ const sp<AMessage> &notify, const AString &desc, const AString &params)
: mNotifyMsg(notify),
+ mIsGeneric(false),
+ mParams(params),
+ mSizeLength(0),
+ mIndexLength(0),
+ mIndexDeltaLength(0),
+ mCTSDeltaLength(0),
+ mDTSDeltaLength(0),
+ mRandomAccessIndication(false),
+ mStreamStateIndication(0),
+ mAuxiliaryDataSizeLength(0),
+ mHasAUHeader(false),
mAccessUnitRTPTime(0),
mNextExpectedSeqNoValid(false),
mNextExpectedSeqNo(0),
mAccessUnitDamaged(false) {
+ mIsGeneric = desc.startsWith("mpeg4-generic/");
+
+ if (mIsGeneric) {
+ AString value;
+ CHECK(GetAttribute(params.c_str(), "mode", &value));
+
+ if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) {
+ mSizeLength = 0;
+ }
+
+ if (!GetIntegerAttribute(
+ params.c_str(), "indexLength", &mIndexLength)) {
+ mIndexLength = 0;
+ }
+
+ if (!GetIntegerAttribute(
+ params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) {
+ mIndexDeltaLength = 0;
+ }
+
+ if (!GetIntegerAttribute(
+ params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) {
+ mCTSDeltaLength = 0;
+ }
+
+ if (!GetIntegerAttribute(
+ params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) {
+ mDTSDeltaLength = 0;
+ }
+
+ unsigned x;
+ if (!GetIntegerAttribute(
+ params.c_str(), "randomAccessIndication", &x)) {
+ mRandomAccessIndication = false;
+ } else {
+ CHECK(x == 0 || x == 1);
+ mRandomAccessIndication = (x != 0);
+ }
+
+ if (!GetIntegerAttribute(
+ params.c_str(), "streamStateIndication",
+ &mStreamStateIndication)) {
+ mStreamStateIndication = 0;
+ }
+
+ if (!GetIntegerAttribute(
+ params.c_str(), "auxiliaryDataSizeLength",
+ &mAuxiliaryDataSizeLength)) {
+ mAuxiliaryDataSizeLength = 0;
+ }
+
+ mHasAUHeader =
+ mSizeLength > 0
+ || mIndexLength > 0
+ || mIndexDeltaLength > 0
+ || mCTSDeltaLength > 0
+ || mDTSDeltaLength > 0
+ || mRandomAccessIndication
+ || mStreamStateIndication > 0;
+ }
}
AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() {
}
+struct AUHeader {
+ unsigned mSize;
+ unsigned mSerial;
+};
+
ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
const sp<ARTPSource> &source) {
List<sp<ABuffer> > *queue = source->queue();
@@ -85,8 +216,116 @@ ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
}
mAccessUnitRTPTime = rtpTime;
- mPackets.push_back(buffer);
- // hexdump(buffer->data(), buffer->size());
+ if (!mIsGeneric) {
+ mPackets.push_back(buffer);
+ } else {
+ // hexdump(buffer->data(), buffer->size());
+
+ CHECK_GE(buffer->size(), 2u);
+ unsigned AU_headers_length = U16_AT(buffer->data()); // in bits
+
+ CHECK_GE(buffer->size(), 2 + (AU_headers_length + 7) / 8);
+
+ List<AUHeader> headers;
+
+ ABitReader bits(buffer->data() + 2, buffer->size() - 2);
+ unsigned numBitsLeft = AU_headers_length;
+
+ unsigned AU_serial = 0;
+ for (;;) {
+ if (numBitsLeft < mSizeLength) { break; }
+
+ unsigned AU_size = bits.getBits(mSizeLength);
+ numBitsLeft -= mSizeLength;
+
+ size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength;
+ if (numBitsLeft < n) { break; }
+
+ unsigned AU_index = bits.getBits(n);
+ numBitsLeft -= n;
+
+ if (headers.empty()) {
+ AU_serial = AU_index;
+ } else {
+ AU_serial += 1 + AU_index;
+ }
+
+ if (mCTSDeltaLength > 0) {
+ if (numBitsLeft < 1) {
+ break;
+ }
+ --numBitsLeft;
+ if (bits.getBits(1)) {
+ if (numBitsLeft < mCTSDeltaLength) {
+ break;
+ }
+ bits.skipBits(mCTSDeltaLength);
+ numBitsLeft -= mCTSDeltaLength;
+ }
+ }
+
+ if (mDTSDeltaLength > 0) {
+ if (numBitsLeft < 1) {
+ break;
+ }
+ --numBitsLeft;
+ if (bits.getBits(1)) {
+ if (numBitsLeft < mDTSDeltaLength) {
+ break;
+ }
+ bits.skipBits(mDTSDeltaLength);
+ numBitsLeft -= mDTSDeltaLength;
+ }
+ }
+
+ if (mRandomAccessIndication) {
+ if (numBitsLeft < 1) {
+ break;
+ }
+ bits.skipBits(1);
+ --numBitsLeft;
+ }
+
+ if (mStreamStateIndication > 0) {
+ if (numBitsLeft < mStreamStateIndication) {
+ break;
+ }
+ bits.skipBits(mStreamStateIndication);
+ }
+
+ AUHeader header;
+ header.mSize = AU_size;
+ header.mSerial = AU_serial;
+ headers.push_back(header);
+ }
+
+ size_t offset = 2 + (AU_headers_length + 7) / 8;
+
+ if (mAuxiliaryDataSizeLength > 0) {
+ ABitReader bits(buffer->data() + offset, buffer->size() - offset);
+
+ unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
+
+ offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
+ }
+
+ for (List<AUHeader>::iterator it = headers.begin();
+ it != headers.end(); ++it) {
+ const AUHeader &header = *it;
+
+ CHECK_LE(offset + header.mSize, buffer->size());
+
+ sp<ABuffer> accessUnit = new ABuffer(header.mSize);
+ memcpy(accessUnit->data(), buffer->data() + offset, header.mSize);
+
+ offset += header.mSize;
+
+ CopyTimes(accessUnit, buffer);
+ mPackets.push_back(accessUnit);
+ }
+
+ CHECK_EQ(offset, buffer->size());
+ }
queue->erase(queue->begin());
++mNextExpectedSeqNo;
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
index 1566d00219f2..794bbcc6c4e6 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.h
@@ -20,6 +20,8 @@
#include "ARTPAssembler.h"
+#include <media/stagefright/foundation/AString.h>
+
#include <utils/List.h>
#include <utils/RefBase.h>
@@ -29,7 +31,9 @@ struct ABuffer;
struct AMessage;
struct AMPEG4ElementaryAssembler : public ARTPAssembler {
- AMPEG4ElementaryAssembler(const sp<AMessage> &notify);
+ AMPEG4ElementaryAssembler(
+ const sp<AMessage> &notify, const AString &desc,
+ const AString &params);
protected:
virtual ~AMPEG4ElementaryAssembler();
@@ -40,6 +44,18 @@ protected:
private:
sp<AMessage> mNotifyMsg;
+ bool mIsGeneric;
+ AString mParams;
+
+ unsigned mSizeLength;
+ unsigned mIndexLength;
+ unsigned mIndexDeltaLength;
+ unsigned mCTSDeltaLength;
+ unsigned mDTSDeltaLength;
+ bool mRandomAccessIndication;
+ unsigned mStreamStateIndication;
+ unsigned mAuxiliaryDataSizeLength;
+ bool mHasAUHeader;
uint32_t mAccessUnitRTPTime;
bool mNextExpectedSeqNoValid;
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index 2d7738b0d8c7..75b45716d49e 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -247,6 +247,65 @@ sp<ABuffer> MakeAACCodecSpecificData(const char *params) {
return csd;
}
+// From mpeg4-generic configuration data.
+sp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
+ AString val;
+ unsigned long objectType;
+ if (GetAttribute(params, "objectType", &val)) {
+ const char *s = val.c_str();
+ char *end;
+ objectType = strtoul(s, &end, 10);
+ CHECK(end > s && *end == '\0');
+ } else {
+ objectType = 0x40; // Audio ISO/IEC 14496-3
+ }
+
+ CHECK(GetAttribute(params, "config", &val));
+
+ sp<ABuffer> config = decodeHex(val);
+ CHECK(config != NULL);
+
+ // Make sure size fits into a single byte and doesn't have to
+ // be encoded.
+ CHECK_LT(20 + config->size(), 128u);
+
+ const uint8_t *data = config->data();
+
+ static const uint8_t kStaticESDS[] = {
+ 0x03, 22,
+ 0x00, 0x00, // ES_ID
+ 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
+
+ 0x04, 17,
+ 0x40, // Audio ISO/IEC 14496-3
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ 0x05, 2,
+ // AudioSpecificInfo follows
+ };
+
+ sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
+ uint8_t *dst = csd->data();
+ *dst++ = 0x03;
+ *dst++ = 20 + config->size();
+ *dst++ = 0x00; // ES_ID
+ *dst++ = 0x00;
+ *dst++ = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
+ *dst++ = 0x04;
+ *dst++ = 15 + config->size();
+ *dst++ = objectType;
+ for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
+ *dst++ = 0x05;
+ *dst++ = config->size();
+ memcpy(dst, config->data(), config->size());
+
+ // hexdump(csd->data(), csd->size());
+
+ return csd;
+}
+
static size_t GetSizeWidth(size_t x) {
size_t n = 1;
while (x > 127) {
@@ -560,6 +619,30 @@ APacketSource::APacketSource(
mFormat->setInt32(kKeyWidth, width);
mFormat->setInt32(kKeyHeight, height);
+ } else if (!strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+ AString val;
+ if (!GetAttribute(params.c_str(), "mode", &val)
+ || (strcasecmp(val.c_str(), "AAC-lbr")
+ && strcasecmp(val.c_str(), "AAC-hbr"))) {
+ mInitCheck = ERROR_UNSUPPORTED;
+ return;
+ }
+
+ mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
+
+ int32_t sampleRate, numChannels;
+ ASessionDescription::ParseFormatDesc(
+ desc.c_str(), &sampleRate, &numChannels);
+
+ mFormat->setInt32(kKeySampleRate, sampleRate);
+ mFormat->setInt32(kKeyChannelCount, numChannels);
+
+ sp<ABuffer> codecSpecificData =
+ MakeAACCodecSpecificData2(params.c_str());
+
+ mFormat->setData(
+ kKeyESDS, 0,
+ codecSpecificData->data(), codecSpecificData->size());
} else {
mInitCheck = ERROR_UNSUPPORTED;
}
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index 12f8f323b61a..10c9e028878a 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -362,7 +362,6 @@ status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
if (receiveRTP) {
err = parseRTP(s, buffer);
} else {
- ++s->mNumRTCPPacketsReceived;
err = parseRTCP(s, buffer);
}
@@ -456,6 +455,12 @@ status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
}
status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
+ if (s->mNumRTCPPacketsReceived++ == 0) {
+ sp<AMessage> notify = s->mNotifyMsg->dup();
+ notify->setInt32("first-rtcp", true);
+ notify->post();
+ }
+
const uint8_t *data = buffer->data();
size_t size = buffer->size();
@@ -626,7 +631,6 @@ void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
if (it->mRTPSocket == index) {
err = parseRTP(s, buffer);
} else {
- ++s->mNumRTCPPacketsReceived;
err = parseRTCP(s, buffer);
}
}
diff --git a/media/libstagefright/rtsp/ARTPSource.cpp b/media/libstagefright/rtsp/ARTPSource.cpp
index 775c4eeaa272..9656ba2c7eb2 100644
--- a/media/libstagefright/rtsp/ARTPSource.cpp
+++ b/media/libstagefright/rtsp/ARTPSource.cpp
@@ -64,8 +64,9 @@ ARTPSource::ARTPSource(
mAssembler = new AAMRAssembler(notify, false /* isWide */, params);
} else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
mAssembler = new AAMRAssembler(notify, true /* isWide */, params);
- } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
- mAssembler = new AMPEG4ElementaryAssembler(notify);
+ } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)
+ || !strncmp(desc.c_str(), "mpeg4-generic/", 14)) {
+ mAssembler = new AMPEG4ElementaryAssembler(notify, desc, params);
mIssueFIRRequests = true;
} else {
TRESPASS();
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index ee6f65a8a106..b84911724930 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -82,7 +82,8 @@ struct MyHandler : public AHandler {
mFirstAccessUnitNTP(0),
mNumAccessUnitsReceived(0),
mCheckPending(false),
- mTryTCPInterleaving(false) {
+ mTryTCPInterleaving(false),
+ mReceivedFirstRTCPPacket(false) {
mNetLooper->setName("rtsp net");
mNetLooper->start(false /* runOnCallingThread */,
false /* canCallJava */,
@@ -199,31 +200,35 @@ struct MyHandler : public AHandler {
break;
}
- CHECK_EQ(response->mStatusCode, 200u);
-
- mSessionDesc = new ASessionDescription;
+ if (response->mStatusCode != 200) {
+ result = UNKNOWN_ERROR;
+ } else {
+ mSessionDesc = new ASessionDescription;
- mSessionDesc->setTo(
- response->mContent->data(),
- response->mContent->size());
+ mSessionDesc->setTo(
+ response->mContent->data(),
+ response->mContent->size());
- CHECK(mSessionDesc->isValid());
+ CHECK(mSessionDesc->isValid());
- ssize_t i = response->mHeaders.indexOfKey("content-base");
- if (i >= 0) {
- mBaseURL = response->mHeaders.valueAt(i);
- } else {
- i = response->mHeaders.indexOfKey("content-location");
+ ssize_t i = response->mHeaders.indexOfKey("content-base");
if (i >= 0) {
mBaseURL = response->mHeaders.valueAt(i);
} else {
- mBaseURL = mSessionURL;
+ i = response->mHeaders.indexOfKey("content-location");
+ if (i >= 0) {
+ mBaseURL = response->mHeaders.valueAt(i);
+ } else {
+ mBaseURL = mSessionURL;
+ }
}
+
+ CHECK_GT(mSessionDesc->countTracks(), 1u);
+ setupTrack(1);
}
+ }
- CHECK_GT(mSessionDesc->countTracks(), 1u);
- setupTrack(1);
- } else {
+ if (result != OK) {
sp<AMessage> reply = new AMessage('disc', id());
mConn->disconnect(reply);
}
@@ -247,16 +252,7 @@ struct MyHandler : public AHandler {
LOG(INFO) << "SETUP(" << index << ") completed with result "
<< result << " (" << strerror(-result) << ")";
- if (result != OK) {
- if (track) {
- if (!track->mUsingInterleavedTCP) {
- close(track->mRTPSocket);
- close(track->mRTCPSocket);
- }
-
- mTracks.removeItemsAt(trackIndex);
- }
- } else {
+ if (result == OK) {
CHECK(track != NULL);
sp<RefBase> obj;
@@ -264,29 +260,40 @@ struct MyHandler : public AHandler {
sp<ARTSPResponse> response =
static_cast<ARTSPResponse *>(obj.get());
- CHECK_EQ(response->mStatusCode, 200u);
-
- ssize_t i = response->mHeaders.indexOfKey("session");
- CHECK_GE(i, 0);
+ if (response->mStatusCode != 200) {
+ result = UNKNOWN_ERROR;
+ } else {
+ ssize_t i = response->mHeaders.indexOfKey("session");
+ CHECK_GE(i, 0);
- if (index == 1) {
mSessionID = response->mHeaders.valueAt(i);
i = mSessionID.find(";");
if (i >= 0) {
// Remove options, i.e. ";timeout=90"
mSessionID.erase(i, mSessionID.size() - i);
}
- }
- sp<AMessage> notify = new AMessage('accu', id());
- notify->setSize("track-index", trackIndex);
+ sp<AMessage> notify = new AMessage('accu', id());
+ notify->setSize("track-index", trackIndex);
- mRTPConn->addStream(
- track->mRTPSocket, track->mRTCPSocket,
- mSessionDesc, index,
- notify, track->mUsingInterleavedTCP);
+ mRTPConn->addStream(
+ track->mRTPSocket, track->mRTCPSocket,
+ mSessionDesc, index,
+ notify, track->mUsingInterleavedTCP);
- mSetupTracksSuccessful = true;
+ mSetupTracksSuccessful = true;
+ }
+ }
+
+ if (result != OK) {
+ if (track) {
+ if (!track->mUsingInterleavedTCP) {
+ close(track->mRTPSocket);
+ close(track->mRTCPSocket);
+ }
+
+ mTracks.removeItemsAt(trackIndex);
+ }
}
++index;
@@ -355,6 +362,12 @@ struct MyHandler : public AHandler {
}
}
mTracks.clear();
+ mSetupTracksSuccessful = false;
+ mSeekPending = false;
+ mFirstAccessUnit = true;
+ mFirstAccessUnitNTP = 0;
+ mNumAccessUnitsReceived = 0;
+ mReceivedFirstRTCPPacket = false;
sp<AMessage> reply = new AMessage('tear', id());
@@ -424,6 +437,12 @@ struct MyHandler : public AHandler {
case 'accu':
{
+ int32_t firstRTCP;
+ if (msg->findInt32("first-rtcp", &firstRTCP)) {
+ mReceivedFirstRTCPPacket = true;
+ break;
+ }
+
++mNumAccessUnitsReceived;
if (!mCheckPending) {
@@ -612,7 +631,7 @@ struct MyHandler : public AHandler {
case 'tiou':
{
- if (mFirstAccessUnit) {
+ if (!mReceivedFirstRTCPPacket) {
if (mTryTCPInterleaving) {
LOG(WARNING) << "Never received any data, disconnecting.";
(new AMessage('abor', id()))->post();
@@ -747,6 +766,7 @@ private:
int64_t mNumAccessUnitsReceived;
bool mCheckPending;
bool mTryTCPInterleaving;
+ bool mReceivedFirstRTCPPacket;
struct TrackInfo {
AString mURL;
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 8349fe6fa797..52e04d7dadb1 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -22,7 +22,7 @@
<bool name="def_airplane_mode_on">false</bool>
<!-- Comma-separated list of bluetooth, wifi, and cell. -->
<string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string>
- <string name="airplane_mode_toggleable_radios" translatable="false">wifi</string>
+ <string name="airplane_mode_toggleable_radios" translatable="false">bluetooth,wifi</string>
<bool name="def_auto_time">true</bool>
<bool name="def_accelerometer_rotation">true</bool>
<!-- Default screen brightness, from 0 to 255. 102 is 40%. -->
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 7395233d0bdb..ad04bb4334c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -64,7 +64,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 56;
+ private static final int DATABASE_VERSION = 57;
private Context mContext;
@@ -713,6 +713,27 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
upgradeVersion = 56;
}
+
+ if (upgradeVersion == 56) {
+ /*
+ * Add Bluetooth to list of toggleable radios in airplane mode
+ */
+ db.beginTransaction();
+ SQLiteStatement stmt = null;
+ try {
+ db.execSQL("DELETE FROM system WHERE name='"
+ + Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS + "'");
+ stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
+ R.string.airplane_mode_toggleable_radios);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ if (stmt != null) stmt.close();
+ }
+ upgradeVersion = 57;
+ }
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/values/defaults.xml b/packages/SystemUI/res/values/defaults.xml
index 34302c4792ab..df07a3d0453d 100644
--- a/packages/SystemUI/res/values/defaults.xml
+++ b/packages/SystemUI/res/values/defaults.xml
@@ -17,62 +17,4 @@
*/
-->
<resources>
- <bool name="def_dim_screen">true</bool>
- <integer name="def_screen_off_timeout">60000</integer>
- <bool name="def_airplane_mode_on">false</bool>
- <!-- Comma-separated list of bluetooth, wifi, and cell. -->
- <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi</string>
- <string name="airplane_mode_toggleable_radios" translatable="false">wifi</string>
- <bool name="def_auto_time">true</bool>
- <bool name="def_accelerometer_rotation">true</bool>
- <!-- Default screen brightness, from 0 to 255. 102 is 40%. -->
- <integer name="def_screen_brightness">102</integer>
- <bool name="def_screen_brightness_automatic_mode">false</bool>
- <fraction name="def_window_animation_scale">100%</fraction>
- <fraction name="def_window_transition_scale">100%</fraction>
- <bool name="def_haptic_feedback">true</bool>
-
- <bool name="def_bluetooth_on">false</bool>
- <bool name="def_install_non_market_apps">false</bool>
- <!-- Comma-separated list of location providers.
- Network location is off by default because it requires
- user opt-in via Setup Wizard or Settings.
- -->
- <string name="def_location_providers_allowed" translatable="false">gps</string>
- <bool name="assisted_gps_enabled">true</bool>
- <!-- 0 == mobile, 1 == wifi. -->
- <integer name="def_network_preference">1</integer>
- <bool name="def_usb_mass_storage_enabled">true</bool>
- <bool name="def_wifi_on">false</bool>
- <bool name="def_networks_available_notification_on">true</bool>
-
- <bool name="def_backup_enabled">false</bool>
- <string name="def_backup_transport" translatable="false"></string>
- <!-- Default value for whether or not to pulse the notification LED when there is a
- pending notification -->
- <bool name="def_notification_pulse">true</bool>
-
- <bool name="def_mount_play_notification_snd">true</bool>
- <bool name="def_mount_ums_autostart">false</bool>
- <bool name="def_mount_ums_prompt">true</bool>
- <bool name="def_mount_ums_notify_enabled">true</bool>
- <!-- Enable User preference for setting install location -->
- <bool name="set_install_location">true</bool>
- <!-- Default install location if user preference for setting install location is turned on. -->
- <integer name="def_install_location">2</integer>
-
- <!-- user interface sound effects -->
- <integer name="def_power_sounds_enabled">1</integer>
- <string name="def_low_battery_sound" translatable="false">/system/media/audio/ui/LowBattery.ogg</string>
- <integer name="def_dock_sounds_enabled">0</integer>
- <string name="def_desk_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
- <string name="def_desk_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
- <string name="def_car_dock_sound" translatable="false">/system/media/audio/ui/Dock.ogg</string>
- <string name="def_car_undock_sound" translatable="false">/system/media/audio/ui/Undock.ogg</string>
- <integer name="def_lockscreen_sounds_enabled">0</integer>
- <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string>
- <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string>
-
- <!-- Default for Settings.System.VIBRATE_IN_SILENT -->
- <bool name="def_vibrate_in_silent">true</bool>
</resources>
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 6a1f2d58cdaf..a1bc24144f3d 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -45,7 +45,7 @@ public:
mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
- mMaxResVersion(NULL),
+ mMaxResVersion(NULL), mDebugMode(false),
mArgc(0), mArgv(NULL)
{}
~Bundle(void) {}
@@ -137,6 +137,8 @@ public:
void setCustomPackage(const char* val) { mCustomPackage = val; }
const char* getMaxResVersion() const { return mMaxResVersion; }
void setMaxResVersion(const char * val) { mMaxResVersion = val; }
+ bool getDebugMode() { return mDebugMode; }
+ void setDebugMode(bool val) { mDebugMode = val; }
/*
* Set and get the file specification.
@@ -234,6 +236,7 @@ private:
const char* mVersionName;
const char* mCustomPackage;
const char* mMaxResVersion;
+ bool mDebugMode;
/* file specification */
int mArgc;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index f457cc8b3323..71c023d93448 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -57,7 +57,7 @@ void usage(void)
fprintf(stderr,
" %s p[ackage] [-d][-f][-m][-u][-v][-x][-z][-M AndroidManifest.xml] \\\n"
" [-0 extension [-0 extension ...]] [-g tolerance] [-j jarfile] \\\n"
- " [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
+ " [--debug-mode] [--min-sdk-version VAL] [--target-sdk-version VAL] \\\n"
" [--app-version VAL] [--app-version-name TEXT] [--custom-package VAL] \\\n"
" [--rename-manifest-package PACKAGE] \\\n"
" [--rename-instrumentation-target-package PACKAGE] \\\n"
@@ -124,6 +124,9 @@ void usage(void)
" -0 specifies an additional extension for which such files will not\n"
" be stored compressed in the .apk. An empty string means to not\n"
" compress any files at all.\n"
+ " --debug-mode\n"
+ " inserts android:debuggable=\"true\" in to the application node of the\n"
+ " manifest, making the application debuggable even on production devices.\n"
" --min-sdk-version\n"
" inserts android:minSdkVersion in to manifest. If the version is 7 or\n"
" higher, the default encoding for resources will be in UTF-8.\n"
@@ -392,7 +395,9 @@ int main(int argc, char* const argv[])
}
break;
case '-':
- if (strcmp(cp, "-min-sdk-version") == 0) {
+ if (strcmp(cp, "-debug-mode") == 0) {
+ bundle.setDebugMode(true);
+ } else if (strcmp(cp, "-min-sdk-version") == 0) {
argc--;
argv++;
if (!argc) {
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index bd84e236a3ec..9c5fcda2bcf0 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -678,6 +678,13 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root)
bundle->getMaxSdkVersion());
}
+ if (bundle->getDebugMode()) {
+ sp<XMLNode> application = root->getChildElement(String16(), String16("application"));
+ if (application != NULL) {
+ addTagAttribute(application, RESOURCES_ANDROID_NAMESPACE, "debuggable", "true");
+ }
+ }
+
// Deal with manifest package name overrides
const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride();
if (manifestPackageNameOverride != NULL) {