Merge "Fix 3391330: Use BATTERY_STATUS_FULL as "Charged" state [DO NOT MERGE]" into gingerbread
diff --git a/Android.mk b/Android.mk
index e299250..b817cc6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -373,6 +373,7 @@
-since ./frameworks/base/api/7.xml 7 \
-since ./frameworks/base/api/8.xml 8 \
-since ./frameworks/base/api/9.xml 9 \
+ -since ./frameworks/base/api/10.xml 10 \
-werror -hide 13 \
-overview $(LOCAL_PATH)/core/java/overview.html
@@ -446,7 +447,7 @@
# release version (ie "Release x") (full releases only)
framework_docs_SDK_REL_ID:=1
# flag to build offline docs for a preview release
-framework_docs_SDK_PREVIEW:=0
+framework_docs_SDK_PREVIEW:=true
framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-hdf sdk.version $(framework_docs_SDK_VERSION) \
@@ -574,6 +575,10 @@
-hdf android.whichdoc online \
-hdf template.showLanguageMenu true
+ifeq ($(framework_docs_SDK_PREVIEW),true)
+ LOCAL_DROIDDOC_OPTIONS += -hdf sdk.preview true
+endif
+
LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
LOCAL_DROIDDOC_CUSTOM_ASSET_DIR:=assets-sdk
diff --git a/api/current.xml b/api/current.xml
index 71ebbb5..ad54650 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -100829,7 +100829,9 @@
</parameter>
<parameter name="intent" type="android.app.PendingIntent">
</parameter>
-<parameter name="filters" type="android.content.IntentFilter...">
+<parameter name="filters" type="android.content.IntentFilter[]">
+</parameter>
+<parameter name="techLists" type="java.lang.String[][]">
</parameter>
</method>
<method name="enableForegroundNdefPush"
@@ -101018,8 +101020,8 @@
visibility="public"
>
</method>
-<method name="getTechnologyList"
- return="int[]"
+<method name="getTechList"
+ return="java.lang.String[]"
abstract="false"
native="false"
synchronized="false"
@@ -101105,6 +101107,8 @@
deprecated="not deprecated"
visibility="public"
>
+<exception name="IOException" type="java.io.IOException">
+</exception>
</method>
<method name="connect"
return="void"
@@ -101130,17 +101134,6 @@
visibility="public"
>
</method>
-<method name="getTechnologyId"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="isConnected"
return="boolean"
abstract="false"
@@ -101246,7 +101239,7 @@
deprecated="not deprecated"
visibility="public"
>
-<method name="authenticateBlock"
+<method name="authenticateSectorWithKeyA"
return="boolean"
abstract="false"
native="false"
@@ -101256,16 +101249,14 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="block" type="int">
+<parameter name="sectorIndex" type="int">
</parameter>
<parameter name="key" type="byte[]">
</parameter>
-<parameter name="keyA" type="boolean">
-</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
-<method name="authenticateSector"
+<method name="authenticateSectorWithKeyB"
return="boolean"
abstract="false"
native="false"
@@ -101275,15 +101266,26 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="sector" type="int">
+<parameter name="sectorIndex" type="int">
</parameter>
<parameter name="key" type="byte[]">
</parameter>
-<parameter name="keyA" type="boolean">
-</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
+<method name="blockToSector"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="blockIndex" type="int">
+</parameter>
+</method>
<method name="decrement"
return="void"
abstract="false"
@@ -101294,7 +101296,9 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="block" type="int">
+<parameter name="blockIndex" type="int">
+</parameter>
+<parameter name="value" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -101322,7 +101326,18 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="sector" type="int">
+</method>
+<method name="getBlockCountInSector"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sectorIndex" type="int">
</parameter>
</method>
<method name="getSectorCount"
@@ -101336,19 +101351,6 @@
visibility="public"
>
</method>
-<method name="getSectorSize"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="sector" type="int">
-</parameter>
-</method>
<method name="getSize"
return="int"
abstract="false"
@@ -101360,17 +101362,6 @@
visibility="public"
>
</method>
-<method name="getTotalBlockCount"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getType"
return="int"
abstract="false"
@@ -101392,35 +101383,9 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="block" type="int">
+<parameter name="blockIndex" type="int">
</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
-<method name="isEmulated"
- return="boolean"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
-<method name="readBlock"
- return="byte[]"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="sector" type="int">
-</parameter>
-<parameter name="block" type="int">
+<parameter name="value" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -101435,7 +101400,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="block" type="int">
+<parameter name="blockIndex" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -101450,11 +101415,24 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="block" type="int">
+<parameter name="blockIndex" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
+<method name="sectorToBlock"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sectorIndex" type="int">
+</parameter>
+</method>
<method name="transceive"
return="byte[]"
abstract="false"
@@ -101480,7 +101458,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="block" type="int">
+<parameter name="blockIndex" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -101495,32 +101473,24 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="block" type="int">
+<parameter name="blockIndex" type="int">
</parameter>
<parameter name="data" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
-<method name="writeBlock"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
+<field name="BLOCK_SIZE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
deprecated="not deprecated"
visibility="public"
>
-<parameter name="sector" type="int">
-</parameter>
-<parameter name="block" type="int">
-</parameter>
-<parameter name="data" type="byte[]">
-</parameter>
-<exception name="IOException" type="java.io.IOException">
-</exception>
-</method>
+</field>
<field name="KEY_DEFAULT"
type="byte[]"
transient="false"
@@ -101598,17 +101568,6 @@
visibility="public"
>
</field>
-<field name="SIZE_UNKNOWN"
- type="int"
- transient="false"
- volatile="false"
- value="0"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="TYPE_CLASSIC"
type="int"
transient="false"
@@ -101646,7 +101605,7 @@
type="int"
transient="false"
volatile="false"
- value="5"
+ value="-1"
static="true"
final="true"
deprecated="not deprecated"
@@ -101686,7 +101645,7 @@
visibility="public"
>
</method>
-<method name="readBlock"
+<method name="readPages"
return="byte[]"
abstract="false"
native="false"
@@ -101696,7 +101655,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="page" type="int">
+<parameter name="pageOffset" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -101726,13 +101685,24 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="page" type="int">
+<parameter name="pageOffset" type="int">
</parameter>
<parameter name="data" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
</method>
+<field name="PAGE_SIZE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="TYPE_ULTRALIGHT"
type="int"
transient="false"
@@ -101759,7 +101729,7 @@
type="int"
transient="false"
volatile="false"
- value="10"
+ value="-1"
static="true"
final="true"
deprecated="not deprecated"
@@ -102237,6 +102207,8 @@
deprecated="not deprecated"
visibility="public"
>
+<implements name="java.io.Closeable">
+</implements>
<method name="close"
return="void"
abstract="true"
@@ -102247,6 +102219,8 @@
deprecated="not deprecated"
visibility="public"
>
+<exception name="IOException" type="java.io.IOException">
+</exception>
</method>
<method name="connect"
return="void"
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index ffbd69d..b5596013 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -149,6 +149,11 @@
ConnectivityManager mConnectivityManager;
public void onReceive(Context context, Intent intent) {
synchronized(this) {
+ // update state and roaming before we set the state - only state changes are
+ // noticed
+ TelephonyManager tm = TelephonyManager.getDefault();
+ setRoamingStatus(tm.isNetworkRoaming());
+ setSubtype(tm.getNetworkType(), tm.getNetworkTypeName());
if (intent.getAction().equals(TelephonyIntents.
ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
Phone.DataState state = getMobileDataState(intent);
@@ -254,9 +259,6 @@
reason == null ? "" : "(" + reason + ")");
setDetailedState(DetailedState.FAILED, reason, apnName);
}
- TelephonyManager tm = TelephonyManager.getDefault();
- setRoamingStatus(tm.isNetworkRoaming());
- setSubtype(tm.getNetworkType(), tm.getNetworkTypeName());
}
}
}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index d340a99..039dfff 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -302,7 +302,7 @@
public boolean isTeardownRequested() {
return mTeardownRequested;
}
-
+
/**
* Send a notification that the results of a scan for network access
* points has completed, and results are available.
@@ -327,10 +327,10 @@
}
protected void setSubtype(int subtype, String subtypeName) {
- if (mNetworkInfo.isConnected()) {
- int oldSubtype = mNetworkInfo.getSubtype();
- if (subtype != oldSubtype) {
- mNetworkInfo.setSubtype(subtype, subtypeName);
+ int oldSubtype = mNetworkInfo.getSubtype();
+ if (subtype != oldSubtype) {
+ mNetworkInfo.setSubtype(subtype, subtypeName);
+ if (mNetworkInfo.isConnected()) {
Message msg = mTarget.obtainMessage(
EVENT_NETWORK_SUBTYPE_CHANGED, oldSubtype, 0, mNetworkInfo);
msg.sendToTarget();
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index cfeff52..d439a48 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -21,6 +21,7 @@
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.Tag;
+import android.nfc.TechListParcel;
import android.nfc.ILlcpSocket;
import android.nfc.ILlcpServiceSocket;
import android.nfc.ILlcpConnectionlessSocket;
@@ -48,7 +49,7 @@
void localSet(in NdefMessage message);
void openTagConnection(in Tag tag);
void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
- in IntentFilter[] filters);
+ in IntentFilter[] filters, in TechListParcel techLists);
void disableForegroundDispatch(in ComponentName activity);
void enableForegroundNdefPush(in ComponentName activity, in NdefMessage msg);
void disableForegroundNdefPush(in ComponentName activity);
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index b1623a5..4808032 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -26,8 +26,8 @@
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.nfc.tech.TagTechnology;
import android.os.IBinder;
+import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
@@ -55,7 +55,7 @@
/**
* Intent to started when a tag is discovered. The data URI is formated as
* {@code vnd.android.nfc://tag/} with the path having a directory entry for each technology
- * in the {@link Tag#getTechnologyList()} is ascending order.
+ * in the {@link Tag#getTechList()} is sorted ascending order.
*
* This intent is started after {@link #ACTION_NDEF_DISCOVERED} and before
* {@link #ACTION_TAG_DISCOVERED}
@@ -416,18 +416,19 @@
/**
* Enables foreground dispatching to the given Activity. This will force all NFC Intents that
* match the given filters to be delivered to the activity bypassing the standard dispatch
- * mechanism.
+ * mechanism. If no IntentFilters are given all the PendingIntent will be invoked for every
+ * dispatch Intent.
*
* This method must be called from the main thread.
*
* @param activity the Activity to dispatch to
* @param intent the PendingIntent to start for the dispatch
- * @param filters the IntentFilters to override dispatching for
+ * @param filters the IntentFilters to override dispatching for, or null to always dispatch
* @throws IllegalStateException
*/
public void enableForegroundDispatch(Activity activity, PendingIntent intent,
- IntentFilter... filters) {
- if (activity == null || intent == null || filters == null) {
+ IntentFilter[] filters, String[][] techLists) {
+ if (activity == null || intent == null) {
throw new NullPointerException();
}
if (!activity.isResumed()) {
@@ -435,9 +436,14 @@
"when your activity is resumed");
}
try {
+ TechListParcel parcel = null;
+ if (techLists != null && techLists.length > 0) {
+ parcel = new TechListParcel(techLists);
+ }
ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
mForegroundDispatchListener);
- sService.enableForegroundDispatch(activity.getComponentName(), intent, filters);
+ sService.enableForegroundDispatch(activity.getComponentName(), intent, filters,
+ parcel);
} catch (RemoteException e) {
attemptDeadServiceRecovery(e);
}
@@ -478,7 +484,13 @@
}
/**
- * Enable NDEF messages push while this Activity is in the foreground.
+ * Enable NDEF message push over P2P while this Activity is in the foreground. For this to
+ * function properly the other NFC device being scanned must support the "com.android.npp"
+ * NDEF push protocol.
+ *
+ * <p><em>NOTE</em> While foreground NDEF push is active standard tag dispatch is disabled.
+ * Only the foreground activity may receive tag discovered dispatches via
+ * {@link #enableForegroundDispatch}.
*/
public void enableForegroundNdefPush(Activity activity, NdefMessage msg) {
if (activity == null || msg == null) {
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 55a95562..aae75c9 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -16,6 +16,15 @@
package android.nfc;
+import android.nfc.tech.IsoDep;
+import android.nfc.tech.MifareClassic;
+import android.nfc.tech.MifareUltralight;
+import android.nfc.tech.Ndef;
+import android.nfc.tech.NdefFormatable;
+import android.nfc.tech.NfcA;
+import android.nfc.tech.NfcB;
+import android.nfc.tech.NfcF;
+import android.nfc.tech.NfcV;
import android.nfc.tech.TagTechnology;
import android.os.Bundle;
import android.os.Parcel;
@@ -49,6 +58,7 @@
public class Tag implements Parcelable {
/*package*/ final byte[] mId;
/*package*/ final int[] mTechList;
+ /*package*/ final String[] mTechStringList;
/*package*/ final Bundle[] mTechExtras;
/*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
/*package*/ final INfcTag mTagService;
@@ -66,6 +76,7 @@
}
mId = id;
mTechList = Arrays.copyOf(techList, techList.length);
+ mTechStringList = generateTechStringList(techList);
// Ensure mTechExtras is as long as mTechList
mTechExtras = Arrays.copyOf(techListExtras, techList.length);
mServiceHandle = serviceHandle;
@@ -88,6 +99,45 @@
return new Tag(id, techList, techListExtras, 0, null);
}
+ private String[] generateTechStringList(int[] techList) {
+ final int size = techList.length;
+ String[] strings = new String[size];
+ for (int i = 0; i < size; i++) {
+ switch (techList[i]) {
+ case TagTechnology.ISO_DEP:
+ strings[i] = IsoDep.class.getName();
+ break;
+ case TagTechnology.MIFARE_CLASSIC:
+ strings[i] = MifareClassic.class.getName();
+ break;
+ case TagTechnology.MIFARE_ULTRALIGHT:
+ strings[i] = MifareUltralight.class.getName();
+ break;
+ case TagTechnology.NDEF:
+ strings[i] = Ndef.class.getName();
+ break;
+ case TagTechnology.NDEF_FORMATABLE:
+ strings[i] = NdefFormatable.class.getName();
+ break;
+ case TagTechnology.NFC_A:
+ strings[i] = NfcA.class.getName();
+ break;
+ case TagTechnology.NFC_B:
+ strings[i] = NfcB.class.getName();
+ break;
+ case TagTechnology.NFC_F:
+ strings[i] = NfcF.class.getName();
+ break;
+ case TagTechnology.NFC_V:
+ strings[i] = NfcV.class.getName();
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown tech type " + techList[i]);
+ }
+ }
+ return strings;
+ }
+
/**
* For use by NfcService only.
* @hide
@@ -110,13 +160,12 @@
* Returns technologies present in the tag that this implementation understands,
* or a zero length array if there are no supported technologies on this tag.
*
- * The elements of the list are guaranteed be one of the constants defined in
- * {@link TagTechnology}.
+ * The elements of the list are the names of the classes implementing the technology.
*
* The ordering of the returned array is undefined and should not be relied upon.
*/
- public int[] getTechnologyList() {
- return Arrays.copyOf(mTechList, mTechList.length);
+ public String[] getTechList() {
+ return mTechStringList;
}
/** @hide */
@@ -187,25 +236,39 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
+ // Null mTagService means this is a mock tag
+ int isMock = (mTagService == null)?1:0;
+
writeBytesWithNull(dest, mId);
dest.writeInt(mTechList.length);
dest.writeIntArray(mTechList);
dest.writeTypedArray(mTechExtras, 0);
dest.writeInt(mServiceHandle);
- dest.writeStrongBinder(mTagService.asBinder());
+ dest.writeInt(isMock);
+ if (isMock == 0) {
+ dest.writeStrongBinder(mTagService.asBinder());
+ }
}
public static final Parcelable.Creator<Tag> CREATOR =
new Parcelable.Creator<Tag>() {
@Override
public Tag createFromParcel(Parcel in) {
+ INfcTag tagService;
+
// Tag fields
byte[] id = Tag.readBytesWithNull(in);
int[] techList = new int[in.readInt()];
in.readIntArray(techList);
Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
int serviceHandle = in.readInt();
- INfcTag tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
+ int isMock = in.readInt();
+ if (isMock == 0) {
+ tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
+ }
+ else {
+ tagService = null;
+ }
return new Tag(id, techList, techExtras, serviceHandle, tagService);
}
diff --git a/core/java/android/nfc/TechListParcel.aidl b/core/java/android/nfc/TechListParcel.aidl
new file mode 100644
index 0000000..92e646f
--- /dev/null
+++ b/core/java/android/nfc/TechListParcel.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+parcelable TechListParcel;
\ No newline at end of file
diff --git a/core/java/android/nfc/TechListParcel.java b/core/java/android/nfc/TechListParcel.java
new file mode 100644
index 0000000..396f0f1
--- /dev/null
+++ b/core/java/android/nfc/TechListParcel.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.nfc;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/** @hide */
+public class TechListParcel implements Parcelable {
+
+ private String[][] mTechLists;
+
+ public TechListParcel(String[]... strings) {
+ mTechLists = strings;
+ }
+
+ public String[][] getTechLists() {
+ return mTechLists;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ int count = mTechLists.length;
+ dest.writeInt(count);
+ for (int i = 0; i < count; i++) {
+ String[] techList = mTechLists[i];
+ dest.writeStringArray(techList);
+ }
+ }
+
+ public static final Creator<TechListParcel> CREATOR = new Creator<TechListParcel>() {
+ @Override
+ public TechListParcel createFromParcel(Parcel source) {
+ int count = source.readInt();
+ String[][] techLists = new String[count][];
+ for (int i = 0; i < count; i++) {
+ techLists[i] = source.readStringArray();
+ }
+ return new TechListParcel(techLists);
+ }
+
+ @Override
+ public TechListParcel[] newArray(int size) {
+ return new TechListParcel[size];
+ }
+ };
+}
diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/core/java/android/nfc/tech/BasicTagTechnology.java
index a909631..32a850d 100644
--- a/core/java/android/nfc/tech/BasicTagTechnology.java
+++ b/core/java/android/nfc/tech/BasicTagTechnology.java
@@ -36,28 +36,10 @@
/*package*/ int mSelectedTechnology;
BasicTagTechnology(Tag tag, int tech) throws RemoteException {
- int[] techList = tag.getTechnologyList();
- int i;
-
- // Check target validity
- for (i = 0; i < techList.length; i++) {
- if (tech == techList[i]) {
- break;
- }
- }
- if (i >= techList.length) {
- // Technology not found
- throw new IllegalArgumentException("Technology " + tech + " not present on tag " + tag);
- }
-
mTag = tag;
mSelectedTechnology = tech;
}
- BasicTagTechnology(Tag tag) throws RemoteException {
- this(tag, tag.getTechnologyList()[0]);
- }
-
@Override
public Tag getTag() {
return mTag;
@@ -65,17 +47,12 @@
/** Internal helper to throw IllegalStateException if the technology isn't connected */
void checkConnected() {
- if ((mTag.getConnectedTechnology() != getTechnologyId()) ||
+ if ((mTag.getConnectedTechnology() != mSelectedTechnology) ||
(mTag.getConnectedTechnology() == -1)) {
throw new IllegalStateException("Call connect() first!");
}
}
- @Override
- public int getTechnologyId() {
- return mSelectedTechnology;
- }
-
/**
* Helper to indicate if {@link #connect} has succeeded.
* <p>
@@ -101,11 +78,12 @@
@Override
public void connect() throws IOException {
try {
- int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(), getTechnologyId());
+ int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(),
+ mSelectedTechnology);
if (errorCode == ErrorCodes.SUCCESS) {
// Store this in the tag object
- mTag.setConnectedTechnology(getTechnologyId());
+ mTag.setConnectedTechnology(mSelectedTechnology);
mIsConnected = true;
} else {
throw new IOException();
@@ -139,7 +117,7 @@
}
@Override
- public void close() {
+ public void close() throws IOException {
try {
/* Note that we don't want to physically disconnect the tag,
* but just reconnect to it to reset its state
@@ -158,7 +136,8 @@
checkConnected();
try {
- TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(), data, raw);
+ TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(),
+ data, raw);
if (result == null) {
throw new IOException("transceive failed");
} else {
diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java
index f6d141a..774982e 100644
--- a/core/java/android/nfc/tech/IsoDep.java
+++ b/core/java/android/nfc/tech/IsoDep.java
@@ -92,7 +92,7 @@
}
@Override
- public void close() {
+ public void close() throws IOException {
try {
mTag.getTagService().resetIsoDepTimeout();
} catch (RemoteException e) {
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 1c52322..d337ead 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -21,6 +21,8 @@
import android.os.RemoteException;
import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
/**
* Technology class representing MIFARE Classic tags (also known as MIFARE Standard).
@@ -32,8 +34,8 @@
* 16 bytes, but the number of sectors and the sector size varies by product. MIFARE has encryption
* built in and each sector has two keys associated with it, as well as ACLs to determine what
* level acess each key grants. Before operating on a sector you must call either
- * {@link #authenticateSector(int, byte[], boolean)} or
- * {@link #authenticateBlock(int, byte[], boolean)} to gain authorize your request.
+ * {@link #authenticateSectorWithKeyA(int, byte[])} or
+ * {@link #authenticateSectorWithKeyB(int, byte[])} to gain authorization for your request.
*/
public final class MifareClassic extends BasicTagTechnology {
/**
@@ -53,14 +55,14 @@
public static final byte[] KEY_NFC_FORUM =
{(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
+ /** A Mifare Classic compatible card of unknown type */
+ public static final int TYPE_UNKNOWN = -1;
/** A MIFARE Classic tag */
public static final int TYPE_CLASSIC = 0;
/** A MIFARE Plus tag */
public static final int TYPE_PLUS = 1;
/** A MIFARE Pro tag */
public static final int TYPE_PRO = 2;
- /** The tag type is unknown */
- public static final int TYPE_UNKNOWN = 5;
/** The tag contains 16 sectors, each holding 4 blocks. */
public static final int SIZE_1K = 1024;
@@ -73,8 +75,12 @@
public static final int SIZE_4K = 4096;
/** The tag contains 5 sectors, each holding 4 blocks. */
public static final int SIZE_MINI = 320;
- /** The capacity is unknown */
- public static final int SIZE_UNKNOWN = 0;
+
+ /** Size of a Mifare Classic block (in bytes) */
+ public static final int BLOCK_SIZE = 16;
+
+ private static final int MAX_BLOCK_COUNT = 256;
+ private static final int MAX_SECTOR_COUNT = 40;
private boolean mIsEmulated;
private int mType;
@@ -99,102 +105,76 @@
public MifareClassic(Tag tag) throws RemoteException {
super(tag, TagTechnology.MIFARE_CLASSIC);
- // Check if this could actually be a MIFARE Classic
- NfcA a = NfcA.get(tag);
+ NfcA a = NfcA.get(tag); // Mifare Classic is always based on NFC a
mIsEmulated = false;
- mType = TYPE_UNKNOWN;
- mSize = SIZE_UNKNOWN;
switch (a.getSak()) {
- case 0x08:
- // Type == classic
- // Size = 1K
- mType = TYPE_CLASSIC;
- mSize = SIZE_1K;
- break;
- case 0x09:
- // Type == classic mini
- // Size == ?
- mType = TYPE_CLASSIC;
- mSize = SIZE_MINI;
- break;
- case 0x10:
- // Type == MF+
- // Size == 2K
- // SecLevel = SL2
- mType = TYPE_PLUS;
- mSize = SIZE_2K;
- break;
- case 0x11:
- // Type == MF+
- // Size == 4K
- // Seclevel = SL2
- mType = TYPE_PLUS;
- mSize = SIZE_4K;
- break;
- case 0x18:
- // Type == classic
- // Size == 4k
- mType = TYPE_CLASSIC;
- mSize = SIZE_4K;
- break;
- case 0x20:
- // TODO this really should be a short, not byte
- if (a.getAtqa()[0] == 0x03) {
- // Type == DESFIRE
- break;
- } else {
- // Type == MF+
- // SL = SL3
- mType = TYPE_PLUS;
- mSize = SIZE_UNKNOWN;
- }
- break;
- case 0x28:
- // Type == MF Classic
- // Size == 1K
- // Emulated == true
- mType = TYPE_CLASSIC;
- mSize = SIZE_1K;
- mIsEmulated = true;
- break;
- case 0x38:
- // Type == MF Classic
- // Size == 4K
- // Emulated == true
- mType = TYPE_CLASSIC;
- mSize = SIZE_4K;
- mIsEmulated = true;
- break;
- case 0x88:
- // Type == MF Classic
- // Size == 1K
- // NXP-tag: false
- mType = TYPE_CLASSIC;
- mSize = SIZE_1K;
- break;
- case 0x98:
- case 0xB8:
- // Type == MF Pro
- // Size == 4K
- mType = TYPE_PRO;
- mSize = SIZE_4K;
- break;
+ case 0x08:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_1K;
+ break;
+ case 0x09:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_MINI;
+ break;
+ case 0x10:
+ mType = TYPE_PLUS;
+ mSize = SIZE_2K;
+ // SecLevel = SL2
+ break;
+ case 0x11:
+ mType = TYPE_PLUS;
+ mSize = SIZE_4K;
+ // Seclevel = SL2
+ break;
+ case 0x18:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_4K;
+ break;
+ case 0x28:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_1K;
+ mIsEmulated = true;
+ break;
+ case 0x38:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_4K;
+ mIsEmulated = true;
+ break;
+ case 0x88:
+ mType = TYPE_CLASSIC;
+ mSize = SIZE_1K;
+ // NXP-tag: false
+ break;
+ case 0x98:
+ case 0xB8:
+ mType = TYPE_PRO;
+ mSize = SIZE_4K;
+ break;
+ default:
+ // Stack incorrectly reported a MifareClassic. We cannot handle this
+ // gracefully - we have no idea of the memory layout. Bail.
+ throw new RuntimeException(
+ "Tag incorrectly enumerated as Mifare Classic, SAK = " + a.getSak());
}
}
- /** Returns the size of the tag, determined at discovery time */
- public int getSize() {
- return mSize;
- }
-
- /** Returns the size of the tag, determined at discovery time */
+ /** Returns the type of the tag, determined at discovery time */
public int getType() {
return mType;
}
- /** Returns true if the tag is emulated, determined at discovery time */
+ /** Returns the size of the tag in bytes, determined at discovery time */
+ public int getSize() {
+ return mSize;
+ }
+
+ /** Returns true if the tag is emulated, determined at discovery time.
+ * These are actually smart-cards that emulate a Mifare Classic interface.
+ * They can be treated identically to a Mifare Classic tag.
+ * @hide
+ */
public boolean isEmulated() {
return mIsEmulated;
}
@@ -202,67 +182,78 @@
/** Returns the number of sectors on this tag, determined at discovery time */
public int getSectorCount() {
switch (mSize) {
- case SIZE_1K: {
- return 16;
- }
- case SIZE_2K: {
- return 32;
- }
- case SIZE_4K: {
- return 40;
- }
- case SIZE_MINI: {
- return 5;
- }
- default: {
- return 0;
- }
+ case SIZE_1K:
+ return 16;
+ case SIZE_2K:
+ return 32;
+ case SIZE_4K:
+ return 40;
+ case SIZE_MINI:
+ return 5;
+ default:
+ return 0;
}
}
- /** Returns the sector size, determined at discovery time */
- public int getSectorSize(int sector) {
- return getBlockCount(sector) * 16;
- }
-
/** Returns the total block count, determined at discovery time */
- public int getTotalBlockCount() {
- int totalBlocks = 0;
- for (int sec = 0; sec < getSectorCount(); sec++) {
- totalBlocks += getSectorSize(sec);
- }
-
- return totalBlocks;
+ public int getBlockCount() {
+ return mSize / BLOCK_SIZE;
}
/** Returns the block count for the given sector, determined at discovery time */
- public int getBlockCount(int sector) {
- if (sector >= getSectorCount()) {
- throw new IllegalArgumentException("this card only has " + getSectorCount() +
- " sectors");
- }
+ public int getBlockCountInSector(int sectorIndex) {
+ validateSector(sectorIndex);
- if (sector <= 32) {
+ if (sectorIndex < 32) {
return 4;
} else {
return 16;
}
}
- private byte firstBlockInSector(int sector) {
- if (sector < 32) {
- return (byte) ((sector * 4) & 0xff);
+ /** Return the sector index of a given block */
+ public int blockToSector(int blockIndex) {
+ validateBlock(blockIndex);
+
+ if (blockIndex < 32 * 4) {
+ return blockIndex / 4;
} else {
- return (byte) ((32 * 4 + ((sector - 32) * 16)) & 0xff);
+ return 32 + (blockIndex - 32 * 4) / 16;
+ }
+ }
+
+ /** Return the first block of a given sector */
+ public int sectorToBlock(int sectorIndex) {
+ if (sectorIndex < 32) {
+ return sectorIndex * 4;
+ } else {
+ return 32 * 4 + (sectorIndex - 32) * 16;
}
}
// Methods that require connect()
/**
- * Authenticate the entire sector that the given block resides in.
+ * Authenticate a sector.
+ * <p>Every sector has an A and B key with different access privileges,
+ * this method attempts to authenticate against the A key.
* <p>This requires a that the tag be connected.
*/
- public boolean authenticateBlock(int block, byte[] key, boolean keyA) throws IOException {
+ public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException {
+ return authenticate(sectorIndex, key, true);
+ }
+
+ /**
+ * Authenticate a sector.
+ * <p>Every sector has an A and B key with different access privileges,
+ * this method attempts to authenticate against the B key.
+ * <p>This requires a that the tag be connected.
+ */
+ public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException {
+ return authenticate(sectorIndex, key, false);
+ }
+
+ private boolean authenticate(int sector, byte[] key, boolean keyA) throws IOException {
+ validateSector(sector);
checkConnected();
byte[] cmd = new byte[12];
@@ -275,7 +266,9 @@
}
// Second byte is block address
- cmd[1] = (byte) block;
+ // Authenticate command takes a block address. Authenticating a block
+ // of a sector will authenticate the entire sector.
+ cmd[1] = (byte) sectorToBlock(sector);
// Next 4 bytes are last 4 bytes of UID
byte[] uid = getTag().getId();
@@ -285,7 +278,7 @@
System.arraycopy(key, 0, cmd, 6, 6);
try {
- if ((transceive(cmd, false) != null)) {
+ if (transceive(cmd, false) != null) {
return true;
}
} catch (TagLostException e) {
@@ -297,106 +290,102 @@
}
/**
- * Authenticate for a given sector.
- * <p>This requires a that the tag be connected.
- */
- public boolean authenticateSector(int sector, byte[] key, boolean keyA) throws IOException {
- checkConnected();
-
- byte addr = (byte) ((firstBlockInSector(sector)) & 0xff);
-
- // Note that authenticating a block of a sector, will authenticate
- // the entire sector.
- return authenticateBlock(addr, key, keyA);
- }
-
- /**
- * Sector indexing starts at 0.
- * Block indexing starts at 0, and resets in each sector.
+ * Read 16-byte block.
* <p>This requires a that the tag be connected.
* @throws IOException
*/
- public byte[] readBlock(int sector, int block) throws IOException {
+ public byte[] readBlock(int blockIndex) throws IOException {
+ validateBlock(blockIndex);
checkConnected();
- byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
- return readBlock(addr);
+ byte[] cmd = { 0x30, (byte) blockIndex };
+ return transceive(cmd, false);
}
/**
- * Reads absolute block index.
+ * Write 16-byte block.
* <p>This requires a that the tag be connected.
* @throws IOException
*/
- public byte[] readBlock(int block) throws IOException {
+ public void writeBlock(int blockIndex, byte[] data) throws IOException {
+ validateBlock(blockIndex);
checkConnected();
+ if (data.length != 16) {
+ throw new IllegalArgumentException("must write 16-bytes");
+ }
- byte addr = (byte) block;
- byte[] blockread_cmd = { 0x30, addr };
+ byte[] cmd = new byte[data.length + 2];
+ cmd[0] = (byte) 0xA0; // MF write command
+ cmd[1] = (byte) blockIndex;
+ System.arraycopy(data, 0, cmd, 2, data.length);
- return transceive(blockread_cmd, false);
+ transceive(cmd, false);
}
/**
- * Writes absolute block index.
- * <p>This requires a that the tag be connected.
+ * Increment a value block, and store the result in temporary memory.
+ * @param blockIndex
* @throws IOException
*/
- public void writeBlock(int block, byte[] data) throws IOException {
+ public void increment(int blockIndex, int value) throws IOException {
+ validateBlock(blockIndex);
+ validateValueOperand(value);
checkConnected();
- byte addr = (byte) block;
- byte[] blockwrite_cmd = new byte[data.length + 2];
- blockwrite_cmd[0] = (byte) 0xA0; // MF write command
- blockwrite_cmd[1] = addr;
- System.arraycopy(data, 0, blockwrite_cmd, 2, data.length);
+ ByteBuffer cmd = ByteBuffer.allocate(6);
+ cmd.order(ByteOrder.LITTLE_ENDIAN);
+ cmd.put( (byte) 0xC1 );
+ cmd.put( (byte) blockIndex );
+ cmd.putInt(value);
- transceive(blockwrite_cmd, false);
+ transceive(cmd.array(), false);
}
/**
- * Writes relative block in sector.
- * <p>This requires a that the tag be connected.
+ * Decrement a value block, and store the result in temporary memory.
+ * @param blockIndex
* @throws IOException
*/
- public void writeBlock(int sector, int block, byte[] data) throws IOException {
+ public void decrement(int blockIndex, int value) throws IOException {
+ validateBlock(blockIndex);
+ validateValueOperand(value);
checkConnected();
- byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
+ ByteBuffer cmd = ByteBuffer.allocate(6);
+ cmd.order(ByteOrder.LITTLE_ENDIAN);
+ cmd.put( (byte) 0xC0 );
+ cmd.put( (byte) blockIndex );
+ cmd.putInt(value);
- writeBlock(addr, data);
+ transceive(cmd.array(), false);
}
- public void increment(int block) throws IOException {
+ /**
+ * Copy from temporary memory to value block.
+ * @param blockIndex
+ * @throws IOException
+ */
+ public void transfer(int blockIndex) throws IOException {
+ validateBlock(blockIndex);
checkConnected();
- byte[] incr_cmd = { (byte) 0xC1, (byte) block };
+ byte[] cmd = { (byte) 0xB0, (byte) blockIndex };
- transceive(incr_cmd, false);
+ transceive(cmd, false);
}
- public void decrement(int block) throws IOException {
+ /**
+ * Copy from value block to temporary memory.
+ * @param blockIndex
+ * @throws IOException
+ */
+ public void restore(int blockIndex) throws IOException {
+ validateBlock(blockIndex);
checkConnected();
- byte[] decr_cmd = { (byte) 0xC0, (byte) block };
+ byte[] cmd = { (byte) 0xC2, (byte) blockIndex };
- transceive(decr_cmd, false);
- }
-
- public void transfer(int block) throws IOException {
- checkConnected();
-
- byte[] trans_cmd = { (byte) 0xB0, (byte) block };
-
- transceive(trans_cmd, false);
- }
-
- public void restore(int block) throws IOException {
- checkConnected();
-
- byte[] rest_cmd = { (byte) 0xC2, (byte) block };
-
- transceive(rest_cmd, false);
+ transceive(cmd, false);
}
/**
@@ -414,4 +403,30 @@
public byte[] transceive(byte[] data) throws IOException {
return transceive(data, true);
}
+
+ private static void validateSector(int sector) {
+ // Do not be too strict on upper bounds checking, since some cards
+ // have more addressable memory than they report. For example,
+ // Mifare Plus 2k cards will appear as Mifare Classic 1k cards when in
+ // Mifare Classic compatibility mode.
+ // Note that issuing a command to an out-of-bounds block is safe - the
+ // tag should report error causing IOException. This validation is a
+ // helper to guard against obvious programming mistakes.
+ if (sector < 0 || sector >= MAX_SECTOR_COUNT) {
+ throw new IndexOutOfBoundsException("sector out of bounds: " + sector);
+ }
+ }
+
+ private static void validateBlock(int block) {
+ // Just looking for obvious out of bounds...
+ if (block < 0 || block >= MAX_BLOCK_COUNT) {
+ throw new IndexOutOfBoundsException("block out of bounds: " + block);
+ }
+ }
+
+ private static void validateValueOperand(int value) {
+ if (value < 0) {
+ throw new IllegalArgumentException("value operand negative");
+ }
+ }
}
diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/core/java/android/nfc/tech/MifareUltralight.java
index f096298..b514f1c 100644
--- a/core/java/android/nfc/tech/MifareUltralight.java
+++ b/core/java/android/nfc/tech/MifareUltralight.java
@@ -21,24 +21,43 @@
import java.io.IOException;
+//TOOD: Ultralight C 3-DES authentication, one-way counter
+
/**
* Technology class representing MIFARE Ultralight and MIFARE Ultralight C tags.
*
* <p>Support for this technology type is optional. If the NFC stack doesn't support this technology
* MIFARE Ultralight class tags will still be scanned, but will only show the NfcA technology.
*
- * <p>MIFARE Ultralight class tags have a series of 4 bytes pages that can be individually written
- * and read in chunks of 4 for a total read of 16 bytes.
+ * <p>MIFARE Ultralight compatible tags have 4 byte pages. The read command
+ * returns 4 pages (16 bytes) at a time, for speed. The write command operates
+ * on a single page (4 bytes) to minimize EEPROM write cycles.
+ *
+ * <p>The original MIFARE Ultralight consists of a 64 byte EEPROM. The first
+ * 4 pages are for the OTP area, manufacturer data, and locking bits. They are
+ * readable and some bits are writable. The final 12 pages are the user
+ * read/write area. For more information see the NXP data sheet MF0ICU1.
+ *
+ * <p>The MIFARE Ultralight C consists of a 192 byte EEPROM. The first 4 pages
+ * are for OTP, manufacturer data, and locking bits. The next 36 pages are the
+ * user read/write area. The next 4 pages are additional locking bits, counters
+ * and authentication configuration and are readable. The final 4 pages are for
+ * the authentication key and are not readable. For more information see the
+ * NXP data sheet MF0ICU2.
*/
public final class MifareUltralight extends BasicTagTechnology {
+ /** A MIFARE Ultralight compatible tag of unknown type */
+ public static final int TYPE_UNKNOWN = -1;
/** A MIFARE Ultralight tag */
public static final int TYPE_ULTRALIGHT = 1;
/** A MIFARE Ultralight C tag */
public static final int TYPE_ULTRALIGHT_C = 2;
- /** The tag type is unknown */
- public static final int TYPE_UNKNOWN = 10;
+
+ /** Size of a MIFARE Ultralight page in bytes */
+ public static final int PAGE_SIZE = 4;
private static final int NXP_MANUFACTURER_ID = 0x04;
+ private static final int MAX_PAGE_COUNT = 256;
private int mType;
@@ -68,48 +87,62 @@
if (a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID) {
// could be UL or UL-C
+ //TODO: stack should use NXP AN1303 procedure to make a best guess
+ // attempt at classifying Ultralight vs Ultralight C.
mType = TYPE_ULTRALIGHT;
}
}
- /** Returns the type of the tag */
+ /** Returns the type of the tag.
+ * <p>It is very hard to always accurately classify a MIFARE Ultralight
+ * compatible tag as Ultralight original or Ultralight C. So consider
+ * {@link #getType} a hint. */
public int getType() {
return mType;
}
// Methods that require connect()
/**
- * Reads a single 16 byte block from the given page offset.
+ * Read 4 pages (16 bytes).
+ * <p>The MIFARE Ultralight protocol always reads 4 pages at a time.
+ * <p>If the read spans past the last readable block, then the tag will
+ * return pages that have been wrapped back to the first blocks. MIFARE
+ * Ultralight tags have readable blocks 0x00 through 0x0F. So a read to
+ * block offset 0x0E would return blocks 0x0E, 0x0F, 0x00, 0x01. MIFARE
+ * Ultralight C tags have readable blocks 0x00 through 0x2B. So a read to
+ * block 0x2A would return blocks 0x2A, 0x2B, 0x00, 0x01.
+ * <p>This requires that the tag be connected.
*
- * <p>This requires a that the tag be connected.
- *
+ * @return 4 pages (16 bytes)
* @throws IOException
*/
- public byte[] readBlock(int page) throws IOException {
+ public byte[] readPages(int pageOffset) throws IOException {
+ validatePageOffset(pageOffset);
checkConnected();
- byte[] blockread_cmd = { 0x30, (byte) page}; // phHal_eMifareRead
- return transceive(blockread_cmd, false);
+ byte[] cmd = { 0x30, (byte) pageOffset};
+ return transceive(cmd, false);
}
/**
- * Writes a 4 byte page to the tag.
+ * Write 1 page (4 bytes).
+ * <p>The MIFARE Ultralight protocol always writes 1 page at a time.
+ * <p>This requires that the tag be connected.
*
- * <p>This requires a that the tag be connected.
- *
- * @param page The offset of the page to write
+ * @param pageOffset The offset of the page to write
* @param data The data to write
* @throws IOException
*/
- public void writePage(int page, byte[] data) throws IOException {
+ public void writePage(int pageOffset, byte[] data) throws IOException {
+ validatePageOffset(pageOffset);
checkConnected();
- byte[] pagewrite_cmd = new byte[data.length + 2];
- pagewrite_cmd[0] = (byte) 0xA2;
- pagewrite_cmd[1] = (byte) page;
- System.arraycopy(data, 0, pagewrite_cmd, 2, data.length);
+ byte[] cmd = new byte[data.length + 2];
+ cmd[0] = (byte) 0xA2;
+ cmd[1] = (byte) pageOffset;
+ System.arraycopy(data, 0, cmd, 2, data.length);
- transceive(pagewrite_cmd, false);
+ transceive(cmd, false);
}
/**
@@ -127,4 +160,15 @@
public byte[] transceive(byte[] data) throws IOException {
return transceive(data, true);
}
+
+ private static void validatePageOffset(int pageOffset) {
+ // Do not be too strict on upper bounds checking, since some cards
+ // may have more addressable memory than they report.
+ // Note that issuing a command to an out-of-bounds block is safe - the
+ // tag will wrap the read to an addressable area. This validation is a
+ // helper to guard against obvious programming mistakes.
+ if (pageOffset < 0 || pageOffset >= MAX_PAGE_COUNT) {
+ throw new IndexOutOfBoundsException("page out of bounds: " + pageOffset);
+ }
+ }
}
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 03f2184..c6804f9 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -31,7 +31,7 @@
/**
* A high-level connection to a {@link Tag} using one of the NFC type 1, 2, 3, or 4 technologies
* to interact with NDEF data. MiFare Classic cards that present NDEF data may also be used
- * via this class. To determine the exact technology being used call {@link #getTechnologyId()}
+ * via this class. To determine the exact technology being used call {@link #getType()}
*
* <p>You can acquire this kind of connection with {@link #get}.
*
diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java
index 1331bae..c8ccdcf 100644
--- a/core/java/android/nfc/tech/TagTechnology.java
+++ b/core/java/android/nfc/tech/TagTechnology.java
@@ -18,9 +18,10 @@
import android.nfc.Tag;
+import java.io.Closeable;
import java.io.IOException;
-public interface TagTechnology {
+public interface TagTechnology extends Closeable {
/**
* This technology is an instance of {@link NfcA}.
* <p>Support for this technology type is mandatory.
@@ -89,12 +90,6 @@
public static final int MIFARE_ULTRALIGHT = 9;
/**
- * Returns the technology type for this tag connection.
- * @hide
- */
- public int getTechnologyId();
-
- /**
* Get the {@link Tag} object this technology came from.
*/
public Tag getTag();
@@ -141,5 +136,5 @@
* @see #connect()
* @see #reconnect()
*/
- public void close();
+ public void close() throws IOException;
}
diff --git a/core/java/android/os/storage/IObbActionListener.java b/core/java/android/os/storage/IObbActionListener.java
index d6fa58a..6a6292d 100644
--- a/core/java/android/os/storage/IObbActionListener.java
+++ b/core/java/android/os/storage/IObbActionListener.java
@@ -112,7 +112,8 @@
_data.writeString(filename);
_data.writeInt(nonce);
_data.writeInt(status);
- mRemote.transact(Stub.TRANSACTION_onObbResult, _data, _reply, 0);
+ mRemote.transact(Stub.TRANSACTION_onObbResult, _data, _reply,
+ Binder.FLAG_ONEWAY);
_reply.readException();
} finally {
_reply.recycle();
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 9ed4dd8..7c40ab5 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -51,6 +51,6 @@
initialIntents[i] = (Intent)pa[i];
}
}
- super.onCreate(savedInstanceState, target, title, initialIntents, false);
+ super.onCreate(savedInstanceState, target, title, initialIntents, null, false);
}
}
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 215e9ae..841de06 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -63,11 +63,12 @@
protected void onCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState, new Intent(getIntent()),
getResources().getText(com.android.internal.R.string.whichApplication),
- null, true);
+ null, null, true);
}
protected void onCreate(Bundle savedInstanceState, Intent intent,
- CharSequence title, Intent[] initialIntents, boolean alwaysUseOption) {
+ CharSequence title, Intent[] initialIntents, List<ResolveInfo> rList,
+ boolean alwaysUseOption) {
super.onCreate(savedInstanceState);
mPm = getPackageManager();
intent.setComponent(null);
@@ -88,7 +89,7 @@
com.android.internal.R.id.clearDefaultHint);
mClearDefaultHint.setVisibility(View.GONE);
}
- mAdapter = new ResolveListAdapter(this, intent, initialIntents);
+ mAdapter = new ResolveListAdapter(this, intent, initialIntents, rList);
if (mAdapter.getCount() > 1) {
ap.mAdapter = mAdapter;
} else if (mAdapter.getCount() == 1) {
@@ -215,14 +216,16 @@
private List<DisplayResolveInfo> mList;
public ResolveListAdapter(Context context, Intent intent,
- Intent[] initialIntents) {
+ Intent[] initialIntents, List<ResolveInfo> rList) {
mIntent = new Intent(intent);
mIntent.setComponent(null);
mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- List<ResolveInfo> rList = mPm.queryIntentActivities(
- intent, PackageManager.MATCH_DEFAULT_ONLY
- | (mAlwaysCheck != null ? PackageManager.GET_RESOLVED_FILTER : 0));
+ if (rList == null) {
+ rList = mPm.queryIntentActivities(
+ intent, PackageManager.MATCH_DEFAULT_ONLY
+ | (mAlwaysCheck != null ? PackageManager.GET_RESOLVED_FILTER : 0));
+ }
int N;
if ((rList != null) && ((N = rList.size()) > 0)) {
// Only display the first matches that are either of equal
diff --git a/core/java/com/android/internal/nfc/LlcpSocket.java b/core/java/com/android/internal/nfc/LlcpSocket.java
index 73c09259..63888ae 100644
--- a/core/java/com/android/internal/nfc/LlcpSocket.java
+++ b/core/java/com/android/internal/nfc/LlcpSocket.java
@@ -193,7 +193,7 @@
throw new IOException();
}
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException in send(): ", e);
+ Log.e(TAG, "RemoteException in receive(): ", e);
}
return receivedLength;
diff --git a/core/java/com/android/internal/widget/DigitalClock.java b/core/java/com/android/internal/widget/DigitalClock.java
index 303a1bf..7289751 100644
--- a/core/java/com/android/internal/widget/DigitalClock.java
+++ b/core/java/com/android/internal/widget/DigitalClock.java
@@ -80,7 +80,11 @@
}
});
} else {
- mContext.unregisterReceiver(this);
+ try {
+ mContext.unregisterReceiver(this);
+ } catch (RuntimeException e) {
+ // Shouldn't happen
+ }
}
}
};
@@ -124,7 +128,11 @@
digitalClock.setDateFormat();
digitalClock.updateTime();
} else {
- mContext.getContentResolver().unregisterContentObserver(this);
+ try {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ } catch (RuntimeException e) {
+ // Shouldn't happen
+ }
}
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b83aea8..a130bf5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1077,7 +1077,7 @@
<permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
android:label="@string/permlab_changeComponentState"
android:description="@string/permdesc_changeComponentState"
- android:protectionLevel="signature" />
+ android:protectionLevel="signatureOrSystem" />
<!-- Allows an application to use SurfaceFlinger's low level features -->
<permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
diff --git a/core/res/res/drawable-hdpi/btn_check_off.png b/core/res/res/drawable-hdpi/btn_check_off.png
index 1381efa..3928b7df 100644
--- a/core/res/res/drawable-hdpi/btn_check_off.png
+++ b/core/res/res/drawable-hdpi/btn_check_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_disable.png b/core/res/res/drawable-hdpi/btn_check_off_disable.png
index abf0e97..922737e 100644
--- a/core/res/res/drawable-hdpi/btn_check_off_disable.png
+++ b/core/res/res/drawable-hdpi/btn_check_off_disable.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_disable_focused.png b/core/res/res/drawable-hdpi/btn_check_off_disable_focused.png
index beae940..992f0fe 100644
--- a/core/res/res/drawable-hdpi/btn_check_off_disable_focused.png
+++ b/core/res/res/drawable-hdpi/btn_check_off_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_pressed.png b/core/res/res/drawable-hdpi/btn_check_off_pressed.png
index 94f5906..c6195ab 100644
--- a/core/res/res/drawable-hdpi/btn_check_off_pressed.png
+++ b/core/res/res/drawable-hdpi/btn_check_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_selected.png b/core/res/res/drawable-hdpi/btn_check_off_selected.png
index ed50a89..d467769 100644
--- a/core/res/res/drawable-hdpi/btn_check_off_selected.png
+++ b/core/res/res/drawable-hdpi/btn_check_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on.png b/core/res/res/drawable-hdpi/btn_check_on.png
index 7ad04a4..91d8ba9 100644
--- a/core/res/res/drawable-hdpi/btn_check_on.png
+++ b/core/res/res/drawable-hdpi/btn_check_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disable.png b/core/res/res/drawable-hdpi/btn_check_on_disable.png
index 25b7c91..6472087 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_disable.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_disable.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_disable_focused.png b/core/res/res/drawable-hdpi/btn_check_on_disable_focused.png
index 5187a0b..58ba72d 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_disable_focused.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_pressed.png b/core/res/res/drawable-hdpi/btn_check_on_pressed.png
index a29dae6..42b8edc 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_pressed.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_selected.png b/core/res/res/drawable-hdpi/btn_check_on_selected.png
index a11ef46..7c94adf 100644
--- a/core/res/res/drawable-hdpi/btn_check_on_selected.png
+++ b/core/res/res/drawable-hdpi/btn_check_on_selected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off.png b/core/res/res/drawable-mdpi/btn_check_off.png
index 251ddff..b0541d9 100644
--- a/core/res/res/drawable-mdpi/btn_check_off.png
+++ b/core/res/res/drawable-mdpi/btn_check_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disable.png b/core/res/res/drawable-mdpi/btn_check_off_disable.png
index 45e6804..5ec8d03 100644
--- a/core/res/res/drawable-mdpi/btn_check_off_disable.png
+++ b/core/res/res/drawable-mdpi/btn_check_off_disable.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_disable_focused.png b/core/res/res/drawable-mdpi/btn_check_off_disable_focused.png
index 193acd2..341ffb9 100644
--- a/core/res/res/drawable-mdpi/btn_check_off_disable_focused.png
+++ b/core/res/res/drawable-mdpi/btn_check_off_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_pressed.png b/core/res/res/drawable-mdpi/btn_check_off_pressed.png
index 807901c..5e77a77 100644
--- a/core/res/res/drawable-mdpi/btn_check_off_pressed.png
+++ b/core/res/res/drawable-mdpi/btn_check_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_selected.png b/core/res/res/drawable-mdpi/btn_check_off_selected.png
index dbc3beb..4e40f207 100644
--- a/core/res/res/drawable-mdpi/btn_check_off_selected.png
+++ b/core/res/res/drawable-mdpi/btn_check_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on.png b/core/res/res/drawable-mdpi/btn_check_on.png
index 4c83e2e..23304a1 100644
--- a/core/res/res/drawable-mdpi/btn_check_on.png
+++ b/core/res/res/drawable-mdpi/btn_check_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_disable.png b/core/res/res/drawable-mdpi/btn_check_on_disable.png
index f1bf178..817745c 100644
--- a/core/res/res/drawable-mdpi/btn_check_on_disable.png
+++ b/core/res/res/drawable-mdpi/btn_check_on_disable.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_disable_focused.png b/core/res/res/drawable-mdpi/btn_check_on_disable_focused.png
index ea232ee..13d13b6 100644
--- a/core/res/res/drawable-mdpi/btn_check_on_disable_focused.png
+++ b/core/res/res/drawable-mdpi/btn_check_on_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_pressed.png b/core/res/res/drawable-mdpi/btn_check_on_pressed.png
index 0de8a4c..9cdc796 100644
--- a/core/res/res/drawable-mdpi/btn_check_on_pressed.png
+++ b/core/res/res/drawable-mdpi/btn_check_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_selected.png b/core/res/res/drawable-mdpi/btn_check_on_selected.png
index 20294f3..b2c3727 100644
--- a/core/res/res/drawable-mdpi/btn_check_on_selected.png
+++ b/core/res/res/drawable-mdpi/btn_check_on_selected.png
Binary files differ
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 046bb4e..504b828 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -727,8 +727,8 @@
<string name="yes" msgid="5362982303337969312">"Aceptar"</string>
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
- <string name="capital_on" msgid="1544682755514494298">"Encendido"</string>
- <string name="capital_off" msgid="6815870386972805832">"APAGADO"</string>
+ <string name="capital_on" msgid="1544682755514494298">"Sí"</string>
+ <string name="capital_off" msgid="6815870386972805832">"No"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar la acción mediante"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar de manera predeterminada en esta acción."</string>
<string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar la predeterminación en Configuración de la página principal > Aplicaciones > Administrar aplicaciones."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 7485791..543b53e 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -450,7 +450,7 @@
<item msgid="9192514806975898961">"Personalizar"</item>
</string-array>
<string-array name="emailAddressTypes">
- <item msgid="8073994352956129127">"Personal"</item>
+ <item msgid="8073994352956129127">"Casa"</item>
<item msgid="7084237356602625604">"Trabajo"</item>
<item msgid="1112044410659011023">"Otra"</item>
<item msgid="2374913952870110618">"Personalizar"</item>
@@ -558,7 +558,7 @@
<string name="lockscreen_low_battery" msgid="1482873981919249740">"Conecta el cargador"</string>
<string name="lockscreen_missing_sim_message_short" msgid="7381499217732227295">"Falta la tarjeta SIM"</string>
<string name="lockscreen_missing_sim_message" msgid="2186920585695169078">"No se ha insertado ninguna tarjeta SIM en el teléfono."</string>
- <string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserta una tarjeta SIM."</string>
+ <string name="lockscreen_missing_sim_instructions" msgid="8874620818937719067">"Inserta una tarjeta SIM"</string>
<string name="emergency_calls_only" msgid="6733978304386365407">"Solo llamadas de emergencia"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Bloqueada para la red"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"La tarjeta SIM está bloqueada con el código PUK."</string>
@@ -727,8 +727,8 @@
<string name="yes" msgid="5362982303337969312">"Aceptar"</string>
<string name="no" msgid="5141531044935541497">"Cancelar"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Atención"</string>
- <string name="capital_on" msgid="1544682755514494298">"Activado"</string>
- <string name="capital_off" msgid="6815870386972805832">"Desconectado"</string>
+ <string name="capital_on" msgid="1544682755514494298">"SÍ"</string>
+ <string name="capital_off" msgid="6815870386972805832">"NO"</string>
<string name="whichApplication" msgid="4533185947064773386">"Completar acción utilizando"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Utilizar de forma predeterminada para esta acción"</string>
<string name="clearDefaultHintMsg" msgid="4815455344600932173">"Borrar valores predeterminados en la página de configuración de la pantalla de inicio del teléfono > Aplicaciones > Administrar aplicaciones\"."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 9f3c8a8..8608b5b 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -589,7 +589,7 @@
<string name="factorytest_not_system" msgid="4435201656767276723">"L\'azione FACTORY_TEST è supportata soltanto per i pacchetti installati in /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"Nessun pacchetto trovato che fornisca l\'azione FACTORY_TEST."</string>
<string name="factorytest_reboot" msgid="6320168203050791643">"Riavvia"</string>
- <string name="js_dialog_title" msgid="8143918455087008109">"La pagina all\'indirizzo <xliff:g id="TITLE">%s</xliff:g> indica:"</string>
+ <string name="js_dialog_title" msgid="8143918455087008109">"Avviso relativo alla pagina <xliff:g id="TITLE">%s</xliff:g>:"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload" msgid="1901675448179653089">"Uscire da questa pagina?"\n\n"<xliff:g id="MESSAGE">%s</xliff:g>"\n\n"Seleziona OK per continuare o Annulla per rimanere nella pagina corrente."</string>
<string name="save_password_label" msgid="6860261758665825069">"Conferma"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 00ee365..3563cf8 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -883,7 +883,7 @@
<string name="reset" msgid="2448168080964209908">"リセット"</string>
<string name="submit" msgid="1602335572089911941">"送信"</string>
<string name="description_star" msgid="2654319874908576133">"お気に入り"</string>
- <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードを有効にする"</string>
+ <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"運転モードになっています"</string>
<string name="car_mode_disable_notification_message" msgid="668663626721675614">"運転モードを終了するには選択してください。"</string>
<string name="tethered_notification_title" msgid="3146694234398202601">"テザリングまたはアクセスポイントが有効です"</string>
<string name="tethered_notification_message" msgid="3067108323903048927">"タップして設定する"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 8de3d33..37f56ea 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -608,7 +608,7 @@
<string name="save_password_never" msgid="8274330296785855105">"Никогда"</string>
<string name="open_permission_deny" msgid="5661861460947222274">"У вас нет разрешения на открытие этой страницы."</string>
<string name="text_copied" msgid="4985729524670131385">"Текст скопирован в буфер обмена."</string>
- <string name="more_item_label" msgid="4650918923083320495">"Дополнительно"</string>
+ <string name="more_item_label" msgid="4650918923083320495">"Ещё"</string>
<string name="prepend_shortcut_label" msgid="2572214461676015642">"Меню+"</string>
<string name="menu_space_shortcut_label" msgid="2410328639272162537">"пробел"</string>
<string name="menu_enter_shortcut_label" msgid="2743362785111309668">"ввод"</string>
diff --git a/docs/html/sdk/android-3.0-highlights.jd b/docs/html/sdk/android-3.0-highlights.jd
new file mode 100644
index 0000000..f48aed8
--- /dev/null
+++ b/docs/html/sdk/android-3.0-highlights.jd
@@ -0,0 +1,266 @@
+page.title=Android 3.0 Platform Highlights
+
+@jd:body
+
+
+<style type="text/css">
+#jd-content {
+ max-width:1200px;
+}
+#jd-content div.screenshot {
+ float:left;
+ clear:left;
+ padding:15px 30px 15px 0;
+}
+#jd-content div.video {
+ float:right;
+ padding:0 60px 40px;
+ margin-top:-15px;
+}
+#jd-content table.columns {
+ margin:0 0 1em 0;
+}
+#jd-content table.columns td {
+ padding:0;
+}
+#jd-content table.columns td+td {
+ padding:0 2em;
+}
+#jd-content table.columns td img {
+ margin:0;
+}
+#jd-content table.columns td+td>*:first-child {
+ margin-top:-2em;
+}
+.green {
+ color:#8db529;
+ font-weight:bold;
+}
+</style>
+
+
+
+
+
+
+<p>Welcome to Android 3.0!</p>
+
+<p>The Android 3.0 platform introduces many new and exciting features for users and developers.
+This document provides a glimpse of some of the new features and technologies, as delivered in the Android 3.0 Preview SDK. For more information about the SDK or how to download it, please see the <a href="{@docRoot}sdk/preview/index.html">Preview SDK</a> document.</p>
+
+<ul>
+ <li><a href="#UserFeatures">New User Features</a></li>
+ <li><a href="#DeveloperApis">New Developer Features</a></li>
+</ul>
+
+<h2 id="UserFeatures" style="clear:right">New User Features</h2>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;margin-left:1em;float:right;padding-top:2em;"><a href="images/3.0/home_hero1_full.png" target="_android"><img src="images/3.0/home_hero1.png" alt="" height="280" /></a></div>
+
+<h3>New UI designed from the ground up for tablets</h3>
+
+<p>Android 3.0 is a new version of the Android platform that is specifically optimized for devices with larger screen sizes, particularly tablets. It introduces a brand new, truly virtual and “holographic” UI design, as well as an elegant, content-focused interaction model.</p>
+
+<p>Android 3.0 builds on the things people love most about Android — refined multitasking, rich notifications, Home screen customization, widgets, and more — and transforms them with a vibrant, 3D experience and deeper interactivity, making them familiar but even better than before.</p>
+
+<p>The new UI brings fresh paradigms for interaction, navigation, and customization and makes them available to all applications — even those built for earlier versions of the platform. Applications written for Android 3.0 are able to use an extended set of UI objects, powerful graphics, and media capabilities to engage users in new ways.</p>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>System Bar, for global status and notifications</strong></p>
+
+<p>Across the system and in all applications, users have quick access to notifications, system status, and soft navigation buttons in a System Bar, available at the bottom of the screen. The System Bar is always present and is a key touchpoint for users, but in a new "lights out mode" can also be dimmed for full-screen viewing, such as for videos.</p>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Action Bar, for application control</strong></p>
+
+<p>In every application, users have access to contextual options, navigation, widgets, or other types of content in an Action Bar, displayed at the top of the screen. The Action Bar is always present when an application is in use, although its content, theme, and other properties are managed by the application rather than the system. The Action Bar is another key touchpoint for users, especially with action items and an overflow dropdown menu, which users frequently access in a similar manner in most applications. </p>
+
+</div>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;"><a href="images/3.0/homescreen_cust_port_full.png" target="_android"><img src="images/3.0/homescreen_cust_port.png" alt="" height="280" /></a></div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Customizable Home screens</strong></p>
+
+<p>Five customizable Home screens give users instant access to all parts of the system from any context. Each screen offers a large grid that maintains spatial arrangement in all orientations. Users can select and manipulate Home screen widgets, app shortcuts, and wallpapers using a dedicated visual layout mode. Visual cues and drop shadows improve visibility when adjusting the layout of shortcuts and widgets. Each Home screen also offers a familiar launcher for access to all installed applications, as well as a Search box for universal search of apps, contacts, media files, web content, and more.</p>
+
+</div>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1.5em;float:left;"><a href="images/3.0/tasks_full.png" target="_android"><img src="images/3.0/tasks.png" alt="" height="280" /></a>
+
+<!--<p style="font-size:90%">Figure</p> --></div>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Recent Apps, for easy visual multitasking</strong></p>
+
+<p>Multitasking is a key strength of Android and it is central to the Android 3.0 experience. As users launch applications to handle various tasks, they can use the Recent Apps list in the System Bar to see the tasks underway and quickly jump from one application context to another. To help users rapidly identify the task associated with each app, the list shows a snapshot of its actual state when the user last viewed it.</p>
+
+</div>
+
+
+<h3>Redesigned keyboard</h3>
+
+<p>The Android soft keyboard is redesigned to make entering text fast and accurate on larger screen sizes. The keys are reshaped and repositioned for improved targeting, and new keys have been added, such as a Tab key, to provide richer and more efficient text input. Users can touch-hold keys to access menus of special characters and switch text/voice input modes from a button in the System Bar.</p>
+
+<div style="padding-top:1em;">
+<div style="margin-right:1em;float:right;"><a href="images/3.0/copy_full.png" target="_android"><img src="images/3.0/copy.png" alt="" height="180" /></a></div>
+
+
+<h3>Improved text selection, copy and paste</h3>
+
+<p>When entering or viewing text, a new UI lets users quickly select a word by press-hold and then adjust the selection area as needed by dragging a set of bounding arrows to new positions. Users can then select an action from the Action Bar, such as copy to the clipboard, share, paste, web search, or find. </p>
+
+
+<h3>New connectivity options</h3>
+
+<p>Android 3.0 includes new connectivity features that add versatility and convenience for users. Built-in support for Media/Photo Transfer Protocol lets users instantly sync media files with a USB-connected camera or desktop computer, without needing to mount a USB mass-storage device. Users can also connect full keyboards over either USB or Bluetooth, for a familiar text-input environment. For improved wi-fi connectivity, a new combo scan reduces scan times across bands and filters. New support for Bluetooth tethering means that more types of devices can share the network connection of an Android-powered device.</p>
+
+
+<h3>Updated set of standard apps</h3>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;;padding-top:0em;margin-left:1em;"><a href="images/3.0/browser_full.png" target="_android"><img src="images/3.0/browser.png" alt="" height="200" /></a><br>
+<a href="images/3.0/camera_full.png" target="_android"><img src="images/3.0/camera_full.png" alt="" height="200" /></a></div>
+
+<p>The Android 3.0 platform includes an updated set of standard applications that are designed for use on larger screen devices. The sections below highlight some of the new features. </p>
+
+<strong>Browser</strong></p>
+
+<p>The browser includes new features that let users navigate and organize more efficiently. Multiple tabs replace browser windows and a new “incognito” mode allows anonymous browsing. Bookmarks and history are presented and managed in a single unified view. Users can now choose to automatically sign into Google sites on the browser with a supplied account and sync bookmarks with Google Chrome. New multitouch support is now available to JavaScript and plugins. Users can enjoy a better browsing experience at non-mobile sites through an improved zoom and viewport model, overflow scrolling, support for fixed positioning, and more.</p>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Camera and Gallery</strong></p>
+
+<p>The Camera application has been redesigned to take advantage of a larger screen for quick access to exposure, focus, flash, zoom, front-facing camera, and more. The Gallery application lets users view albums and other collections in full-screen mode, with easy access to thumbnails for other photos in the collection. </p>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Contacts</strong></p>
+
+<p>The Contacts app uses a new two-pane UI and Fast Scroll to let users easily organize and locate contacts. The application offers improved formatting of international phone numbers as user types, based on home country and an international number parsing library. Contact information is presented in a card-like UI, making it easier for users to read and edit contacts.</p>
+
+<p style="margin-top:1em;margin-bottom:.75em;"><strong>Email</strong></p>
+
+<p>The Email application uses a new two-pane UI to make viewing and organizing messages more efficient. The app lets users select one or more messages, then select an action from the Action Bar, such as moving them to a folder. Users can sync attachments for later viewing and keep track of email using a home screen Widget.</p>
+
+</div>
+
+
+<h2 id="DeveloperApis" style="clear:both">New Developer Features</h2>
+
+<p>The Android 3.0 platform is designed specially to meet the unique needs of applications on devices with larger screen sizes. It offers all of the tools developers need to create incredible visual and interaction experiences on these devices.</p>
+
+ <ul>
+<li><a href="#ui">New UI framework for creating great tablet apps</a></li>
+<li><a href="#graphics">High-performance 2D and 3D graphics</a></li>
+<li><a href="#multicore">Support for multicore processor architectures</a></li>
+<li><a href="#multimedia">Rich multimedia and connectivity</a></li>
+<li><a href="#enterprise">Enhancements for enterprise</a></li>
+<li><a href="#compatibility">Compatibility with existing apps</a></li>
+</ul>
+
+<h3 id="ui">New UI Framework for creating great tablet apps</h3>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;"><a href="images/3.0/contacts_full.png" target="_android"><img src="images/3.0/contacts.png" alt="" height="200" /></a></div>
+
+
+<p style="margin-top:.75em;margin-bottom:.75em;"><strong>Activity fragments, for greater control of content and design flexibility</strong></p>
+
+<p>Starting with Android 3.0, developers can break the Activities of their applications into subcomponents called Fragments, then combine them in a variety of ways to create a richer, more interactive experience. For example, an application can use a set of Fragments to create a true multipane UI, with the user being able to interact with each pane independently. Fragments can be added, removed, replaced, and animated inside an Activity dynamically, and they are modular and reusable across multiple Activities. Because they are modular, Fragments also offer an efficient way for developers to write applications that can run properly on both larger screen as well as smaller screen devices.</p>
+
+</div>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Redesigned UI widgets</strong></p>
+
+<p>Android 3.0 offers an updated set of UI widgets that developers can use to quickly add new types of content to their applications. The new UI widgets are redesigned for use on larger screens such as tablets and incorporate the new holographic UI theme. Several new widget types are available, including a 3D stack, search box, a date/time picker, number picker, calendar, popup menu, and others. Most of the redesigned UI widgets can now be used as remote views in application widgets displayed on the home screen. Applications written for earlier versions can inherit the new Widget designs and themes.</p>
+
+
+<div style="padding-top:0em;">
+<div style="margin-right:1.5em;float:left;margin-left:0em;"><a href="images/3.0/widgets.png" target="_android"><img src="images/3.0/widgets.png" alt="" height="200" target="_android" /></a></div>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Expanded Home screen widgets</strong></p>
+
+<p>Home screen widgets are popular with users because they offer fast access to application-specific data directly from the home screen. Android 3.0 lets developers take home screen widgets to the next level, offering more types of content and new modes of interaction with users. Developers can now use more standard UI widget types home screen widgets, including widgets that let users flip through collections of content as 3D stacks, grids, or lists. Users can interact with the home screen widgets in new ways, such as by using touch gestures to scroll and flip the content displayed in a widget. </p>
+
+</div>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Persistent Action Bar</strong></p>
+
+<p>The platform provides each application with its own instance of the Action Bar at the top of the screen, which the application can use to give the user quick access to contextual options, widgets, status, navigation, and more. The application can also customize the display theme of its Action Bar instance. The Action Bar lets developers expose more features of their applications to users in a familiar location, while also unifying the experience of using an application that spans multiple Activities or states.</p>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Richer notifications</strong></p>
+
+<p>Notifications are a key part of the Android user experience because they let applications show key updates and status information to users in real time. Android 3.0 extends this capability, letting developers include richer content and control more properties. A new builder class lets developers quickly create notifications that include large and small icons, a title, a priority flag, and any properties already available in previous versions. Notifications can offer more types of content by building on the expanded set of UI Widgets that are now available as remote Views.</p>
+
+<div style="padding-top:0em;">
+<div style="margin-right:1em;float:right;margin-left:1em;"><a href="images/3.0/mail_drag_full.png" target="_android"><img src="images/3.0/mail_drag.png" alt="" height="200" style="padding-top:1em;"/></a></div>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Multiselect, clipboard, and drag-and-drop</strong></p>
+
+<p>The platform offers convenient new interaction modes that developers can use. For managing collections of items in lists or grids, developers can offer a new multiselect mode that lets users choose multiple items for an action. Developers can also use a new system-wide Clipboard to let users easily copy any type of data into and out of their applications. To make it easier for users to manage and organize files, developers can now add drag-and-drop interaction through a DragEvent framework.</p>
+
+</div>
+
+
+<h3 id="graphics">High-performance 2D and 3D graphics</h3>
+
+<p style="margin-top:.75em;margin-bottom:.75em;"><strong>New animation framework</strong></p>
+
+<p>The platform includes a flexible new animation framework that lets developers easily animate the properties of UI elements such as Views, Widgets, Fragments, Drawables, or any arbitrary object. Animations can create fades or movement between states, loop an animated image or an existing animation, change colors, and much more. Adding animation to UI elements can add visual interest to an application and refine the user experience, to keep users engaged.</p>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Hardware-accelerated 2D graphics</strong></p>
+
+<p>Android 3.0 offers a new hardware-accelerated OpenGL renderer that gives a performance boost to many common graphics operations for applications running in the Android framework. When the renderer is enabled, most operations in Canvas, Paint, Xfermode, ColorFilter, Shader, and Camera are accelerated. Developers can control how hardware-acceleration is applied at every level, from enabling it globally in an application to enabling it in specific Activities and Views inside the application.</p>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Renderscript 3D graphics engine</strong></p>
+
+<p>Renderscript is a runtime 3D framework that provides both an API for building 3D scenes as well as a special, platform-independent shader language for maximum performance. Using Renderscript, you can accelerate graphics operations and data processing. Renderscript is an ideal way to create high-performance 3D effects for applications, wallpapers, carousels, and more.</p>
+
+
+<h3 id="multicore">Support for multicore processor architectures</h3>
+
+<p>Android 3.0 is the first version of the platform designed to run on either single or multicore processor architectures. A variety of changes in the Dalvik VM, Bionic library, and elsewhere add support for symmetric multiprocessing in multicore environments. These optimizations can benefit all applications, even those that are single-threaded. For example, with two active cores, a single-threaded application might still see a performance boost if the Dalvik garbage collector runs on the second core. The system will arrange for this automatically.</p>
+
+
+<h3 id="multimedia">Rich multimedia and connectivity</h3>
+
+<p style="margin-top:.75em;margin-bottom:.75em;"><strong>HTTP Live streaming</strong></p>
+
+<p>Applications can now pass an M3U playlist URL to the media framework to begin an HTTP Live streaming session. The media framework supports most of the HTTP Live streaming specification, including adaptive bit rate.</p>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Pluggable DRM framework</strong></p>
+
+<p>Android 3.0 includes an extensible DRM framework that lets applications manage protected content according to a variety of DRM mechanisms that may be available on the device. For application developers, the framework API offers an consistent, unified API that simplifies the management of protected content, regardless of the underlying DRM engines. </p>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>Digital media file transfer</strong></p>
+
+<p>The platform includes built-in support for Media/Picture Transfer Protocol (MTP/PTP) over USB, which lets users easily transfer any type of media files between devices and to a host computer. Developers can build on this support, creating applications that let users create or manage media files that they may want to transfer or share across devices. </p>
+
+<p style="margin-top:1.25em;margin-bottom:.75em;"><strong>More types of connectivity</strong></p>
+
+<p>The platform offers new connectivity that developers can build on. API support for Bluetooth A2DP and HSP profiles lets applications query Bluetooth profiles for connected devices, audio state, and more, then notify the user. For example, a music application can check connectivity and status and let the user know that music is playing through a stereo headset. Applications can also register to receive system broadcasts of pre-defined vendor-specific AT commands, such as Platronics Xevent. For example, an application could receive broadcasts that indicate a connected device's battery level and could notify the user or take other action as needed. Applications can also take advantage of the platform's new support for full keyboards connected by USB or Bluetooth. </p>
+
+
+<h3 id="enterprise">Enhancements for enterprise</h3>
+
+<p>In Android 3.0, developers of device administration applications can support new types of policies, including policies for encrypted storage, password expiration, password history, and password complex characters required. </p>
+
+<h3 id="compatibility">Compatibility with existing apps</h3>
+
+<p>Android 3.0 brings a new UI designed for tablets and other larger screen devices, but it also is fully compatible with applications developed for earlier versions of the platform, or for smaller screen sizes. Existing applications can seamlessly participate in the new holographic UI theme without code changes, by adding a single attribute in their manifest files. The platform emulates the Menu key, which is replaced by the overflow menu in the Action Bar in the new UI. Developers wanting to take fuller advantage of larger screen sizes can also create dedicated layouts and assets for larger screens and add them to their existing applications.</p>
+
+
+<h2>More information</h2>
+
+<div class="video">
+<object width="278" height="180">
+<param name="movie" value="http://www.youtube.com/v/hPUGNCIozp0?hl=en&fs=1"></param>
+<param name="allowFullScreen" value="true"></param><param name="allowscriptaccess"
+value="always"></param>
+<embed src="http://www.youtube.com/v/hPUGNCIozp0?hl=en&fs=1" type="application/x-shockwave-flash"
+allowscriptaccess="always" allowfullscreen="true" width="278" height="180"></embed>
+</object>
+</div>
+
+<p>For more information about the new developer APIs, see the Android 3.0 Platform notes in the SDK Preview documentation, available by download through the Android SDK Manager.</p>
+
+<p>For a video overview of platform features, see the Android 3.0 Sneak Peek. </p>
+
+
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 0d1ea0c..78d2ccd 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,9 +1,8 @@
page.title=ADT Plugin for Eclipse
-sdk.preview=0
-adt.zip.version=8.0.1
-adt.zip.download=ADT-8.0.1.zip
-adt.zip.bytes=8724909
-adt.zip.checksum=0e62185279083ddc01f18098ce7ba2d1
+adt.zip.version=9.0.0
+adt.zip.download=ADT_9.0.0.zip
+adt.zip.bytes=4433536
+adt.zip.checksum=bc2757f2a5a11d131390ce547bae154b
@jd:body
@@ -100,6 +99,115 @@
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ADT 9.0.0</a> <em>(January 2011)</em>
+ <div class="toggleme">
+
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd>ADT 9.0.0 is designed for use with SDK Tools r9. If you haven't
+already installed SDK Tools r9 into your SDK, use the Android SDK and AVD Manager to do
+so.</dd>
+
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>"Go To Declaration" hyperlink support: You can jump directly from code references (such as
+ <code>R.id.main</code>) to the corresponding XML declaration, or from XML attributes (such as
+ <code>@string</code>) to the corresponding resource definition, or from manifest XML
+ registrations to activities and services.</li>
+ <li>Improvements were made to name refactoring.</li>
+ <li>AVDs now automatically save their state, so they can restart almost instantly. You can enable this feature when
+ creating an AVD or by editing an AVD with the AVD Manager.</li>
+ <li>Improvements to the Visual Layout Editor:
+ <ul>
+ <li>Support for rendering targets: You can now choose an arbitrary Android platform to
+ render the current page, regardless of the project's minimum platform. This makes it
+ easy to verify the layout and appearance of your activity on different versions of
+ the platform.
+ </li>
+ <li>Improved support for empty and nested layouts: Dragging items over nested and
+ invisible layouts automatically enlarges and highlights these layouts, so that they
+ can receive drops.
+ </li>
+ <li>XML formatting improvements: The editor generates cleaner XML and you can now enable
+ XML auto-formatting in the <strong>Preferences</strong> menu.</li>
+ <li>Improved Outline labels: The Outline tab now displays additional information about each
+ View. Textual Views display a snippet of the actual text. Views with a source
+ (such as ImageView) displays the resource name. Included Views display the name of the View.
+ </li>
+ <li>When you right click a View in the Layout Editor,
+ the context menu now contains <strong>Edit ID...</strong> and <strong>Edit Text...</strong>
+ items. The <strong>Properties...</strong> context menus now list all of the properties and
+ provide a way to edit them
+ (<a href="http://tools.android.com/recent/editidtextandotherpropertiesviamenu">Details</a>).
+ </li>
+ <li>The layout editor now properly handles
+ <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element"><code><include></code></a>
+ and <a href="{@docRoot}guide/topics/resources/layout-resource.html#merge-element"><code><merge></code></a>
+ tags (<a href="http://tools.android.com/recent/supportforincludeandmerge">Details</a>).</li>
+ <li>"Extract as Include" refactoring: The Layout Editor has a new refactoring that allows
+ you to select one or more views in a layout, and extract it into a separate layout
+ (<a href="http://tools.android.com/recent/extractasincluderefactoring">Details</a>).</li>
+ <li>Improved diagnostics for class loading and rendering errors: Class loading and rendering
+ error messages are more useful and provide better information about the root cause of the
+ error.</li>
+ <li>Improved error handling to prevent drag and reordering operations from adding children
+ into an {@link android.widget.AdapterView}.</li>
+ <li>Outline reordering: Reordering your views in the Outline tab is much easier
+ (<a href="http://tools.android.com/recent/outlineimprovements">Details</a>).</li>
+ <li>Fix for keybinding bug where keyboard shortcuts did not work (Issues
+ <a href="http://code.google.com/p/android/issues/detail?id=13231">13231</a> and
+ <a href="http://code.google.com/p/android/issues/detail?id=13134">13134</a>).</li>
+ <li>Fix for problems with Custom layout attribute menu (Issue
+ <a href="http://code.google.com/p/android/issues/detail?id=13134">13134</a>).</li>
+ <li>Automatic configuration for various view types: Certain views have properties configured
+ by default. For example, the width of an {@link android.widget.EditText} object is set to
+ <code>match_parent</code> when added to a vertical {@link android.widget.LinearLayout}
+ or a default image is added to an {@link android.widget.ImageButton}.</li>
+ <li>Previews during dragging: Dragging from the palette or dragging within the layout editor
+ now shows live previews of the dragged item.</li>
+ <li>Navigation improvements: In the Layout Editor, double-clicking Views jumps to the
+ corresponding XML element. In the Outline view, double-clicking opens the Properties view.</li>
+ <li>The editor has Honeycomb style animation preview support.</li>
+ <li>Improved rendering support for various Views (such as TabHosts and SlidingDrawers) in
+ Honeycomb (Issues <a href="http://code.google.com/p/android/issues/detail?id=3162">3162</a>
+ and <a href="http://code.google.com/p/android/issues/detail?id=13092">13092</a>).</li>
+ <li>Included layouts can be rendered and edited in the context of the layouts that include
+ them. From a layout using an <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element">
+ <code><include></code></a> tag, double-clicking on the
+ <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element">
+ <code><include></code></a> element edits the referenced layout in the context of the
+ current layout. Additionally, when editing a layout that is included by other layouts,
+ you can quickly change between context layouts, by right clicking in the editor and choosing
+ <strong>Show included in...</strong>. This feature is only available in Honeycomb.</li>
+ </ul>
+ </li>
+ <li>This release fixes many other bugs, but the most important ones are listed below:
+ <ul>
+ <li>Fixed issue that prevented launching debug builds on productions devices when
+ <code>debuggable=true</code> was not set in the Android manifest.</li>
+ <li>The LogCat view in DDMS properly handles UTF-8 characters.</li>
+ <li>The SDK Manager is more reliable on Windows
+ (<a href="http://tools.android.com/recent/sdkmanagerfixes">Details</a>).</li>
+ <li>A JUnit initialization bug that prevented you from working with JUnit tests was fixed
+ (Issue <a href="http://code.google.com/p/android/issues/detail?id=12411">12411</a>).</li>
+ </ul>
+</li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
ADT 8.0.1</a> <em>(December 2010)</em>
<div class="toggleme">
@@ -121,7 +229,7 @@
<p>Also see the recent release notes for 8.0.0, below.</p>
</dd>
</dl>
- </div>
+</div>
</div>
diff --git a/docs/html/sdk/images/3.0/browser.png b/docs/html/sdk/images/3.0/browser.png
new file mode 100644
index 0000000..5d3ba31
--- /dev/null
+++ b/docs/html/sdk/images/3.0/browser.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/browser_full.png b/docs/html/sdk/images/3.0/browser_full.png
new file mode 100644
index 0000000..495a23d
--- /dev/null
+++ b/docs/html/sdk/images/3.0/browser_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/camera.png b/docs/html/sdk/images/3.0/camera.png
new file mode 100644
index 0000000..a549182
--- /dev/null
+++ b/docs/html/sdk/images/3.0/camera.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/camera_full.png b/docs/html/sdk/images/3.0/camera_full.png
new file mode 100644
index 0000000..a549182
--- /dev/null
+++ b/docs/html/sdk/images/3.0/camera_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/contacts.png b/docs/html/sdk/images/3.0/contacts.png
new file mode 100644
index 0000000..0dcd164
--- /dev/null
+++ b/docs/html/sdk/images/3.0/contacts.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/contacts_full.png b/docs/html/sdk/images/3.0/contacts_full.png
new file mode 100644
index 0000000..829ad11
--- /dev/null
+++ b/docs/html/sdk/images/3.0/contacts_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/copy.png b/docs/html/sdk/images/3.0/copy.png
new file mode 100644
index 0000000..363aa8e
--- /dev/null
+++ b/docs/html/sdk/images/3.0/copy.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/copy_full.png b/docs/html/sdk/images/3.0/copy_full.png
new file mode 100644
index 0000000..a8db8a2
--- /dev/null
+++ b/docs/html/sdk/images/3.0/copy_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/home_hero1.png b/docs/html/sdk/images/3.0/home_hero1.png
new file mode 100644
index 0000000..c81e7ef
--- /dev/null
+++ b/docs/html/sdk/images/3.0/home_hero1.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/home_hero1_full.png b/docs/html/sdk/images/3.0/home_hero1_full.png
new file mode 100644
index 0000000..e280b81
--- /dev/null
+++ b/docs/html/sdk/images/3.0/home_hero1_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/homescreen_cust_port.png b/docs/html/sdk/images/3.0/homescreen_cust_port.png
new file mode 100644
index 0000000..ef7f5ab
--- /dev/null
+++ b/docs/html/sdk/images/3.0/homescreen_cust_port.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/homescreen_cust_port_full.png b/docs/html/sdk/images/3.0/homescreen_cust_port_full.png
new file mode 100644
index 0000000..22433a3e
--- /dev/null
+++ b/docs/html/sdk/images/3.0/homescreen_cust_port_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/mail_drag.png b/docs/html/sdk/images/3.0/mail_drag.png
new file mode 100644
index 0000000..6084caa
--- /dev/null
+++ b/docs/html/sdk/images/3.0/mail_drag.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/mail_drag_full.png b/docs/html/sdk/images/3.0/mail_drag_full.png
new file mode 100644
index 0000000..f99c612
--- /dev/null
+++ b/docs/html/sdk/images/3.0/mail_drag_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/tasks.png b/docs/html/sdk/images/3.0/tasks.png
new file mode 100644
index 0000000..9e82dcb
--- /dev/null
+++ b/docs/html/sdk/images/3.0/tasks.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/tasks_full.png b/docs/html/sdk/images/3.0/tasks_full.png
new file mode 100644
index 0000000..d2a2241
--- /dev/null
+++ b/docs/html/sdk/images/3.0/tasks_full.png
Binary files differ
diff --git a/docs/html/sdk/images/3.0/widgets.png b/docs/html/sdk/images/3.0/widgets.png
new file mode 100644
index 0000000..d847666
--- /dev/null
+++ b/docs/html/sdk/images/3.0/widgets.png
Binary files differ
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 40eab1c..bfcd14e 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,21 +1,21 @@
page.title=Android SDK
sdk.redirect=0
-sdk.win_installer=installer_r08-windows.exe
-sdk.win_installer_bytes=32746192
-sdk.win_installer_checksum=04ce87b10a8361a1f63cf2238bbc1ee3
+sdk.win_installer=installer_r09-windows.exe
+sdk.win_installer_bytes=32828818
+sdk.win_installer_checksum=a0185701ac0d635a4fbf8169ac949a3c5b3d31e0
-sdk.win_download=android-sdk_r08-windows.zip
-sdk.win_bytes=32696391
-sdk.win_checksum=3e0b08ade5bfa9624bce9ddc164a48cb
+sdk.win_download=android-sdk_r09-windows.zip
+sdk.win_bytes=32779808
+sdk.win_checksum=1a1bb8fad80bcc2dfbd00443b9a13e6b
-sdk.mac_download=android-sdk_r08-mac_86.zip
-sdk.mac_bytes=28797617
-sdk.mac_checksum=d2e392c4e4680cbf2dfd6dbf82b662c7
+sdk.mac_download=android-sdk_r09-mac_x86.zip
+sdk.mac_bytes=28829553
+sdk.mac_checksum=ef3102fdbbbbd9bf4d9b572624aa9dc1
-sdk.linux_download=android-sdk_r08-linux_86.tgz
-sdk.linux_bytes=26817291
-sdk.linux_checksum=3b626645b223d137d27beefbda0c94bc
+sdk.linux_download=android-sdk_r09-linux_x86.tgz
+sdk.linux_bytes=26917824
+sdk.linux_checksum=9fefac5ff85d329836439f6e77a78cae
@jd:body
diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd
index 9de247a..7344bef 100644
--- a/docs/html/sdk/installing.jd
+++ b/docs/html/sdk/installing.jd
@@ -1,5 +1,4 @@
page.title=Installing the SDK
-sdk.preview=0
@jd:body
diff --git a/docs/html/sdk/oem-usb.jd b/docs/html/sdk/oem-usb.jd
new file mode 100644
index 0000000..14015f5
--- /dev/null
+++ b/docs/html/sdk/oem-usb.jd
@@ -0,0 +1,81 @@
+page.title=OEM USB Drivers
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/developing/device.html">Developing on a Device</a></li>
+ <li><a href="{@docRoot}sdk/win-usb.html">Google USB Driver</a></li>
+ </ol>
+</div>
+</div>
+
+<p>If you are developing on Windows and would like to connect an Android-powered device
+ to test your applications, then you need to install the appropriate USB driver. This document
+provides links to the web sites for several device original equipment manufacturers (OEMs),
+where you can download the appropriate USB driver for your device. However, this list is
+not exhaustive for all available Android-powered devices.</p>
+
+<p>If your device is one of the Android Developer Phones (ADP), a Nexus One, or a Nexus S,
+then you should instead use the <a href="{@docRoot}sdk/win-usb.html">Google USB Driver</a>.</p>
+
+<p class="note"><strong>Note:</strong> If you're developing on Mac OS X or Linux, then you probably
+ don't need to install a USB driver. Refer to <a
+ href="{@docRoot}guide/developing/device.html#setting-up">Setting up a Device</a> to start
+ development with a device.</p>
+
+<p>For instructions about how to install the driver on Windows, follow the guide for <a
+ href="{@docRoot}sdk/win-usb.html#InstallingDriver">Installing the USB Driver</a>.</p>
+
+<p class="table-caption"><strong>Table 1.</strong> Links to OEM USB drivers</p>
+<table><tr>
+ <th>OEM</th>
+ <th>Driver URL</th></tr>
+<tr><td>Acer</td> <td><a
+href="http://www.acer.com/worldwide/support/mobile.html">http://www.acer.com/worldwide/support/
+mobile.html</a>
+ </td></tr>
+
+<tr><td>Dell</td> <td>
+ <a href="http://support.dell.com/support/downloads/index.aspx?c=us&cs=19&l=en&s=dhs&~ck=anavml">http://support.dell.com/support/downloads/index.aspx?c=us&cs=19&l=en&s=dhs&~ck=anavml</a> </td></tr>
+
+<tr><td>Foxconn</td> <td><a
+href="http://drivers.cmcs.com.tw/">http://drivers.cmcs.com.tw/</a></td>
+</tr><tr><td>Garmin-Asus</td> <td><a
+href="https://www.garminasus.com/en_US/support/pcsync/">https://www.garminasus.com/en_US/support/
+pcsync/</a></td>
+</tr><tr><td>HTC</td> <td><a href="http://www.htc.com ">http://www.htc.com </a> <br>Click on the
+support tab to select your products/device. Different regions will have different links.</td>
+</tr>
+<tr><td>Huawei</td> <td><a
+href="http://www.huaweidevice.com/worldwide/downloadCenter.do?method=list&flay=software&directoryId=
+20&treeId=0">http://www.huaweidevice.com/worldwide/downloadCenter.do?method=list&flay=software&
+directoryId=20&treeId=0</a></td>
+</tr><tr><td>KT Tech</td> <td><a
+href="http://www.kttech.co.kr/cscenter/download05.asp">http://www.kttech.co.kr/cscenter/download05.
+asp</a> for EV-S100(Take)</td>
+</tr><tr><td>LGE</td> <td><a
+href="http://www.lg.com/us/mobile-phones/mobile-support/mobile-lg-mobile-phone-support.jsp">http://
+www.lg.com/us/mobile-phones/mobile-support/mobile-lg-mobile-phone-support.jsp</a></td>
+</tr><tr><td>Motorola</td> <td><a
+href="http://developer.motorola.com/docstools/USB_Drivers/">http://developer.motorola.com/docstools/
+USB_Drivers/</a></td>
+</tr><tr><td>Pantech</td> <td><a
+href="http://www.isky.co.kr/cs/software/software.sky?fromUrl=index">http://www.isky.co.kr/cs/
+software/software.sky?fromUrl=index</a></td>
+</tr><tr><td>Samsung</td> <td><a
+href="http://www.samsung.com/us/support/downloads">http://www.samsung.com/us/support/downloads</a></
+td>
+</tr><tr><td>Sharp</td> <td><a
+href="http://k-tai.sharp.co.jp/support/">http://k-tai.sharp.co.jp/support/</a></td>
+</tr><tr><td>SK Telesys</td> <td><a
+href="http://www.sk-w.com/service/wDownload/wDownload.jsp">http://www.sk-w.com/service/wDownload/
+wDownload.jsp</a></td></tr><tr>
+<td>Sony Ericsson</td> <td><a
+href="http://developer.sonyericsson.com/wportal/devworld/search-downloads/android">http://developer.
+sonyericsson.com/wportal/devworld/search-downloads/android</a></td></tr><tr>
+<td>ZTE</td> <td><a
+href="http://www.zte.com.cn/cn/products/mobile/services_support/index.jsp">http://www.zte.com.cn/cn/
+products/mobile/services_support/index.jsp</a></td></tr>
+</table>
diff --git a/docs/html/sdk/preview/index.jd b/docs/html/sdk/preview/index.jd
index 81b4ff6..edfa02b 100644
--- a/docs/html/sdk/preview/index.jd
+++ b/docs/html/sdk/preview/index.jd
@@ -1,4 +1,183 @@
-sdk.redirect=true
-
+page.title=Android 3.0 Preview SDK
@jd:body
+<p>Android 3.0 is the next major release of the Android platform and is optimized for tablet
+devices. We're offering a Preview SDK so you can get a head-start developing
+applications for it or simply optimize your existing application for upcoming
+tablets.</p>
+
+
+<h3>What is the Preview SDK?</h3>
+
+<p>The Android 3.0 Preview SDK is an early look at the upcoming version of Android 3.0, for
+developers only. </p>
+
+<p>The Preview SDK includes:</p>
+<ul>
+ <li>An early Android 3.0 system image for use in the Android emulator</li>
+ <li>An Android 3.0 library with non-final APIs</li>
+ <li>A new WXGA emulator skin for an extra large Android Virtual Device</li>
+ <li>New documentation for Android 3.0, including a complete API reference, new developer guides,
+and an API differences report between Android 3.0 and 2.3.</li>
+</ul>
+
+<div class="note">
+<p><strong>Be aware that:</strong></p>
+<ul>
+ <li>The APIs in the Preview SDK are <strong>not final</strong>. Some APIs may change in behavior
+or availability when the final SDK is made available.</li>
+ <li>You <strong>cannot</strong> publish an application that's built against the Preview
+SDK—you can only run an application built against the Preview SDK on the Android
+emulator.</li>
+ <li>The documentation on <a href="http://developer.android.com">developer.android.com</a>
+does <strong>not</strong> include the Android 3.0 documentation—to read the API reference and
+developer guides for Android 3.0, you must install the Android 3.0 Preview documentation from
+the AVD and SDK Manager.</li>
+</ul>
+</div>
+
+
+<p><b>About emulator performance</b></p>
+
+<p>Because the Android emulator must simulate the ARM instruction set architecture on your
+computer and the WXGA screen is significantly larger than what the emulator
+normally handles, emulator performance is much slower than usual. </p>
+
+<p>In particular, initializing the emulator can be slow and can take several
+minutes, depending on your hardware. When the emulator is booting there is
+limited user feedback, so please be patient and continue waiting until you see
+the home screen appear. </p>
+
+<p>We're working hard to resolve the performance issues in the emulator and it will improve in
+future releases. In the meantime, we wanted to give developers access to new APIs and an basic test
+environment as early as possible. </p>
+
+<p>Keeping in mind that performance on the emulator does not reflect the speed or performance of
+apps on actual devices running Android 3.0, developing and testing on the emulator is still an
+important tool in evaluating your application's appearance and functionality on the new platform.
+</p>
+
+
+
+
+
+<h3>What can I do with the preview?</h3>
+
+<p>The Preview SDK is intended for testing existing applications on the new platform and
+developing new applications with new Android 3.0 APIs.</p>
+
+<p>If you have an existing Android application, you don't <em>have to</em> do anything. Android
+applications are always forward-compatible. If your application is a good citizen of the Android
+APIs, your app should work fine on devices running Android 3.0 without any additional work. However,
+in order to ensure proper performance and provide users a better experience when running your
+application on an Android 3.0 tablet, we recommend that you perform the following:</p>
+
+<ol>
+ <li><b>Test your application on Android 3.0</b>
+ <p>Simply install the Android 3.0 preview in your Android SDK, create an AVD using the
+Android 3.0 system image, install your application, and run some tests.</p>
+ <p>As mentioned above, your application should perform as expected. You might, however,
+discover that your activity layouts are less than ideal on a large screen or some other aspects
+of your application don't behave the way you expect.</p>
+ </li>
+ <li><b>Inherit the new "Holographic" theme</b>
+ <p>Android 3.0 offers an updated set of UI widgets that are redesigned for use on larger screens
+such as tablets and incorporate the new holographic theme. Your existing application can inherit
+the new design simply by setting the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a>
+element's {@code android:targetSdkVersion} attribute to {@code "Honeycomb"}.</p>
+ <p>If you do not update the {@code android:targetSdkVersion} attribute and the {@code
+android:minSdkVersion} is set to "9" or lower, then your application uses the widget designs
+from Android 2.3 and does <em>not</em> inherit the holographic theme.</p>
+ <p>In order for your application to match the rest of the system UI, we highly recommend you
+make this change to inherit the new widget styles and system theme. However, beware that doing so
+might conflict with color or text designs you applied to your application based on the previous
+system theme, so you should be sure to inspect your application UI when using the holographic
+theme.</p>
+ </li>
+ <li><b>Provide alternative layouts for extra large screens</b>
+ <p>As discussed in the guide to <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>, Android
+2.3 and above support the <code>xlarge</code> resource qualifier, which you should use to supply
+alternative layouts for extra large screens.</p>
+ <p>By providing alternative layouts for some of your activities when running on extra large
+screens, you can improve the user experience of your application on a tablet without using any
+new APIs.</p>
+ <p>For example, here are some things to consider when creating a new layout for tables:</p>
+ <ul>
+ <li>Landscape layout: The "normal" orientation for tablets is usually landscape (wide), so
+you should be sure that your activities offer an appropriate layout for such a wide viewing
+area.</li>
+ <li>Button position: Consider whether the position of the most common buttons in your UI are
+easily accessible while holding a tablet with two hands.</li>
+ </ul>
+ <p class="note"><strong>Note:</strong> You can add alternative resources for <em>xlarge</em>
+screens without changing your {@code minSdkVersion}. For example, if you add alternative layouts in
+<code>res/layout-xlarge/</code> and your application is compatible with older versions, such
+as Android 1.5—which doesn't support <em>xlarge</em> screens—this layout directory is
+simply ignored by those devices.</p>
+ </li>
+</ol>
+
+
+<p>Otherwise, if you want to develop a new application or upgrade your existing application to
+use APIs added in Android 3.0, we encourage you to get started by developing against the Android
+3.0 preview platform. You can get started the same way as you would for any other version of
+Android.</p>
+
+
+<p>To get started—whether testing an existing application or creating a new one—follow
+the procedure in the following section to install the Preview SDK.</p>
+
+
+
+<h3 id="Setup">How do I get it?</h3>
+
+<p>To get the Preview SDK, you can download it using the Android SDK and AVD Manager.</p>
+
+<p>If you're new to Android development, start by <a href="{@docRoot}sdk/index.html">downloading the
+Android SDK starter package</a>.</p>
+
+<p><a href="{@docRoot}sdk/adding-components.html#launching">Launch the Android SDK and AVD
+Manager</a> and install the following:</p>
+<ul>
+ <li>SDK Platform Android Honeycomb Preview</li>
+ <li>Android SDK Tools, revision 9</li>
+ <li>Android SDK Platform-tools, revision 2</li>
+ <li>Documentation for Android 'Honeycomb' Preview</li>
+ <li>Samples for SDK API Honeycomb Preview</li>
+</ul>
+
+<p class="note"><strong>Note:</strong> Be sure to install the documentation component for the
+Honeycomb Preview SDK. The API reference for the Android 3.0 API is <strong>not</strong> available
+online.</p>
+
+<p>Once you have installed these components, open your SDK directory and navigate to {@code
+docs/sdk/} and open {@code index.html} in your browser. </p>
+
+
+
+<h3 id="Issues">Known issues</h3>
+
+<p>The following known issues occur for Android 3.0 AVDs that are loaded in the emulator:</p>
+
+<ul>
+ <li>The emulator displays a rotated portrait screen while in landscape
+orientation. To view the screen correctly in landscape orientation, turn off the auto-rotate setting
+in <strong>Settings > Screen > Auto-rotate screen</strong>. Then use Ctrl-F11 to rotate the
+emulator.</li>
+ <li>You cannot take screenshots of an emulator screen. The Device Screen Capture window displays
+<strong>Screen not available</strong>.</li>
+ <li>GPS emulation is currently not supported.</li>
+ <li>When rotating the emulator screen by pressing Ctrl-F11, the screen turns green momentarily,
+then displays the normal interface.</li>
+ <li>The Dev Tools application sometimes crashes when trying to use the Package Browser
+feature.</li>
+</ul>
+
+
+<div class="special">
+ <p>For an overview of new features in Android 3.0, read the <a
+href="{@docRoot}sdk/android-3.0-highlights.html">Platform Highlights</a>.</p>
+</div>
+
diff --git a/docs/html/sdk/requirements.jd b/docs/html/sdk/requirements.jd
index 401dfe3..3d62dd9 100644
--- a/docs/html/sdk/requirements.jd
+++ b/docs/html/sdk/requirements.jd
@@ -10,8 +10,8 @@
<li>Mac OS X 10.5.8 or later (x86 only)</li>
<li>Linux (tested on Ubuntu Linux, Lucid Lynx)
<ul>
- <li>GNU C Library (glibc) 2.11 or later is required.</li>
- <li>On Ubuntu Linux, Lucid Lynx or later release is required.</li>
+ <li>GNU C Library (glibc) 2.7 or later is required.</li>
+ <li>On Ubuntu Linux, version 8.04 or later is required.</li>
<li>64-bit distributions must be capable of running 32-bit applications.
For information about how to add support for 32-bit applications, see
the <a href="installing.html#troubleshooting">Ubuntu Linux
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 7e677e3..3358cf0 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -37,6 +37,16 @@
</ul>
</li><?cs
/if ?>
+ <?cs
+ if:sdk.preview ?>
+ <li><h2>Android 3.0 Preview</h2>
+ <ul>
+ <li><a href="<?cs var:toroot ?>sdk/android-3.0-highlights.html">Platform Highlights</a> <span
+class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/preview/index.html">SDK</a> <span class="new">new!</span></li>
+ </ul>
+ </li><?cs
+ /if ?>
<li>
<h2>
<span class="en">Downloadable SDK Components</span>
@@ -63,7 +73,7 @@
<ul>
<li class="toggle-list">
<div><a href="<?cs var:toroot ?>sdk/android-2.3.html">
- <span class="en">Android 2.3 Platform</span></a> <span class="new">new!</span></div>
+ <span class="en">Android 2.3 Platform</span></a></div>
<ul>
<li><a href="<?cs var:toroot ?>sdk/android-2.3-highlights.html">Platform Highlights</a></li>
<li><a href="<?cs var:toroot ?>sdk/api_diff/9/changes.html">API Differences Report »</a></li>
@@ -83,10 +93,8 @@
</li>
</ul>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r8</a> <span class="new">new!</span></li>
- <li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for
- Windows, r4</a> <span class="new">new!</span>
- </li>
+ <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r9</a> <span class="new">new!</span></li>
+ <li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a></li>
</ul>
</li>
<li>
@@ -101,7 +109,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 8.0.1
+ <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 9.0.0
<span style="display:none" class="de"></span>
<span style="display:none" class="es"></span>
<span style="display:none" class="fr"></span>
@@ -123,7 +131,7 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r5</a>
+ <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r5b</a>
<span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>sdk/ndk/overview.html">What is the NDK?</a></li>
</ul>
@@ -141,11 +149,11 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
+ <li><a href="<?cs var:toroot ?>sdk/oem-usb.html">
+ <span class="en">OEM USB Drivers</span>
+ </a></li>
<li><a href="<?cs var:toroot ?>sdk/requirements.html">SDK System Requirements</a></li>
- <!-- <li><a href="<?cs var:toroot ?>sdk/RELEASENOTES.html">SDK Release
- Notes</a></li> -->
- <li><a href="<?cs var:toroot ?>sdk/older_releases.html">SDK
- Archives</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/older_releases.html">SDK Archives</a></li>
</ul>
</li>
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index f8d7071..d188bc5 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -15,6 +15,7 @@
href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK
Components</a>. </p>
+
<h2 id="notes">Revisions</h2>
<p>The sections below provide notes about successive releases of
@@ -64,6 +65,63 @@
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 9</a> <em>(January 2011)</em>
+ <div class="toggleme">
+ <dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that the SDK Tools r9 is
+designed for use with ADT 9.0.0 and later. After installing SDK Tools r9, we
+highly recommend updating your ADT Plugin to 9.0.0.</p>
+
+<p>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
+Ant</a> 1.8 or later.</p>
+
+<dt>Upgrading to SDK Tools r9:</dt>
+<dd>
+<p>If you are upgrading to SDK Tools r9 from SDK Tools r7 or earlier, the default installed location
+for the <code>adb</code> tool has changed from <code><<em>SDK</em>>/tools/adb</code> to
+<code><<em>SDK</em>>/platform-tools/adb</code>. This means that you should
+add the new location to your PATH and modify any custom build scripts to
+reference the new location. Copying the <code>adb</code> executable from the new
+location to the old is not recommended, since subsequent updates to the SDK
+Tools will delete the file.</p>
+</dd>
+
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>The default ProGuard configuration, <code>proguard.cfg</code>, now ignores the following classes:
+ <ul>
+ <li>classes that extend {@link android.preference.Preference}</li>
+ <li>classes that extend {@link android.app.backup.BackupAgentHelper}</li>
+ </ul>
+ </li>
+ <li>Ant lib rules now allow you to override <code>java.encoding</code>, <code>java.source</code>,
+ and <code>java.target</code> properties.</li>
+ <li>The default encoding for the <code>javac</code> Ant task is now UTF-8.</li>
+ <li>The LogCat view in DDMS now properly displays UTF-8 characters.</li>
+ <li>The SDK Manager is more reliable on Windows. For details on the improvements, see the
+ <a href="http://tools.android.com/recent/sdkmanagerfixes">Android Tools Project Site</a>. </li>
+ <li>Early look at the new snapshot feature: To improve startup time for the emulator, you can
+enable snapshots for the system state. The emulator will then restore to the state when it last
+closed almost instantly. <strong>Note:</strong> The snapshot feature is still under active
+development and might not always perform as expected.</li>
+ <li>Fixed the missing JAR file error that prevented <code>draw9patch</code> from running.</li>
+ <li>Fixed the Windows launch scripts <code>hierarchyviewer</code> and <code>ddms</code> to support
+ the new location of <code>adb</code>.</li>
+ <li>Known issues with emulator performance: Because the Android emulator must simulate the ARM
+instruction set architecture on your computer, emulator performance is slow. We're working hard to
+resolve the performance issues and it will improve in future releases.</li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" />
SDK Tools, Revision 8</a> <em>(December 2010)</em>
<div class="toggleme">
diff --git a/docs/html/sdk/win-usb.jd b/docs/html/sdk/win-usb.jd
index 1f74ffe..ffaec4c 100644
--- a/docs/html/sdk/win-usb.jd
+++ b/docs/html/sdk/win-usb.jd
@@ -1,4 +1,4 @@
-page.title=USB Driver for Windows
+page.title=Google USB Driver
@jd:body
<div id="qv-wrapper">
@@ -6,27 +6,48 @@
<h2>In this document</h2>
<ol>
<li><a href="#notes">Revisions</a></li>
- <li><a href="#WinUsbDriver">Installing the USB Driver for Windows</a></li>
+ <li><a href="#WinUsbDriver">Downloading the Google USB Driver</a></li>
+ <li><a href="#InstallingDriver">Installing the USB Driver</a>
+ <ol>
+ <li><a href="#Win7">Windows 7</a></li>
+ <li><a href="#WinXp">Windows XP</a></li>
+ <li><a href="#WinVista">Windows Vista</a></li>
+ </ol>
+ </li>
</ol>
<h2>See also</h2>
<ol>
- <li><a
- href="{@docRoot}guide/developing/device.html">Developing on a
- Device</a></li>
- <li><a
- href="adding-components.html">Adding SDK Components</a></li>
+ <li><a href="{@docRoot}guide/developing/device.html">Developing on a Device</a></li>
+ <li><a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a></li>
+ <li><a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a></li>
</ol>
</div>
</div>
-<p>The USB driver for Windows is a downloadable component for the
-Android SDK. If you are developing on Windows and would like to
-connect an Android-powered device to test your applications, then you will need
-to install the USB driver.</p>
+<p>The Google USB driver is a downloadable component for Windows developers, available
+for download from the AVD and SDK Manager.</p>
-<p>This document provides information about the latest version of the
-USB driver and a guide to installing the driver on your development
-computer.</p>
+<p>The Google USB Driver is only for Android Developer Phones (ADP), Nexus One, and Nexus S.
+If you're using a different Android-powered device,
+then you need to get a USB driver from the device OEM. For help finding the appropriate
+driver, see the list of <a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a>.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <p>The Google USB driver for Windows provides support for the following
+Android-powered devices:</p>
+ <ul>
+ <li>ADP1 / T-Mobile G1*</li>
+ <li>ADP2 / Google Ion / T-Mobile myTouch 3G*</li>
+ <li>Verizon Droid*</li>
+ <li>Nexus One</li>
+ <li>Nexus S</li>
+ </ul>
+ <p>* <em>Or similar hardware on other carriers</em></p>
+ <p>Any additional devices will require Windows drivers provided by
+the hardware manufacturer. See <a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a>.</p>
+</div>
+</div>
<p class="note"><strong>Note:</strong>
If you're developing on Mac OS X or Linux, then you do not need to install a
@@ -34,6 +55,12 @@
href="{@docRoot}guide/developing/device.html#setting-up">Setting up a
Device</a> to start development with a device.</p>
+<p>The sections below provide instructions on how to download the USB Driver
+for Windows and install it on your development computer. </p>
+
+
+
+
<h2 id="notes">Revisions</h2>
<p>The sections below provide notes about successive revisions of the USB Driver
@@ -132,77 +159,49 @@
</div>
</div>
-<h2 id="WinUsbDriver">Installing the USB Driver for Windows</h2>
-<div class="sidebox-wrapper">
-<div class="sidebox">
- <p>The USB driver for Windows provides support for the following
-Android-powered
-devices:</p>
- <ul>
- <li>ADP1 / T-Mobile G1*</li>
- <li>ADP2 / Google Ion / T-Mobile myTouch 3G*</li>
- <li>Verizon Droid*</li>
- <li>Nexus One</li>
- <li>Nexus S</li>
- </ul>
- <p>* <em>Or similar hardware on other carriers</em></p>
- <p>Any additional devices will require Windows drivers provided by
-the hardware manufacturer.</p>
+<h2 id="WinUsbDriver">Downloading the Google USB Driver</h2>
+
+<div class="figure" style="width:498px;margin:0">
+ <img src="{@docRoot}images/developing/sdk-usb-driver.png" alt="" />
+ <p class="img-caption"><strong>Figure 1.</strong> The SDK and AVD Manager
+ with the Google USB Driver selected.</p>
</div>
-</div>
-
-
-<p>The sections below provide instructions on how to download the USB Driver
-for Windows and install it on your development computer. </p>
-
-<h3>Downloading the USB Driver for Windows</h3>
<p>The USB Driver for Windows is available for download as an optional SDK
component. You need the driver only if you are developing on Windows and
-want to connect an Android-powered device to your development environment
-over USB. </p>
-
-<p>To install the driver or upgrade your existing driver to the latest
-revision, you must first download the driver to your development computer. </p>
+want to connect an Android-powered device (ADP, Nexus One, or Nexus S) to your
+development environment over USB. </p>
<p>To download the driver, use the Android SDK and AVD Manager tool that is
-included with the Android SDK. If you haven't yet installed the Android SDK, as
-described in <a href="installing.html">Installing the Android SDK</a>, please do
-so before continuing with the driver installation. </p>
+included with the <a href="{@docRoot}sdk/index.html">Android SDK</a>:</p>
+<ol>
+ <li>Launch the SDK and AVD Manager by double-clicking <code>SDK Manager.exe</code>,
+ at the root of your SDK directory.</li>
+ <li>Expand the <em>Third party Add-ons</em> and <em>Google Inc. add-ons</em>.</li>
+ <li>Check <strong>Google Usb Driver package</strong> and click <strong>Install selected</strong>.</li>
+ <li>Proceed to install the package. When done, the driver files are
+downloaded into the <code><sdk>\google-usb_driver\</code> directory.</li>
+</ol>
-<p>When you are ready to download the driver, follow the instructions given in
-<a href="adding-components.html">Adding SDK Components</a> to launch the Android
-SDK and AVD Manager. From the <strong>Available Packages</strong> panel, select
-"Usb Driver Package" and download it to your computer. The driver files are
-downloaded into the <code><sdk>\google-usb_driver\</code> directory.</p>
-<p>After the download, follow the instructions below to install or upgrade the
-driver, based on your needs and Windows operating system version. If you are
-connecting an Android-powered device to your computer for the first time, follow
-the below procedure to "Perform a fresh installation." If you have installed one
-of the older USB drivers and would like to upgrade to the latest version, follow
-the procedure to "Upgrade an existing driver."</p>
-<p>Once you've completed the USB driver installation,
-please see <a
+<h2 id="InstallingDriver">Installing the USB Driver</h2>
+
+<p>Once you've downloaded your USB driver, follow the instructions below to install or upgrade the
+driver, based on your version of Windows and whether you're installing for the first time
+or upgrading an existing driver.</p>
+
+<p class="note"><strong>Tip:</strong> When you finish the USB driver installation,
+see <a
href="{@docRoot}guide/developing/device.html">Developing on a Device</a> for
other important information about using an Android-powered device for
development.</p>
<ol class="nolist">
- <li><strong>Windows Vista:</strong>
- <ol class="nolist">
- <li><a href="#VistaFreshInstall">Perform a fresh installation</a></li>
- <li><a href="#VistaUpgrade">Upgrade an existing driver</a></li>
- </ol>
- </li>
- <li><strong>Windows XP:</strong>
- <ol class="nolist">
- <li><a href="#XPFreshInstall">Perform a fresh installation</a></li>
- <li><a href="#XPUpgrade">Upgrade an existing driver</a></li>
- </ol>
- </li>
+ <li><a href="#Win7">Windows 7</a></li>
+ <li><a href="#WinXp">Windows XP</a></li>
+ <li><a href="#WinVista">Windows Vista</a></li>
</ol>
@@ -213,94 +212,140 @@
driver. Making any other changes to the driver files may break the installation
process.</p>
-<h3 id="VistaFreshInstall">Windows Vista: Perform a fresh installation</h3>
-<p>To install the Android USB driver on Windows Vista for the first time:</p>
+<h3 id="Win7">Windows 7</h3>
+
+<p>To install the Android USB driver on Windows 7 for the first time:</p>
<ol>
- <li>Connect your Android-powered device to your computer's USB port. Windows
- will detect the device and launch the Found New Hardware wizard.</li>
- <li>Select "Locate and install driver software."</li>
- <li>Select "Don't search online."</li>
- <li>Select "I don't have the disk. Show me other options."</li>
- <li>Select "Browse my computer for driver software."</li>
- <li>Click "Browse..." and locate the folder where you copied the
- installation package. As long as you specified the exact location of the
- installation package, you may leave "Include subfolders" checked or
- unchecked—it doesn't matter.</li>
- <li>Click "Next." Vista may prompt you to confirm the privilege elevation
- required for driver installation. Confirm it.</li>
- <li>When Vista asks if you'd like to install the Google ADB Interface device,
- click "Install" to install the driver.</li>
+ <li>Connect your Android-powered device to your computer's USB port.</li>
+ <li>Right-click on <em>Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Devices</strong> in the left pane.</li>
+ <li>Locate and expand <em>Other device</em> in the right pane.</li>
+ <li>Right-click the device name (such as <em>Nexus S</em>) and select <strong>Update
+ Driver Software</strong>.
+ This will launch the Hardware Update Wizard.</li>
+ <li>Select <strong>Browse my computer for driver software</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to install the driver.</li>
</ol>
-
-<h3 id="VistaUpgrade">Windows Vista: Upgrade an existing driver</h3>
-
-<p>To upgrade an existing Android USB driver on Windows Vista with the new
+<p>Or, to <em>upgrade</em> an existing Android USB driver on Windows 7 with the new
driver:</p>
<ol>
<li>Connect your Android-powered device to your computer's USB port.</li>
- <li>Right-click on "Computer" from your desktop or Windows Explorer,
- and select "Manage."</li>
- <li>Select "Device Manager" in the left pane of the Computer Management
+ <li>Right-click on <em>Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Device Manager</strong> in the left pane of the Computer Management
window.</li>
- <li>Locate and expand "ADB Interface" in the right pane.</li>
- <li>Right-click on "HTC Dream Composite ADB Interface", and select "Update
- Driver Software..."</li>
- <li>When Vista starts updating the driver, a prompt will ask how you want to
- search for the driver
- software. Select "Browse my computer for driver software."</li>
- <li>Click "Browse..." and locate the folder where you copied the
- installation package. As long as you specified the exact location of the
- installation package, you may leave "Include subfolders" checked or
- unchecked—it doesn't matter.</li>
- <li>Click "Next." Vista may prompt you to confirm the privilege elevation
- required for driver installation. Confirm it.</li>
- <li>When Vista asks if you'd like to install the Google ADB Interface device,
- click "Install" to install the driver.</li>
+ <li>Locate and expand <em>Android Phone</em> in the right pane.</li>
+ <li>Right-click <em>Android Composite ADB Interface</em> and select <strong>Update
+ Driver</strong>.
+ This will launch the Hardware Update Wizard.</li>
+ <li>Select <strong>Install from a list or specific location</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Select <strong>Search for the best driver in these locations</strong>; un-check
+<strong>Search removable media</strong>; and check <strong>Include this location in the
+search</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to upgrade the driver.</li>
</ol>
-<h3 id="XPFreshInstall">Windows XP: Perform a fresh installation</h3>
+
+
+
+<h3 id="WinXp">Windows XP</h3>
<p>To install the Android USB driver on Windows XP for the first time:</p>
<ol>
<li>Connect your Android-powered device to your computer's USB port. Windows
will detect the device and launch the Hardware Update Wizard.</li>
- <li>Select "Install from a list or specific location" and click
- "Next."</li>
- <li>Select "Search for the best driver in these locations"; un-check "Search
- removable media"; and check "Include this location in the search."</li>
- <li>Click "Browse..." and locate the folder where you copied the installation
- package.</li>
- <li>Click "Next" to install the driver.</li>
+ <li>Select <strong>Install from a list or specific location</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Select <strong>Search for the best driver in these locations</strong>; un-check
+<strong>Search
+ removable media</strong>; and check <strong>Include
+this location in the search</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to install the driver.</li>
</ol>
-
-<h3 id="XPUpgrade">Windows XP: Upgrade an existing driver</h3>
-
-<p>To upgrade an existing Android USB driver on Windows XP with the new
+<p>Or, to <em>upgrade</em> an existing Android USB driver on Windows XP with the new
driver:</p>
<ol>
<li>Connect your Android-powered device to your computer's USB port.</li>
- <li>Right-click on "My Computer" from your desktop or Windows Explorer,
- and select "Manage."</li>
- <li>Select "Device Manager" in the left pane of the Computer Management
- window.</li>
- <li>Locate and expand "Android Phone" in the right pane.</li>
- <li>Right-click "Android Composite ADB Interface" and select "Update
- Driver..."
+ <li>Right-click on <em>My Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Device Manager</strong> in the left pane.</li>
+ <li>Locate and expand <em>Android Phone</em> in the right pane.</li>
+ <li>Right-click <em>Android Composite ADB Interface</em> and select <strong>Update
+ Driver</strong>.
This will launch the Hardware Update Wizard.</li>
- <li>Select "Install from a list or specific location" and click
- "Next."</li>
- <li>Select "Search for the best driver in these locations"; un-check "Search
- removable media"; and check "Include this location in the search."</li>
- <li>Click "Browse..." and locate the folder where you copied the installation
- package.</li>
- <li>Click "Next" to install the driver.</li>
+ <li>Select <strong>Install from a list or specific location</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Select <strong>Search for the best driver in these locations</strong>; un-check <strong>Search
+ removable media</strong>; and check <strong>Include
+this location in the search</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to upgrade the driver.</li>
+</ol>
+
+
+
+<h3 id="WinVista">Windows Vista</h3>
+
+<p>To install the Android USB driver on Windows Vista for the first time:</p>
+
+<ol>
+ <li>Connect your Android-powered device to your computer's USB port. Windows
+ will detect the device and launch the Found New Hardware wizard.</li>
+ <li>Select <strong>Locate and install driver software</strong>.</li>
+ <li>Select <strong>Don't search online</strong>.</li>
+ <li>Select <strong>I don't have the disk. Show me other options</strong>.</li>
+ <li>Select <strong>Browse my computer for driver software</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.) As long as you specified the exact
+location of the
+ installation package, you may leave <strong>Include subfolders</strong> checked or
+ unchecked—it doesn't matter.</li>
+ <li>Click <strong>Next</strong>. Vista may prompt you to confirm the privilege elevation
+ required for driver installation. Confirm it.</li>
+ <li>When Vista asks if you'd like to install the Google ADB Interface device,
+ click <strong>Install</strong> to install the driver.</li>
+</ol>
+
+<p>Or, to <em>upgrade</em> an existing Android USB driver on Windows Vista with the new
+driver:</p>
+
+<ol>
+ <li>Connect your Android-powered device to your computer's USB port.</li>
+ <li>Right-click on <em>Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Device Manager</strong> in the left pane.</li>
+ <li>Locate and expand <em>ADB Interface</em> in the right pane.</li>
+ <li>Right-click on <em>HTC Dream Composite ADB Interface</em>, and select <strong>Update
+ Driver Software</strong>.</li>
+ <li>When Vista starts updating the driver, a prompt will ask how you want to
+ search for the driver
+ software. Select <strong>Browse my computer for driver software</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.) As long as you specified the
+exact location of the
+ installation package, you may leave <strong>Include subfolders</strong> checked or
+ unchecked—it doesn't matter.</li>
+ <li>Click <strong>Next</strong>. Vista might prompt you to confirm the privilege elevation
+ required for driver installation. Confirm it.</li>
+ <li>When Vista asks if you'd like to install the Google ADB Interface device,
+ click <strong>Install</strong> to upgrade the driver.</li>
</ol>
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 9fd905f..e881747 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -156,6 +156,7 @@
MODE_NORMAL = 0,
MODE_RINGTONE,
MODE_IN_CALL,
+ MODE_IN_COMMUNICATION,
NUM_MODES // not a valid entry, denotes end-of-list
};
@@ -466,7 +467,7 @@
AudioParameter(const String8& keyValuePairs);
virtual ~AudioParameter();
- // reserved parameter keys for changeing standard parameters with setParameters() function.
+ // reserved parameter keys for changing standard parameters with setParameters() function.
// Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
// configuration changes and act accordingly.
// keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices
@@ -474,11 +475,14 @@
// keyFormat: to change audio format, value is an int in AudioSystem::audio_format
// keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels
// keyFrameCount: to change audio output frame count, value is an int
+ // keyInputSource: to change audio input source, value is an int in audio_source
+ // (defined in media/mediarecorder.h)
static const char *keyRouting;
static const char *keySamplingRate;
static const char *keyFormat;
static const char *keyChannels;
static const char *keyFrameCount;
+ static const char *keyInputSource;
String8 toString();
diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h
index 16fb43c..b97c22e 100644
--- a/include/media/EffectApi.h
+++ b/include/media/EffectApi.h
@@ -602,9 +602,9 @@
// Audio mode
enum audio_mode_e {
- AUDIO_MODE_NORMAL, // phone idle
- AUDIO_MODE_RINGTONE, // phone ringing
- AUDIO_MODE_IN_CALL // phone call connected
+ AUDIO_MODE_NORMAL, // device idle
+ AUDIO_MODE_RINGTONE, // device ringing
+ AUDIO_MODE_IN_CALL // audio call connected (VoIP or telephony)
};
// Values for "accessMode" field of buffer_config_t:
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 5ab1640..9a76393 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -44,7 +44,8 @@
AUDIO_SOURCE_VOICE_CALL = 4,
AUDIO_SOURCE_CAMCORDER = 5,
AUDIO_SOURCE_VOICE_RECOGNITION = 6,
- AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_RECOGNITION,
+ AUDIO_SOURCE_VOICE_COMMUNICATION = 7,
+ AUDIO_SOURCE_MAX = AUDIO_SOURCE_VOICE_COMMUNICATION,
AUDIO_SOURCE_LIST_END // must be last - used to validate audio source type
};
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index d6ae5e9..4ae3cdf 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -105,7 +105,7 @@
volatile int32_t head; // server's current front buffer
volatile int32_t available; // number of dequeue-able buffers
volatile int32_t queued; // number of buffers waiting for post
- volatile int32_t inUse; // buffer currently in use by SF
+ volatile int32_t reserved1;
volatile status_t status; // surface's status code
// not part of the conditions
@@ -275,7 +275,6 @@
int32_t identity);
ssize_t retireAndLock();
- status_t unlock(int buffer);
void setStatus(status_t status);
status_t reallocateAll();
status_t reallocateAllExcept(int buffer);
@@ -346,11 +345,6 @@
int mNumBuffers;
BufferList mBufferList;
- struct UnlockUpdate : public UpdateBase {
- const int lockedBuffer;
- inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
- inline ssize_t operator()();
- };
struct RetireUpdate : public UpdateBase {
const int numBuffers;
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 22684db8..7b2a7f5 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -248,7 +248,7 @@
uint32_t *pWidth, uint32_t *pHeight,
uint32_t *pFormat, uint32_t *pUsage) const;
- static void cleanCachedSurfaces();
+ static void cleanCachedSurfacesLocked();
class BufferInfo {
uint32_t mWidth;
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index 4bc5d9e..b45e43f 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -58,7 +58,6 @@
void SharedBufferStack::init(int32_t i)
{
- inUse = -2;
status = NO_ERROR;
identity = i;
}
@@ -199,9 +198,9 @@
SharedBufferStack& stack( *mSharedStack );
snprintf(buffer, SIZE,
"%s[ head=%2d, available=%2d, queued=%2d ] "
- "reallocMask=%08x, inUse=%2d, identity=%d, status=%d",
+ "reallocMask=%08x, identity=%d, status=%d",
prefix, stack.head, stack.available, stack.queued,
- stack.reallocMask, stack.inUse, stack.identity, stack.status);
+ stack.reallocMask, stack.identity, stack.status);
result.append(buffer);
result.append("\n");
return result;
@@ -261,8 +260,7 @@
// NOTE: if stack.head is messed up, we could crash the client
// or cause some drawing artifacts. This is okay, as long as it is
// limited to the client.
- return (buf != stack.index[stack.head] ||
- (stack.queued > 0 && stack.inUse != buf));
+ return (buf != stack.index[stack.head]);
}
// ----------------------------------------------------------------------------
@@ -295,22 +293,6 @@
return NO_ERROR;
}
-SharedBufferServer::UnlockUpdate::UnlockUpdate(
- SharedBufferBase* sbb, int lockedBuffer)
- : UpdateBase(sbb), lockedBuffer(lockedBuffer) {
-}
-ssize_t SharedBufferServer::UnlockUpdate::operator()() {
- if (stack.inUse != lockedBuffer) {
- LOGE("unlocking %d, but currently locked buffer is %d "
- "(identity=%d, token=%d)",
- lockedBuffer, stack.inUse,
- stack.identity, stack.token);
- return BAD_VALUE;
- }
- android_atomic_write(-1, &stack.inUse);
- return NO_ERROR;
-}
-
SharedBufferServer::RetireUpdate::RetireUpdate(
SharedBufferBase* sbb, int numBuffers)
: UpdateBase(sbb), numBuffers(numBuffers) {
@@ -320,9 +302,6 @@
if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
return BAD_VALUE;
- // Preventively lock the current buffer before updating queued.
- android_atomic_write(stack.headBuf, &stack.inUse);
-
// Decrement the number of queued buffers
int32_t queued;
do {
@@ -338,7 +317,6 @@
head = (head + 1) % numBuffers;
const int8_t headBuf = stack.index[head];
stack.headBuf = headBuf;
- android_atomic_write(headBuf, &stack.inUse);
// head is only modified here, so we don't need to use cmpxchg
android_atomic_write(head, &stack.head);
@@ -542,13 +520,6 @@
return buf;
}
-status_t SharedBufferServer::unlock(int buf)
-{
- UnlockUpdate update(this, buf);
- status_t err = updateCondition( update );
- return err;
-}
-
void SharedBufferServer::setStatus(status_t status)
{
if (status < NO_ERROR) {
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 854a3c6..017e94c 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -377,7 +377,7 @@
Mutex Surface::sCachedSurfacesLock;
-DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces(wp<Surface>(0));
+DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces;
sp<Surface> Surface::readFromParcel(const Parcel& data) {
Mutex::Autolock _l(sCachedSurfacesLock);
@@ -390,13 +390,13 @@
if (surface->mSurface == 0) {
surface = 0;
}
- cleanCachedSurfaces();
+ cleanCachedSurfacesLocked();
return surface;
}
// Remove the stale entries from the surface cache. This should only be called
// with sCachedSurfacesLock held.
-void Surface::cleanCachedSurfaces() {
+void Surface::cleanCachedSurfacesLocked() {
for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
wp<Surface> s(sCachedSurfaces.valueAt(i));
if (s == 0 || s.promote() == 0) {
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index fa46ab7..9847a5f 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -63,7 +63,7 @@
const size_t c = list.size();
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
list.keyAt(i), rec.size/1024.0f,
rec.w, rec.s, rec.h, rec.format, rec.usage);
result.append(buffer);
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index bbbba74..4459505 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -966,9 +966,14 @@
*/
public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE;
/**
- * In call audio mode. A call is established.
+ * In call audio mode. A telephony call is established.
*/
public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL;
+ /**
+ * @hide
+ * In communication audio mode. An audio/video chat or VoIP call is established.
+ */
+ public static final int MODE_IN_COMMUNICATION = AudioSystem.MODE_IN_COMMUNICATION;
/* Routing bits for setRouting/getRouting API */
/**
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index c48eaad..0eb39db 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -252,7 +252,8 @@
//--------------
// audio source
if ( (audioSource < MediaRecorder.AudioSource.DEFAULT) ||
- (audioSource > MediaRecorder.getAudioSourceMax()) ) {
+ (audioSource > MediaRecorder.AudioSource.VOICE_COMMUNICATION) ) {
+ //(audioSource > MediaRecorder.getAudioSourceMax()) ) {
throw (new IllegalArgumentException("Invalid audio source."));
} else {
mRecordSource = audioSource;
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 41d2cc5..06e00c5 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -708,7 +708,7 @@
return;
}
- if (mode < AudioSystem.MODE_CURRENT || mode > AudioSystem.MODE_IN_CALL) {
+ if (mode < AudioSystem.MODE_CURRENT || mode >= AudioSystem.NUM_MODES) {
return;
}
@@ -2259,6 +2259,7 @@
// add modify the phone app to take advantage of the new API
synchronized(mRingingLock) {
if (mIsRinging || (getMode() == AudioSystem.MODE_IN_CALL) ||
+ (getMode() == AudioSystem.MODE_IN_COMMUNICATION) ||
(getMode() == AudioSystem.MODE_RINGTONE) ) {
return;
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index a4818ff..4ddbb35 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -106,7 +106,8 @@
public static final int MODE_NORMAL = 0;
public static final int MODE_RINGTONE = 1;
public static final int MODE_IN_CALL = 2;
- public static final int NUM_MODES = 3;
+ public static final int MODE_IN_COMMUNICATION = 3;
+ public static final int NUM_MODES = 4;
/* Routing bits for setRouting/getRouting API */
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 32c02bc..d9f2302 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -145,6 +145,15 @@
/** Microphone audio source tuned for voice recognition if available, behaves like
* {@link #DEFAULT} otherwise. */
public static final int VOICE_RECOGNITION = 6;
+
+ /**
+ * @hide
+ * Microphone audio source tuned for voice communications such as VoIP. It
+ * will for instance take advantage of echo cancellation or automatic gain control
+ * if available. It otherwise behaves like {@link #DEFAULT} if no voice processing
+ * is available.
+ */
+ public static final int VOICE_COMMUNICATION = 7;
}
/**
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 9c2a8ba..1a3fcd6 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -835,6 +835,7 @@
const char *AudioParameter::keyFormat = "format";
const char *AudioParameter::keyChannels = "channels";
const char *AudioParameter::keyFrameCount = "frame_count";
+const char *AudioParameter::keyInputSource = "input_source";
AudioParameter::AudioParameter(const String8& keyValuePairs)
{
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index a660429..43571cf 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -219,8 +219,13 @@
}
for (uint32_t i = 0; i < mCaptureSize; i += 2) {
- fft[i] = workspace[i >> 1] >> 24;
- fft[i + 1] = workspace[i >> 1] >> 8;
+ short tmp = workspace[i >> 1] >> 21;
+ while (tmp > 127 || tmp < -128) tmp >>= 1;
+ fft[i] = tmp;
+ tmp = workspace[i >> 1];
+ tmp >>= 5;
+ while (tmp > 127 || tmp < -128) tmp >>= 1;
+ fft[i + 1] = tmp;
}
return NO_ERROR;
diff --git a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
index 0f08f6e..dcf129e 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
@@ -23,8 +23,8 @@
#include "mp4dec_api.h"
#include <OMX_Component.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
@@ -106,7 +106,7 @@
int32_t vol_size = 0;
if (meta->findData(kKeyESDS, &type, &data, &size)) {
ESDS esds((const uint8_t *)data, size);
- CHECK_EQ(esds.InitCheck(), OK);
+ CHECK_EQ(esds.InitCheck(), (status_t)OK);
const void *codec_specific_data;
size_t codec_specific_data_size;
@@ -132,7 +132,7 @@
}
MP4DecodingMode actualMode = PVGetDecBitstreamMode(mHandle);
- CHECK_EQ(mode, actualMode);
+ CHECK_EQ((int)mode, (int)actualMode);
PVSetPostProcType((VideoDecControls *) mHandle, 0);
@@ -182,7 +182,7 @@
ReadOptions::SeekMode mode;
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
seeking = true;
- CHECK_EQ(PVResetVideoDecoder(mHandle), PV_TRUE);
+ CHECK_EQ((int)PVResetVideoDecoder(mHandle), PV_TRUE);
}
MediaBuffer *inputBuffer = NULL;
@@ -220,19 +220,26 @@
return UNKNOWN_ERROR;
}
- int32_t width, height;
- PVGetVideoDimensions(mHandle, &width, &height);
- if (width != mWidth || height != mHeight) {
+ int32_t disp_width, disp_height;
+ PVGetVideoDimensions(mHandle, &disp_width, &disp_height);
+
+ int32_t buf_width, buf_height;
+ PVGetBufferDimensions(mHandle, &buf_width, &buf_height);
+
+ if (buf_width != mWidth || buf_height != mHeight) {
++mNumSamplesOutput; // The client will never get to see this frame.
inputBuffer->release();
inputBuffer = NULL;
- mWidth = width;
- mHeight = height;
+ mWidth = buf_width;
+ mHeight = buf_height;
mFormat->setInt32(kKeyWidth, mWidth);
mFormat->setInt32(kKeyHeight, mHeight);
+ CHECK_LE(disp_width, buf_width);
+ CHECK_LE(disp_height, buf_height);
+
return INFO_FORMAT_CHANGED;
}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
index ef09900..24a50ce 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
+++ b/media/libstagefright/codecs/m4v_h263/dec/include/mp4dec_api.h
@@ -159,6 +159,7 @@
Bool PVDecodeVopBody(VideoDecControls *decCtrl, int32 buffer_size[]);
void PVDecPostProcess(VideoDecControls *decCtrl, uint8 *outputYUV);
OSCL_IMPORT_REF void PVGetVideoDimensions(VideoDecControls *decCtrl, int32 *display_width, int32 *display_height);
+ OSCL_IMPORT_REF void PVGetBufferDimensions(VideoDecControls *decCtrl, int32 *buf_width, int32 *buf_height);
OSCL_IMPORT_REF void PVSetPostProcType(VideoDecControls *decCtrl, int mode);
uint32 PVGetVideoTimeStamp(VideoDecControls *decoderControl);
int PVGetDecBitrate(VideoDecControls *decCtrl);
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
index 0c354d9..844bd14 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -722,6 +722,12 @@
*display_height = video->displayHeight;
}
+OSCL_EXPORT_REF void PVGetBufferDimensions(VideoDecControls *decCtrl, int32 *width, int32 *height) {
+ VideoDecData *video = (VideoDecData *)decCtrl->videoDecoderData;
+ *width = video->width;
+ *height = video->height;
+}
+
/* ======================================================================== */
/* Function : PVGetVideoTimeStamp() */
/* Date : 04/27/2000, 08/29/2000 */
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
index bbde516..8bfe285 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
@@ -359,7 +359,10 @@
}
}
- CHECK_EQ(offset, buffer->size());
+ if (offset < buffer->size()) {
+ LOGI("ignoring %d bytes of trailing data", buffer->size() - offset);
+ }
+ CHECK_LE(offset, buffer->size());
return out;
}
diff --git a/packages/SettingsProvider/res/values-fi/strings.xml b/packages/SettingsProvider/res/values-fi/strings.xml
index 83c7f66..e4130e7a 100644
--- a/packages/SettingsProvider/res/values-fi/strings.xml
+++ b/packages/SettingsProvider/res/values-fi/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4567566098528588863">"Asetuksien tallennus"</string>
+ <!-- outdated translation 1595939146166335368 --> <string name="app_label" msgid="4567566098528588863">"Asetuksien tallennus"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index b510981..6d636e1 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"UI systému"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"UI systému"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Vymazat"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žádná oznámení"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Probíhající"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 6b22329..d60cd04f 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"System-UI"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Systemets brugergrænseflade"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ryd"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen meddelelser"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"I gang"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index a5a97c67..2155141 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"System-UI"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"System-UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Löschen"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Keine Benachrichtigungen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktuell"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 79b90f8..1f1b5a8 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"UI συστήματ."</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"UI συστήματος"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Εκκαθάριση"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Δεν υπάρχουν ειδοποιήσεις"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Εν εξελίξει"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 4a13f44..ff025cc 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Sistema UI"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Sistema UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No hay notificaciones"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continuo"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 38c6f91..909a088 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"IU sistema"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"IU del sistema"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Borrar"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No tienes notificaciones"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Entrante"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c5b6ce8..4efef06 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"IU système"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"IU système"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Effacer"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Aucune notification"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En cours"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8bc101c..3dda5481 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"UI sistema"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"UI sistema"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Cancella"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nessuna notifica"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"In corso"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b059e74..5de9d86 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"システムUI"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"システムUI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"通知を消去"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"通知なし"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"実行中"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index d325c02..69e9702 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"시스템 UI"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"시스템 UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"지우기"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"알림 없음"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"진행 중"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index cb44ef4..2cd836c 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Sys.gr.snitt"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Systemgrensesnitt"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Fjern"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen varslinger"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Aktiviteter"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 79f18b4..80a1f1a 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Systeem-UI"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Systeem-UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wissen"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Geen meldingen"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Actief"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index ddc5c88..289463d 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Interfejs"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Interfejs użytkownika systemu"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Wyczyść"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Brak powiadomień"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Bieżące"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index e89346d0..6301e28 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"IU do sist."</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"IU do sistema"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em curso"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 23e4870..755b85e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Interf sist"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Interf sist"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Limpar"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Sem notificações"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Em andamento"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 71109e3..94892ea 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Графический интерфейс системы"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Графический интерфейс системы"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Очистить"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Нет уведомлений"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Текущие"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 492a74d..75a081d 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Gränssnitt"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Gränssnitt"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ta bort"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Inga aviseringar"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Pågående"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 504ea45..c63e489 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"Sist Arayüzü"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"Sistem Arayüzü"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"Temizle"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Bildirim yok"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sürüyor"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6e59024..131a4db 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"系统用户界面"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"系统用户界面"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"无通知"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"正在进行的"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 906a68c..75f2d3d 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- outdated translation 7164937344850004466 --> <string name="app_label" msgid="4489004083283879149">"系統 UI"</string>
+ <!-- outdated translation 7290757281635988063 --> <string name="app_label" msgid="4489004083283879149">"系統 UI"</string>
<string name="status_bar_clear_all_button" msgid="7774721344716731603">"清除"</string>
<string name="status_bar_no_notifications_title" msgid="4755261167193833213">"沒有通知"</string>
<string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"進行中"</string>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 92c41d8..f934e6b 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2083,10 +2083,12 @@
return mSeascapeRotation;
case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
//return either landscape rotation based on the sensor
- mOrientationListener.setAllow180Rotation(false);
+ mOrientationListener.setAllow180Rotation(
+ isLandscapeOrSeascape(Surface.ROTATION_180));
return getCurrentLandscapeRotation(lastRotation);
case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- mOrientationListener.setAllow180Rotation(true);
+ mOrientationListener.setAllow180Rotation(
+ !isLandscapeOrSeascape(Surface.ROTATION_180));
return getCurrentPortraitRotation(lastRotation);
}
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 5071555..5935bf9 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -5810,7 +5810,8 @@
const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = {
AUDIO_MODE_NORMAL, // AudioSystem::MODE_NORMAL
AUDIO_MODE_RINGTONE, // AudioSystem::MODE_RINGTONE
- AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_CALL
+ AUDIO_MODE_IN_CALL, // AudioSystem::MODE_IN_CALL
+ AUDIO_MODE_IN_CALL // AudioSystem::MODE_IN_COMMUNICATION, same conversion as for MODE_IN_CALL
};
int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode)
diff --git a/services/audioflinger/AudioHardwareInterface.cpp b/services/audioflinger/AudioHardwareInterface.cpp
index 9a4a7f9..f58e4c0 100644
--- a/services/audioflinger/AudioHardwareInterface.cpp
+++ b/services/audioflinger/AudioHardwareInterface.cpp
@@ -48,14 +48,15 @@
"CURRENT",
"NORMAL",
"RINGTONE",
- "IN_CALL"
+ "IN_CALL",
+ "IN_COMMUNICATION"
};
static const char* routeNone = "NONE";
static const char* displayMode(int mode)
{
- if ((mode < -2) || (mode > 2))
+ if ((mode < AudioSystem::MODE_INVALID) || (mode >= AudioSystem::NUM_MODES))
return routingModeStrings[0];
return routingModeStrings[mode+3];
}
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index 8d16ab4..0da353a 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -235,7 +235,7 @@
// if leaving call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
- if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+ if (isInCall()) {
LOGV("setPhoneState() in call state management: new state is %d", state);
for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
handleIncallSonification(stream, false, true);
@@ -248,16 +248,21 @@
bool force = false;
// are we entering or starting a call
- if ((oldState != AudioSystem::MODE_IN_CALL) && (state == AudioSystem::MODE_IN_CALL)) {
+ if (!isStateInCall(oldState) && isStateInCall(state)) {
LOGV(" Entering call in setPhoneState()");
// force routing command to audio hardware when starting a call
// even if no device change is needed
force = true;
- } else if ((oldState == AudioSystem::MODE_IN_CALL) && (state != AudioSystem::MODE_IN_CALL)) {
+ } else if (isStateInCall(oldState) && !isStateInCall(state)) {
LOGV(" Exiting call in setPhoneState()");
// force routing command to audio hardware when exiting a call
// even if no device change is needed
force = true;
+ } else if (isStateInCall(state) && (state != oldState)) {
+ LOGV(" Switching between telephony and VoIP in setPhoneState()");
+ // force routing command to audio hardware when switching between telephony and VoIP
+ // even if no device change is needed
+ force = true;
}
// check for device and output changes triggered by new phone state
@@ -272,7 +277,7 @@
// force routing command to audio hardware when ending call
// even if no device change is needed
- if (oldState == AudioSystem::MODE_IN_CALL && newDevice == 0) {
+ if (isStateInCall(oldState) && newDevice == 0) {
newDevice = hwOutputDesc->device();
}
@@ -280,7 +285,7 @@
// immediately and delay the route change to avoid sending the ring tone
// tail into the earpiece or headset.
int delayMs = 0;
- if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
+ if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
// delay the device change command by twice the output latency to have some margin
// and be sure that audio buffers not yet affected by the mute are out when
// we actually apply the route change
@@ -293,7 +298,7 @@
// if entering in call state, handle special case of active streams
// pertaining to sonification strategy see handleIncallSonification()
- if (state == AudioSystem::MODE_IN_CALL) {
+ if (isStateInCall(state)) {
LOGV("setPhoneState() in call state management: new state is %d", state);
// unmute the ringing tone after a sufficient delay if it was muted before
// setting output device above
@@ -564,7 +569,7 @@
setOutputDevice(output, getNewDevice(output));
// handle special case for sonification while in call
- if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+ if (isInCall()) {
handleIncallSonification(stream, true, false);
}
@@ -589,7 +594,7 @@
routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
// handle special case for sonification while in call
- if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+ if (isInCall()) {
handleIncallSonification(stream, false, false);
}
@@ -738,10 +743,8 @@
AudioParameter param = AudioParameter();
param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
- // use Voice Recognition mode or not for this input based on input source
- int vr_enabled = inputDesc->mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION ? 1 : 0;
- param.addInt(String8("vr_mode"), vr_enabled);
- LOGV("AudioPolicyManager::startInput(%d), setting vr_mode to %d", inputDesc->mInputSource, vr_enabled);
+ param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource);
+ LOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
mpClientInterface->setParameters(input, param.toString());
@@ -1494,7 +1497,7 @@
// use device for strategy media
// 4: the strategy DTMF is active on the hardware output:
// use device for strategy DTMF
- if (mPhoneState == AudioSystem::MODE_IN_CALL ||
+ if (isInCall() ||
outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
} else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
@@ -1549,7 +1552,7 @@
switch (strategy) {
case STRATEGY_DTMF:
- if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+ if (!isInCall()) {
// when off call, DTMF strategy follows the same rules as MEDIA strategy
device = getDeviceForStrategy(STRATEGY_MEDIA, false);
break;
@@ -1562,7 +1565,7 @@
// of priority
switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
case AudioSystem::FORCE_BT_SCO:
- if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
+ if (!isInCall() || strategy != STRATEGY_DTMF) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
if (device) break;
}
@@ -1580,7 +1583,7 @@
if (device) break;
#ifdef WITH_A2DP
// when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
- if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+ if (!isInCall()) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
if (device) break;
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
@@ -1594,14 +1597,14 @@
break;
case AudioSystem::FORCE_SPEAKER:
- if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
+ if (!isInCall() || strategy != STRATEGY_DTMF) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
if (device) break;
}
#ifdef WITH_A2DP
// when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
// A2DP speaker when forcing to speaker output
- if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+ if (!isInCall()) {
device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
if (device) break;
}
@@ -1618,7 +1621,7 @@
// If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
// handleIncallSonification().
- if (mPhoneState == AudioSystem::MODE_IN_CALL) {
+ if (isInCall()) {
device = getDeviceForStrategy(STRATEGY_PHONE, false);
break;
}
@@ -1739,6 +1742,7 @@
case AUDIO_SOURCE_DEFAULT:
case AUDIO_SOURCE_MIC:
case AUDIO_SOURCE_VOICE_RECOGNITION:
+ case AUDIO_SOURCE_VOICE_COMMUNICATION:
if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
@@ -1960,6 +1964,16 @@
}
}
+bool AudioPolicyManagerBase::isInCall()
+{
+ return isStateInCall(mPhoneState);
+}
+
+bool AudioPolicyManagerBase::isStateInCall(int state) {
+ return ((state == AudioSystem::MODE_IN_CALL) ||
+ (state == AudioSystem::MODE_IN_COMMUNICATION));
+}
+
bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
uint32_t samplingRate,
uint32_t format,
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 85bb3aa..a191549 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -78,7 +78,7 @@
private static final boolean LOCAL_LOGD = false;
private static final boolean DEBUG_UNMOUNT = false;
private static final boolean DEBUG_EVENTS = false;
- private static final boolean DEBUG_OBB = true;
+ private static final boolean DEBUG_OBB = false;
private static final String TAG = "MountService";
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index e2f8a74..c5bdaa1 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -37,7 +37,6 @@
LOCAL_SHARED_LIBRARIES := \
libcutils \
- libpixelflinger \
libhardware \
libutils \
libEGL \
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3a8690e..c9dcef3 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -682,22 +682,6 @@
}
}
-void Layer::finishPageFlip()
-{
- ClientRef::Access sharedClient(mUserClientRef);
- SharedBufferServer* lcblk(sharedClient.get());
- if (lcblk) {
- int buf = mBufferManager.getActiveBufferIndex();
- if (buf >= 0) {
- status_t err = lcblk->unlock( buf );
- LOGE_IF(err!=NO_ERROR,
- "layer %p, buffer=%d wasn't locked!",
- this, buf);
- }
- }
-}
-
-
void Layer::dump(String8& result, char* buffer, size_t SIZE) const
{
LayerBaseClient::dump(result, buffer, SIZE);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index cb62558..7bb207a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -73,7 +73,6 @@
virtual uint32_t doTransaction(uint32_t transactionFlags);
virtual void lockPageFlip(bool& recomputeVisibleRegions);
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
- virtual void finishPageFlip();
virtual bool needsBlending() const { return mNeedsBlending; }
virtual bool needsDithering() const { return mNeedsDithering; }
virtual bool needsFiltering() const;
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 79c6d0d..916d420 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -273,10 +273,6 @@
}
}
-void LayerBase::finishPageFlip()
-{
-}
-
void LayerBase::invalidate()
{
if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
@@ -519,6 +515,12 @@
result.append(buffer);
}
+void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
+{
+ LayerBase::dump(result, scratch, size);
+}
+
+
// ---------------------------------------------------------------------------
int32_t LayerBaseClient::sIdentity = 1;
@@ -570,6 +572,12 @@
result.append(buffer);
}
+
+void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
+{
+ LayerBaseClient::dump(result, scratch, size);
+}
+
// ---------------------------------------------------------------------------
LayerBaseClient::Surface::Surface(
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 3ec8ac3..1470729 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -174,11 +174,6 @@
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
/**
- * finishPageFlip - called after all surfaces have drawn.
- */
- virtual void finishPageFlip();
-
- /**
* needsBlending - true if this surface needs blending
*/
virtual bool needsBlending() const { return false; }
@@ -211,6 +206,7 @@
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void shortDump(String8& result, char* scratch, size_t size) const;
enum { // flags for doTransaction()
@@ -330,6 +326,7 @@
protected:
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void shortDump(String8& result, char* scratch, size_t size) const;
private:
mutable Mutex mLock;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index af0f95a..4876946 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -396,17 +396,13 @@
logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
hw.compositionComplete();
- // release the clients before we flip ('cause flip might block)
- logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
- unlockClients();
-
logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
postFramebuffer();
logger.log(GraphicLog::SF_REPAINT_DONE, index);
} else {
// pretend we did the post
- unlockClients();
+ hw.compositionComplete();
usleep(16667); // 60 fps period
}
return true;
@@ -894,17 +890,6 @@
}
}
-void SurfaceFlinger::unlockClients()
-{
- const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
- const size_t count = drawingLayers.size();
- sp<LayerBase> const* const layers = drawingLayers.array();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer = layers[i];
- layer->finishPageFlip();
- }
-}
-
void SurfaceFlinger::debugFlashRegions()
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -1081,8 +1066,12 @@
status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
{
- // remove the layer from the main list (through a transaction).
+ // First add the layer to the purgatory list, which makes sure it won't
+ // go away, then remove it from the main list (through a transaction).
ssize_t err = removeLayer_l(layerBase);
+ if (err >= 0) {
+ mLayerPurgatory.add(layerBase);
+ }
layerBase->onRemoved();
@@ -1353,6 +1342,19 @@
* to use the purgatory.
*/
status_t err = flinger->removeLayer_l(l);
+ if (err == NAME_NOT_FOUND) {
+ // The surface wasn't in the current list, which means it was
+ // removed already, which means it is in the purgatory,
+ // and need to be removed from there.
+ // This needs to happen from the main thread since its dtor
+ // must run from there (b/c of OpenGL ES). Additionally, we
+ // can't really acquire our internal lock from
+ // destroySurface() -- see postMessage() below.
+ ssize_t idx = flinger->mLayerPurgatory.remove(l);
+ LOGE_IF(idx < 0,
+ "layer=%p is not in the purgatory list", l.get());
+ }
+
LOGE_IF(err<0 && err != NAME_NOT_FOUND,
"error removing layer=%p (%s)", l.get(), strerror(-err));
return true;
@@ -1468,8 +1470,13 @@
result.append(buffer);
}
+ /*
+ * Dump the visible layer list
+ */
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
+ snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+ result.append(buffer);
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(currentLayers[i]);
layer->dump(result, buffer, SIZE);
@@ -1479,6 +1486,24 @@
layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
}
+ /*
+ * Dump the layers in the purgatory
+ */
+
+ const size_t purgatorySize = mLayerPurgatory.size();
+ snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+ result.append(buffer);
+ for (size_t i=0 ; i<purgatorySize ; i++) {
+ const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ layer->shortDump(result, buffer, SIZE);
+ }
+
+ /*
+ * Dump SurfaceFlinger global state
+ */
+
+ snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+ result.append(buffer);
mWormholeRegion.dump(result, "WormholeRegion");
const DisplayHardware& hw(graphicPlane(0).displayHardware());
snprintf(buffer, SIZE,
@@ -1504,6 +1529,9 @@
result.append(buffer);
}
+ /*
+ * Dump gralloc state
+ */
const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
alloc.dump(result);
@@ -2113,6 +2141,7 @@
// invert everything, b/c glReadPixel() below will invert the FB
glViewport(0, 0, sw, sh);
+ glScissor(0, 0, sw, sh);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -2122,6 +2151,7 @@
// redraw the screen entirely...
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
+
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; ++i) {
@@ -2156,7 +2186,6 @@
result = NO_MEMORY;
}
}
-
glEnable(GL_SCISSOR_TEST);
glViewport(0, 0, hw_w, hw_h);
glMatrixMode(GL_PROJECTION);
@@ -2172,6 +2201,9 @@
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
glDeleteRenderbuffersOES(1, &tname);
glDeleteFramebuffersOES(1, &name);
+
+ hw.compositionComplete();
+
return result;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ca57292..a023347 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -310,7 +310,6 @@
bool handleBypassLayer();
void postFramebuffer();
void composeSurfaces(const Region& dirty);
- void unlockClients();
ssize_t addClientLayer(const sp<Client>& client,
@@ -371,6 +370,7 @@
volatile int32_t mTransactionFlags;
volatile int32_t mTransactionCount;
Condition mTransactionCV;
+ SortedVector< sp<LayerBase> > mLayerPurgatory;
bool mResizeTransationPending;
// protected by mStateLock (but we could use another lock)
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index a8dd9c2..b89058f 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -380,12 +380,17 @@
break;
case OFFHOOK:
Phone fgPhone = getFgPhone();
- // Enable IN_CALL mode while foreground call is in DIALING,
- // ALERTING, ACTIVE and DISCONNECTING state and not from sipPhone
+ // While foreground call is in DIALING,
+ // ALERTING, ACTIVE and DISCONNECTING state
if (getActiveFgCallState() != Call.State.IDLE
- && getActiveFgCallState() != Call.State.DISCONNECTED
- && !(fgPhone instanceof SipPhone)) {
- mode = AudioManager.MODE_IN_CALL;
+ && getActiveFgCallState() != Call.State.DISCONNECTED) {
+ if (fgPhone instanceof SipPhone) {
+ // enable IN_COMMUNICATION audio mode for sipPhone
+ mode = AudioManager.MODE_IN_COMMUNICATION;
+ } else {
+ // enable IN_CALL audio mode for telephony
+ mode = AudioManager.MODE_IN_CALL;
+ }
}
break;
}
@@ -890,6 +895,8 @@
public boolean getMute() {
if (hasActiveFgCall()) {
return getActiveFgCall().getPhone().getMute();
+ } else if (hasActiveBgCall()) {
+ return getFirstActiveBgCall().getPhone().getMute();
}
return false;
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 7d31687..f2643bb 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -225,7 +225,15 @@
private Context mContext;
WakeLock mWakeLock;
int mWakeLockTimeout;
+ // The number of requests pending to be sent out, it increases before calling
+ // EVENT_SEND and decreases while handling EVENT_SEND. It gets cleared while
+ // WAKE_LOCK_TIMEOUT occurs.
int mRequestMessagesPending;
+ // The number of requests sent out but waiting for response. It increases while
+ // sending request and decreases while handling response. It should match
+ // mRequestList.size() unless there are requests no replied while
+ // WAKE_LOCK_TIMEOUT occurs.
+ int mRequestMessagesWaiting;
// Is this the first radio state change?
private boolean mInitialRadioStateChange = true;
@@ -308,16 +316,19 @@
if (s == null) {
rr.onError(RADIO_NOT_AVAILABLE, null);
rr.release();
- mRequestMessagesPending--;
+ if (mRequestMessagesPending > 0)
+ mRequestMessagesPending--;
alreadySubtracted = true;
return;
}
synchronized (mRequestsList) {
mRequestsList.add(rr);
+ mRequestMessagesWaiting++;
}
- mRequestMessagesPending--;
+ if (mRequestMessagesPending > 0)
+ mRequestMessagesPending--;
alreadySubtracted = true;
byte[] data;
@@ -361,7 +372,7 @@
}
}
- if (!alreadySubtracted) {
+ if (!alreadySubtracted && mRequestMessagesPending > 0) {
mRequestMessagesPending--;
}
@@ -376,25 +387,48 @@
// new send request. So when WAKE_LOCK_TIMEOUT occurs
// all requests in mRequestList already waited at
// least DEFAULT_WAKE_LOCK_TIMEOUT but no response.
- // Therefore all should be treated as lost requests.
- // Those lost requests return GENERIC_FAILURE and
- // request list is cleared.
+ // Reset mRequestMessagesWaiting to enable
+ // releaseWakeLockIfDone().
//
- // Note: mRequestMessagesPending shows how many
- // requests are waiting to be sent (and before
- // to be added in request list) since star the
- // timer. It should be
- // zero here since all request should already
- // be put in request list while TIMEOUT occurs.
- clearRequestsList(GENERIC_FAILURE, true);
+ // Note: Keep mRequestList so that delayed response
+ // can still be handled when response finally comes.
+ if (mRequestMessagesWaiting != 0) {
+ Log.d(LOG_TAG, "NOTE: mReqWaiting is NOT 0 but"
+ + mRequestMessagesWaiting + " at TIMEOUT, reset!"
+ + " There still msg waitng for response");
+
+ mRequestMessagesWaiting = 0;
+
+ if (RILJ_LOGD) {
+ synchronized (mRequestsList) {
+ int count = mRequestsList.size();
+ Log.d(LOG_TAG, "WAKE_LOCK_TIMEOUT " +
+ " mRequestList=" + count);
+
+ for (int i = 0; i < count; i++) {
+ rr = mRequestsList.get(i);
+ Log.d(LOG_TAG, i + ": [" + rr.mSerial + "] "
+ + requestToString(rr.mRequest));
+ }
+ }
+ }
+ }
+ // mRequestMessagesPending shows how many
+ // requests are waiting to be sent (and before
+ // to be added in request list) since star the
+ // WAKE_LOCK_TIMEOUT timer. Since WAKE_LOCK_TIMEOUT
+ // is the expected time to get response, all requests
+ // should already sent out (i.e.
+ // mRequestMessagesPending is 0 )while TIMEOUT occurs.
if (mRequestMessagesPending != 0) {
- Log.e(LOG_TAG, "ERROR: mReqPending is NOT 0 at TIMEOUT, "
- + "mReqPending = " + mRequestMessagesPending);
+ Log.e(LOG_TAG, "ERROR: mReqPending is NOT 0 but"
+ + mRequestMessagesPending + " at TIMEOUT, reset!");
+ mRequestMessagesPending = 0;
+
}
mWakeLock.release();
}
}
-
break;
}
}
@@ -607,6 +641,7 @@
mWakeLockTimeout = SystemProperties.getInt(TelephonyProperties.PROPERTY_WAKE_LOCK_TIMEOUT,
DEFAULT_WAKE_LOCK_TIMEOUT);
mRequestMessagesPending = 0;
+ mRequestMessagesWaiting = 0;
mContext = context;
@@ -2000,7 +2035,7 @@
/**
* Holds a PARTIAL_WAKE_LOCK whenever
* a) There is outstanding RIL request sent to RIL deamon and no replied
- * b) There is a request waiting to be sent out.
+ * b) There is a request pending to be sent out.
*
* There is a WAKE_LOCK_TIMEOUT to release the lock, though it shouldn't
* happen often.
@@ -2023,7 +2058,7 @@
synchronized (mWakeLock) {
if (mWakeLock.isHeld() &&
(mRequestMessagesPending == 0) &&
- (mRequestsList.size() == 0)) {
+ (mRequestMessagesWaiting == 0)) {
mSender.removeMessages(EVENT_WAKE_LOCK_TIMEOUT);
mWakeLock.release();
}
@@ -2081,6 +2116,7 @@
rr.release();
}
mRequestsList.clear();
+ mRequestMessagesWaiting = 0;
}
}
@@ -2091,6 +2127,8 @@
if (rr.mSerial == serial) {
mRequestsList.remove(i);
+ if (mRequestMessagesWaiting > 0)
+ mRequestMessagesWaiting--;
return rr;
}
}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 72f3831..461e4fb 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -306,7 +306,9 @@
}
public boolean getMute() {
- return foregroundCall.getMute();
+ return (foregroundCall.getState().isAlive()
+ ? foregroundCall.getMute()
+ : backgroundCall.getMute());
}
public Call getForegroundCall() {
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
index 3af6e78..dc66989 100644
--- a/voip/java/com/android/server/sip/SipService.java
+++ b/voip/java/com/android/server/sip/SipService.java
@@ -105,7 +105,7 @@
if (SipManager.isApiSupported(context)) {
ServiceManager.addService("sip", new SipService(context));
context.sendBroadcast(new Intent(SipManager.ACTION_SIP_SERVICE_UP));
- if (DEBUG) Log.i(TAG, "SIP service started");
+ if (DEBUG) Log.d(TAG, "SIP service started");
}
}
@@ -113,10 +113,6 @@
if (DEBUG) Log.d(TAG, " service started!");
mContext = context;
mConnectivityReceiver = new ConnectivityReceiver();
- context.registerReceiver(mConnectivityReceiver,
- new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
- context.registerReceiver(mWifiStateReceiver,
- new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
mMyWakeLock = new SipWakeLock((PowerManager)
context.getSystemService(Context.POWER_SERVICE));
@@ -124,7 +120,7 @@
mWifiOnly = SipManager.isSipWifiOnly(context);
}
- BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
@@ -147,6 +143,20 @@
}
};
+ private void registerReceivers() {
+ mContext.registerReceiver(mConnectivityReceiver,
+ new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+ mContext.registerReceiver(mWifiStateReceiver,
+ new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
+ if (DEBUG) Log.d(TAG, " +++ register receivers");
+ }
+
+ private void unregisterReceivers() {
+ mContext.unregisterReceiver(mConnectivityReceiver);
+ mContext.unregisterReceiver(mWifiStateReceiver);
+ if (DEBUG) Log.d(TAG, " --- unregister receivers");
+ }
+
private MyExecutor getExecutor() {
// create mExecutor lazily
if (mExecutor == null) mExecutor = new MyExecutor();
@@ -166,12 +176,14 @@
return profiles.toArray(new SipProfile[profiles.size()]);
}
- public void open(SipProfile localProfile) {
+ public synchronized void open(SipProfile localProfile) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.USE_SIP, null);
localProfile.setCallingUid(Binder.getCallingUid());
try {
+ boolean addingFirstProfile = mSipGroups.isEmpty();
createGroup(localProfile);
+ if (addingFirstProfile && !mSipGroups.isEmpty()) registerReceivers();
} catch (SipException e) {
Log.e(TAG, "openToMakeCalls()", e);
// TODO: how to send the exception back
@@ -192,8 +204,10 @@
if (DEBUG) Log.d(TAG, "open3: " + localProfile.getUriString() + ": "
+ incomingCallPendingIntent + ": " + listener);
try {
+ boolean addingFirstProfile = mSipGroups.isEmpty();
SipSessionGroupExt group = createGroup(localProfile,
incomingCallPendingIntent, listener);
+ if (addingFirstProfile && !mSipGroups.isEmpty()) registerReceivers();
if (localProfile.getAutoRegistration()) {
group.openToReceiveCalls();
if (mWifiEnabled) grabWifiLock();
@@ -235,6 +249,7 @@
releaseWifiLock();
mMyWakeLock.reset(); // in case there's leak
}
+ if (mSipGroups.isEmpty()) unregisterReceivers();
}
public synchronized boolean isOpened(String localProfileUri) {
@@ -1055,7 +1070,10 @@
// we want to skip the interim ones) but deliver bad news
// immediately
if (connected) {
- if (mTask != null) mTask.cancel();
+ if (mTask != null) {
+ mTask.cancel();
+ mMyWakeLock.release(mTask);
+ }
mTask = new MyTimerTask(type, connected);
mTimer.schedule(mTask, 2 * 1000L);
// hold wakup lock so that we can finish changes before the
@@ -1096,6 +1114,7 @@
if (mTask != this) {
Log.w(TAG, " unexpected task: " + mNetworkType
+ (mConnected ? " CONNECTED" : "DISCONNECTED"));
+ mMyWakeLock.release(this);
return;
}
mTask = null;
diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp
index 60abf2a..2cbd023 100644
--- a/voip/jni/rtp/AudioGroup.cpp
+++ b/voip/jni/rtp/AudioGroup.cpp
@@ -483,7 +483,7 @@
ON_HOLD = 0,
MUTED = 1,
NORMAL = 2,
- EC_ENABLED = 3,
+ ECHO_SUPPRESSION = 3,
LAST_MODE = 3,
};
@@ -619,6 +619,10 @@
if (mode < 0 || mode > LAST_MODE) {
return false;
}
+ if (mode == ECHO_SUPPRESSION && AudioSystem::getParameters(
+ 0, String8("ec_supported")) == "ec_supported=yes") {
+ mode = NORMAL;
+ }
if (mMode == mode) {
return true;
}
@@ -775,8 +779,8 @@
AudioTrack track;
AudioRecord record;
if (track.set(AudioSystem::VOICE_CALL, sampleRate, AudioSystem::PCM_16_BIT,
- AudioSystem::CHANNEL_OUT_MONO, output) != NO_ERROR ||
- record.set(AUDIO_SOURCE_MIC, sampleRate, AudioSystem::PCM_16_BIT,
+ AudioSystem::CHANNEL_OUT_MONO, output) != NO_ERROR || record.set(
+ AUDIO_SOURCE_VOICE_COMMUNICATION, sampleRate, AudioSystem::PCM_16_BIT,
AudioSystem::CHANNEL_IN_MONO, input) != NO_ERROR) {
LOGE("cannot initialize audio device");
return false;