Merge "Some documentation fixes." into gingerbread
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index 971a177..afa64f8 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -143,15 +143,20 @@
send(the_socket, message, length, 0);
}
-/* Here is the file format. Values are encrypted by AES CBC, and MD5 is used to
- * compute their checksums. To make the files portable, the length is stored in
- * network order. Note that the first four bytes are reserved for future use and
- * are always set to zero in this implementation. */
+/* Here is the file format. There are two parts in blob.value, the secret and
+ * the description. The secret is stored in ciphertext, and its original size
+ * can be found in blob.length. The description is stored after the secret in
+ * plaintext, and its size is specified in blob.info. The total size of the two
+ * parts must be no more than VALUE_SIZE bytes. The first three bytes of the
+ * file are reserved for future use and are always set to zero. Fields other
+ * than blob.info, blob.length, and blob.value are modified by encrypt_blob()
+ * and decrypt_blob(). Thus they should not be accessed from outside. */
static int the_entropy = -1;
static struct __attribute__((packed)) {
- uint32_t reserved;
+ uint8_t reserved[3];
+ uint8_t info;
uint8_t vector[AES_BLOCK_SIZE];
uint8_t encrypted[0];
uint8_t digest[MD5_DIGEST_LENGTH];
@@ -170,9 +175,13 @@
return SYSTEM_ERROR;
}
- length = blob.length + blob.value - blob.encrypted;
+ length = blob.length + (blob.value - blob.encrypted);
length = (length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
+ if (blob.info != 0) {
+ memmove(&blob.encrypted[length], &blob.value[blob.length], blob.info);
+ }
+
blob.length = htonl(blob.length);
MD5(blob.digested, length - (blob.digested - blob.encrypted), blob.digest);
@@ -180,8 +189,8 @@
AES_cbc_encrypt(blob.encrypted, blob.encrypted, length, aes_key, vector,
AES_ENCRYPT);
- blob.reserved = 0;
- length += blob.encrypted - (uint8_t *)&blob;
+ memset(blob.reserved, 0, sizeof(blob.reserved));
+ length += (blob.encrypted - (uint8_t *)&blob) + blob.info;
fd = open(".tmp", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
length -= write(fd, &blob, length);
@@ -200,7 +209,7 @@
length = read(fd, &blob, sizeof(blob));
close(fd);
- length -= blob.encrypted - (uint8_t *)&blob;
+ length -= (blob.encrypted - (uint8_t *)&blob) + blob.info;
if (length < blob.value - blob.encrypted || length % AES_BLOCK_SIZE != 0) {
return VALUE_CORRUPTED;
}
@@ -215,8 +224,13 @@
length -= blob.value - blob.digested;
blob.length = ntohl(blob.length);
- return (blob.length < 0 || blob.length > length) ? VALUE_CORRUPTED :
- NO_ERROR;
+ if (blob.length < 0 || blob.length > length) {
+ return VALUE_CORRUPTED;
+ }
+ if (blob.info != 0) {
+ memmove(&blob.value[blob.length], &blob.value[length], blob.info);
+ }
+ return NO_ERROR;
}
/* Here are the actions. Each of them is a function without arguments. All
@@ -266,6 +280,7 @@
char name[NAME_MAX];
int n = sprintf(name, "%u_", uid);
encode_key(&name[n], params[0].value, params[0].length);
+ blob.info = 0;
blob.length = params[1].length;
memcpy(blob.value, params[1].value, params[1].length);
return encrypt_blob(name, &encryption_key);
@@ -336,56 +351,88 @@
#define MASTER_KEY_FILE ".masterkey"
#define MASTER_KEY_SIZE 16
+#define SALT_SIZE 16
-static void generate_key(uint8_t *key, uint8_t *password, int length)
+static void set_key(uint8_t *key, uint8_t *password, int length, uint8_t *salt)
{
- PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, (uint8_t *)"keystore",
- sizeof("keystore"), 1024, MASTER_KEY_SIZE, key);
+ if (salt) {
+ PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, salt, SALT_SIZE,
+ 8192, MASTER_KEY_SIZE, key);
+ } else {
+ PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, (uint8_t *)"keystore",
+ sizeof("keystore"), 1024, MASTER_KEY_SIZE, key);
+ }
}
+/* Here is the history. To improve the security, the parameters to generate the
+ * master key has been changed. To make a seamless transition, we update the
+ * file using the same password when the user unlock it for the first time. If
+ * any thing goes wrong during the transition, the new file will not overwrite
+ * the old one. This avoids permanent damages of the existing data. */
+
static int8_t password()
{
uint8_t key[MASTER_KEY_SIZE];
AES_KEY aes_key;
- int n;
+ int8_t response = SYSTEM_ERROR;
if (state == UNINITIALIZED) {
- blob.length = MASTER_KEY_SIZE;
if (read(the_entropy, blob.value, MASTER_KEY_SIZE) != MASTER_KEY_SIZE) {
return SYSTEM_ERROR;
}
} else {
- generate_key(key, params[0].value, params[0].length);
+ int fd = open(MASTER_KEY_FILE, O_RDONLY);
+ uint8_t *salt = NULL;
+ if (fd != -1) {
+ int length = read(fd, &blob, sizeof(blob));
+ close(fd);
+ if (length > SALT_SIZE && blob.info == SALT_SIZE) {
+ salt = (uint8_t *)&blob + length - SALT_SIZE;
+ }
+ }
+
+ set_key(key, params[0].value, params[0].length, salt);
AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key);
- n = decrypt_blob(MASTER_KEY_FILE, &aes_key);
- if (n == SYSTEM_ERROR) {
+ response = decrypt_blob(MASTER_KEY_FILE, &aes_key);
+ if (response == SYSTEM_ERROR) {
return SYSTEM_ERROR;
}
- if (n != NO_ERROR || blob.length != MASTER_KEY_SIZE) {
+ if (response != NO_ERROR || blob.length != MASTER_KEY_SIZE) {
if (retry <= 0) {
reset();
return UNINITIALIZED;
}
return WRONG_PASSWORD + --retry;
}
+
+ if (!salt && params[1].length == -1) {
+ params[1] = params[0];
+ }
}
if (params[1].length == -1) {
memcpy(key, blob.value, MASTER_KEY_SIZE);
} else {
- generate_key(key, params[1].value, params[1].length);
+ uint8_t *salt = &blob.value[MASTER_KEY_SIZE];
+ if (read(the_entropy, salt, SALT_SIZE) != SALT_SIZE) {
+ return SYSTEM_ERROR;
+ }
+
+ set_key(key, params[1].value, params[1].length, salt);
AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key);
memcpy(key, blob.value, MASTER_KEY_SIZE);
- n = encrypt_blob(MASTER_KEY_FILE, &aes_key);
+ blob.info = SALT_SIZE;
+ blob.length = MASTER_KEY_SIZE;
+ response = encrypt_blob(MASTER_KEY_FILE, &aes_key);
}
- if (n == NO_ERROR) {
+ if (response == NO_ERROR) {
AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &encryption_key);
AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &decryption_key);
state = NO_ERROR;
retry = MAX_RETRY;
}
- return n;
+ return response;
}
static int8_t lock()
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index c12cd48..954b3e7 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -73,6 +73,7 @@
public final static int FLAG_ALT_GR = 0x00000020;
public final static int FLAG_MENU = 0x00000040;
public final static int FLAG_LAUNCHER = 0x00000080;
+ public final static int FLAG_VIRTUAL = 0x00000100;
public final static int FLAG_INJECTED = 0x01000000;
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 4cdf4f6f..02524bf 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -244,6 +244,7 @@
<item name="android:clickable">true</item>
<item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
<item name="android:textColor">@android:color/primary_text_light</item>
+ <item name="android:textStyle">bold</item>
<item name="android:gravity">center_vertical|center_horizontal</item>
</style>
diff --git a/docs/html/resources/dashboard/platform-versions.jd b/docs/html/resources/dashboard/platform-versions.jd
index 92d4e15..3b4ccb0e 100644
--- a/docs/html/resources/dashboard/platform-versions.jd
+++ b/docs/html/resources/dashboard/platform-versions.jd
@@ -52,7 +52,7 @@
<div class="dashboard-panel">
<img alt="" height="250" width="460"
-src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:12.0,17.5,0.1,41.7,28.7&chl=
+src="http://chart.apis.google.com/chart?&cht=p&chs=460x250&chd=t:9.7,16.4,0.1,40.4,33.4&chl=
Android%201.5|Android%201.6|Other*|Android%202.1|Android%202.2&chco=c4df9b,
6fad0c" />
@@ -62,13 +62,13 @@
<th>API Level</th>
<th>Distribution</th>
</tr>
-<tr><td>Android 1.5</td><td>3</td><td>12.0%</td></tr>
-<tr><td>Android 1.6</td><td>4</td><td>17.5%</td></tr>
-<tr><td>Android 2.1</td><td>7</td><td>41.7%</td></tr>
-<tr><td>Android 2.2</td><td>8</td><td>28.7%</td></tr>
+<tr><td>Android 1.5</td><td>3</td><td>9.7%</td></tr>
+<tr><td>Android 1.6</td><td>4</td><td>16.4%</td></tr>
+<tr><td>Android 2.1</td><td>7</td><td>40.4%</td></tr>
+<tr><td>Android 2.2</td><td>8</td><td>33.4%</td></tr>
</table>
-<p><em>Data collected during two weeks ending on September 1, 2010</em></p>
+<p><em>Data collected during two weeks ending on October 1, 2010</em></p>
<p style="font-size:.9em">* <em>Other: 0.1% of devices running obsolete versions</em></p>
</div><!-- end dashboard-panel -->
@@ -96,19 +96,19 @@
<div class="dashboard-panel">
<img alt="" height="250" width="660" style="padding:5px;background:#fff"
-src="http://chart.apis.google.com/chart?&cht=lc&chs=660x250&chxt=x,y,r&chxr=0,0,12|1,0,100|2,0,100&
-chxl=0%3A%7C2010/03/01%7C03/15%7C04/01%7C04/15%7C05/01%7C05/15%7C06/01%7C06/15%7C07/01%7C07/15%7C08/
-01%7C08/15%7C2010/09/01%7C1%3A%7C0%25%7C25%25%7C50%25%7C75%25%7C100%25%7C2%3A%7C0%25%7C25%25%7C50%25
-%7C75%25%7C100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&chxtc=0,5&chd=t:99.4,99.5,99.6,99.6,99.6,99.7,
-100.6,101.1,99.9,100.0,100.0,99.8,99.9|61.6,60.6,61.5,61.7,62.3,63.5,73.0,76.4,78.6,81.1,84.5,86.6,
-88.0|24.3,25.4,29.4,30.2,32.7,35.3,46.2,51.3,55.1,59.0,64.1,68.2,70.4|0.0,0.0,4.0,28.3,32.0,34.9,45.
-9,51.0,54.9,58.8,64.0,68.1,70.3|0.0,0.0,0.0,0.0,0.0,0.0,0.8,1.2,1.8,3.3,4.3,11.3,27.8&chm=tAndroid%
-201.5,7caa36,0,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid%201.6,638d23,1,0,15,,t::-5|b,b0db6e,1,2,0|
-tAndroid%202.0.1,496c13,2,0,15,,t::-5|b,9ddb3d,2,3,0|tAndroid%202.1,2f4708,3,3,15,,t::-5|b,89cf19,3,
-4,0|tAndroid%202.2,131d02,4,11,15,,t::-5|B,6fad0c,4,5,0&chg=7,25&chdl=Android%201.5|Android%201.6|
-Android%202.0.1|Android%202.1|Android%202.2&chco=add274,9ad145,84c323,6ba213,507d08" />
+src="http://chart.apis.google.com/chart?cht=lc&chs=660x250&chxt=x,y,r&chxr=0,0,12|1,0,100|2,0,100&
+chxl=0:|2010/04/01|04/15|05/01|05/15|06/01|06/15|07/01|07/15|08/01|08/15|09/01|09/15|2010/10/01|1:|0
+%25|25%25|50%25|75%25|100%25|2:|0%25|25%25|50%25|75%25|100%25&chxp=0,0,1,2,3,4,5,6,7,8,9,10,11,12&
+chxtc=0,5&chd=t:99.6,99.6,99.6,99.7,100.6,101.1,99.9,100.0,100.0,99.8,99.9,100.0,100.0|61.5,61.7,62.
+3,63.5,73.0,76.4,78.6,81.1,84.5,86.6,88.0,89.3,90.3|29.4,30.2,32.7,35.3,46.2,51.3,55.1,59.0,64.1,68.
+2,70.4,72.2,73.9|4.0,28.3,32.0,34.9,45.9,51.0,54.9,58.8,64.0,68.1,70.3,72.1,73.8|0.0,0.0,0.0,0.0,0.8
+,1.2,1.8,3.3,4.3,11.3,27.8,32.1,33.4&chm=tAndroid+1.5,7caa36,0,0,15,,t::-5|b,c3df9b,0,1,0|tAndroid+1
+.6,638d23,1,0,15,,t::-5|b,b0db6e,1,2,0|tAndroid+2.0.1,496c13,2,0,15,,t::-5|b,9ddb3d,2,3,0|tAndroid+2
+.1,2f4708,3,1,15,,t:-30:-40|b,89cf19,3,4,0|tAndroid+2.2,131d02,4,9,15,,t::-5|B,6fad0c,4,5,0&chg=7,25
+&chdl=Android+1.5|Android+1.6|Android+2.0.1|Android+2.1|Android+2.2&chco=add274,9ad145,84c323,6ba213
+,507d08" />
-<p><em>Last historical dataset collected during two weeks ending on September 1, 2010</em></p>
+<p><em>Last historical dataset collected during two weeks ending on October 1, 2010</em></p>
</div><!-- end dashboard-panel -->
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 21baf32..ee40b85 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -73,7 +73,8 @@
* policy decisions such as waking from device sleep.
*/
enum {
- /* These flags originate in RawEvents and are generally set in the key map. */
+ /* These flags originate in RawEvents and are generally set in the key map.
+ * See also labels for policy flags in KeycodeLabels.h. */
POLICY_FLAG_WAKE = 0x00000001,
POLICY_FLAG_WAKE_DROPPED = 0x00000002,
@@ -83,6 +84,7 @@
POLICY_FLAG_ALT_GR = 0x00000020,
POLICY_FLAG_MENU = 0x00000040,
POLICY_FLAG_LAUNCHER = 0x00000080,
+ POLICY_FLAG_VIRTUAL = 0x00000100,
POLICY_FLAG_RAW_MASK = 0x0000ffff,
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
index d3fbaf7..2209cb8 100644
--- a/include/ui/InputReader.h
+++ b/include/ui/InputReader.h
@@ -103,10 +103,6 @@
virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation) = 0;
- /* Provides feedback for a virtual key down.
- */
- virtual void virtualKeyDownFeedback() = 0;
-
/* Intercepts a key event.
* The policy can use this method as an opportunity to perform power management functions
* and early event preprocessing such as updating policy flags.
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index c8d6ffc..f71d9cd 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -142,6 +142,7 @@
{ NULL, 0 }
};
+// See also policy flags in Input.h.
static const KeycodeLabel FLAGS[] = {
{ "WAKE", 0x00000001 },
{ "WAKE_DROPPED", 0x00000002 },
@@ -151,6 +152,7 @@
{ "ALT_GR", 0x00000020 },
{ "MENU", 0x00000040 },
{ "LAUNCHER", 0x00000080 },
+ { "VIRTUAL", 0x00000100 },
{ NULL, 0 }
};
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
index 1d35e10..825febc 100644
--- a/libs/ui/InputReader.cpp
+++ b/libs/ui/InputReader.cpp
@@ -993,7 +993,10 @@
int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP;
int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM;
if (policyFlags & POLICY_FLAG_WOKE_HERE) {
- keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE;
+ keyEventFlags |= AKEY_EVENT_FLAG_WOKE_HERE;
+ }
+ if (policyFlags & POLICY_FLAG_VIRTUAL) {
+ keyEventFlags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
}
getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
@@ -2162,10 +2165,7 @@
int32_t keyCode, int32_t scanCode, nsecs_t downTime) {
int32_t metaState = mContext->getGlobalMetaState();
- if (keyEventAction == AKEY_EVENT_ACTION_DOWN) {
- getPolicy()->virtualKeyDownFeedback();
- }
-
+ policyFlags |= POLICY_FLAG_VIRTUAL;
int32_t policyActions = getPolicy()->interceptKey(when, getDeviceId(),
keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
diff --git a/packages/SystemUI/res/drawable-hdpi/divider_horizontal_light_opaque.9.png b/packages/SystemUI/res/drawable-hdpi/divider_horizontal_light_opaque.9.png
new file mode 100644
index 0000000..f70f079
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/divider_horizontal_light_opaque.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/divider_horizontal_light_opaque.9.png b/packages/SystemUI/res/drawable-mdpi/divider_horizontal_light_opaque.9.png
new file mode 100644
index 0000000..f70f079
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/divider_horizontal_light_opaque.9.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 12d1d5c..c3f4205 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -57,7 +57,7 @@
style="?android:attr/buttonStyle"
android:paddingLeft="15dp"
android:paddingRight="15dp"
- android:background="@drawable/btn_default_small"
+ android:background="@android:drawable/btn_default_small"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_latest_event.xml b/packages/SystemUI/res/layout/status_bar_latest_event.xml
index 65c731b..b8a1cbe 100644
--- a/packages/SystemUI/res/layout/status_bar_latest_event.xml
+++ b/packages/SystemUI/res/layout/status_bar_latest_event.xml
@@ -17,7 +17,7 @@
<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@drawable/divider_horizontal_dark_opaque"
+ android:background="@drawable/divider_horizontal_light_opaque"
/>
</LinearLayout>
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 84998c3..8e5cdc2 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1968,7 +1968,8 @@
}
rc = StorageResultCode.OperationSucceeded;
- String cmd = String.format("obb mount %s %s %d", mObbState.filename, mKey,
+ String cmd = String.format("obb mount %s %s %d", mObbState.filename,
+ mKey != null ? mKey : "none",
mObbState.callerUid);
try {
mConnector.doCommand(cmd);
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 6f52f24..6b3df38 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -182,7 +182,6 @@
virtual bool getDisplayInfo(int32_t displayId,
int32_t* width, int32_t* height, int32_t* orientation);
- virtual void virtualKeyDownFeedback();
virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags);
virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
@@ -464,17 +463,6 @@
return android_server_PowerManagerService_isScreenBright();
}
-void NativeInputManager::virtualKeyDownFeedback() {
-#if DEBUG_INPUT_READER_POLICY
- LOGD("virtualKeyDownFeedback");
-#endif
-
- JNIEnv* env = jniEnv();
-
- env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
- checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
-}
-
int32_t NativeInputManager::interceptKey(nsecs_t when,
int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
#if DEBUG_INPUT_READER_POLICY
@@ -483,6 +471,12 @@
when, deviceId, down, keyCode, scanCode, policyFlags);
#endif
+ if (down && (policyFlags & POLICY_FLAG_VIRTUAL)) {
+ JNIEnv* env = jniEnv();
+ env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
+ checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
+ }
+
const int32_t WM_ACTION_PASS_TO_USER = 1;
const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
const int32_t WM_ACTION_GO_TO_SLEEP = 4;
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 7c3508f..09b7d05 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -861,6 +861,25 @@
}
/**
+ * Enables or disables echo suppression.
+ */
+ public void setEchoSuppressionEnabled(boolean enabled) {
+ if (VDBG) {
+ Log.d(LOG_TAG, " setEchoSuppression(" + enabled + ")");
+ Log.d(LOG_TAG, this.toString());
+ }
+
+ if (hasActiveFgCall()) {
+ getActiveFgCall().getPhone().setEchoSuppressionEnabled(enabled);
+ }
+
+ if (VDBG) {
+ Log.d(LOG_TAG, "End setEchoSuppression(" + enabled + ")");
+ Log.d(LOG_TAG, this.toString());
+ }
+ }
+
+ /**
* Play a DTMF tone on the active call.
*
* @param c should be one of 0-9, '*' or '#'. Other values will be
diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java
index 9afade3..d5791eb 100644
--- a/telephony/java/com/android/internal/telephony/Phone.java
+++ b/telephony/java/com/android/internal/telephony/Phone.java
@@ -1169,6 +1169,11 @@
boolean getMute();
/**
+ * Enables or disables echo suppression.
+ */
+ void setEchoSuppressionEnabled(boolean enabled);
+
+ /**
* Invokes RIL_REQUEST_OEM_HOOK_RAW on RIL implementation.
*
* @param data The data for the request.
diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java
index ff28773..53503a53 100644
--- a/telephony/java/com/android/internal/telephony/PhoneBase.java
+++ b/telephony/java/com/android/internal/telephony/PhoneBase.java
@@ -505,6 +505,10 @@
mCM.unregisterForResendIncallMute(h);
}
+ public void setEchoSuppressionEnabled(boolean enabled) {
+ // no need for regular phone
+ }
+
/**
* Subclasses of Phone probably want to replace this with a
* version scoped to their packages
diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java
index e1511e6..6f08868 100644
--- a/telephony/java/com/android/internal/telephony/PhoneProxy.java
+++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java
@@ -568,6 +568,10 @@
return mActivePhone.getMute();
}
+ public void setEchoSuppressionEnabled(boolean enabled) {
+ mActivePhone.setEchoSuppressionEnabled(enabled);
+ }
+
public void invokeOemRilRequestRaw(byte[] data, Message response) {
mActivePhone.invokeOemRilRequestRaw(data, response);
}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index af3e0886..e3c3d65 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -327,6 +327,20 @@
Log.e(LOG_TAG, "call waiting not supported");
}
+ @Override
+ public void setEchoSuppressionEnabled(boolean enabled) {
+ synchronized (SipPhone.class) {
+ AudioGroup audioGroup = foregroundCall.getAudioGroup();
+ if (audioGroup == null) return;
+ int mode = audioGroup.getMode();
+ audioGroup.setMode(enabled
+ ? AudioGroup.MODE_ECHO_SUPPRESSION
+ : AudioGroup.MODE_NORMAL);
+ Log.d(LOG_TAG, String.format("audioGroup mode change: %d --> %d",
+ mode, audioGroup.getMode()));
+ }
+ }
+
public void setMute(boolean muted) {
synchronized (SipPhone.class) {
foregroundCall.setMute(muted);
diff --git a/tools/obbtool/mkobb.sh b/tools/obbtool/mkobb.sh
index 1987696..ba5256f 100755
--- a/tools/obbtool/mkobb.sh
+++ b/tools/obbtool/mkobb.sh
@@ -161,11 +161,10 @@
while true; do \
case "$1" in
- -c) use_crypto=1; shift;;
-d) directory=$2; shift 2;;
-h) usage; exit 1;;
- -k) key=$2; shift 2;;
- -K) prompt_key=1; shift;;
+ -k) key=$2; use_crypto=1; shift 2;;
+ -K) prompt_key=1; use_crypto=1; shift;;
-v) verbose=1; shift;;
-o) filename=$2; shift 2;;
--) shift; break;;