Mass merge from gingerbread - do not merge
Change-Id: I45dc3596bf4211d8f91c64f2d1d00588878df629
diff --git a/Android.mk b/Android.mk
index 7728b02..93e1c4f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -367,6 +367,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 \
-since ./frameworks/base/api/current.xml Honeycomb \
-werror -hide 113 \
-overview $(LOCAL_PATH)/core/java/overview.html
diff --git a/NOTICE b/NOTICE
index d857ba3..462d5ae 100644
--- a/NOTICE
+++ b/NOTICE
@@ -56,6 +56,16 @@
=========================================================================
== NOTICE file corresponding to the section 4 d of ==
== the Apache License, Version 2.0, ==
+ == in this case for Additional Codecs code. ==
+ =========================================================================
+
+Additional Codecs
+These files are Copyright 2003-2010 VisualOn, but released under
+the Apache2 License.
+
+ =========================================================================
+ == NOTICE file corresponding to the section 4 d of ==
+ == the Apache License, Version 2.0, ==
== in this case for the TagSoup code. ==
=========================================================================
diff --git a/api/current.xml b/api/current.xml
index bd59694..5d42845 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -118502,6 +118502,66 @@
deprecated="not deprecated"
visibility="public"
>
+<method name="disableForegroundDispatch"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
+</method>
+<method name="disableForegroundNdefPush"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
+</method>
+<method name="enableForegroundDispatch"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+<parameter name="filters" type="android.content.IntentFilter[]">
+</parameter>
+<parameter name="techLists" type="java.lang.String[][]">
+</parameter>
+</method>
+<method name="enableForegroundNdefPush"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activity" type="android.app.Activity">
+</parameter>
+<parameter name="msg" type="android.nfc.NdefMessage">
+</parameter>
+</method>
<method name="getDefaultAdapter"
return="android.nfc.NfcAdapter"
abstract="false"
@@ -118537,6 +118597,17 @@
visibility="public"
>
</method>
+<field name="ACTION_NDEF_DISCOVERED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.nfc.action.NDEF_DISCOVERED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_TAG_DISCOVERED"
type="java.lang.String"
transient="false"
@@ -118548,6 +118619,17 @@
visibility="public"
>
</field>
+<field name="ACTION_TECHNOLOGY_DISCOVERED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.nfc.action.TECH_DISCOVERED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="EXTRA_ID"
type="java.lang.String"
transient="false"
@@ -118570,6 +118652,17 @@
visibility="public"
>
</field>
+<field name="EXTRA_TAG"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.nfc.extra.TAG""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="NfcManager"
extends="java.lang.Object"
@@ -118591,6 +118684,1295 @@
>
</method>
</class>
+<class name="Tag"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="createMockTag"
+ return="android.nfc.Tag"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="id" type="byte[]">
+</parameter>
+<parameter name="techList" type="int[]">
+</parameter>
+<parameter name="techListExtras" type="android.os.Bundle[]">
+</parameter>
+</method>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getId"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getTechList"
+ return="java.lang.String[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="dest" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="TagLostException"
+ extends="java.io.IOException"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="TagLostException"
+ type="android.nfc.TagLostException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<constructor name="TagLostException"
+ type="android.nfc.TagLostException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="message" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
+</package>
+<package name="android.nfc.tech"
+>
+<class name="BasicTagTechnology"
+ extends="java.lang.Object"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility=""
+>
+<implements name="android.nfc.tech.TagTechnology">
+</implements>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="connect"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getTag"
+ return="android.nfc.Tag"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isConnected"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="reconnect"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="IsoDep"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="get"
+ return="android.nfc.tech.IsoDep"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getHiLayerResponse"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getHistoricalBytes"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setTimeout"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="timeout" type="int">
+</parameter>
+</method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="MifareClassic"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="authenticateSectorWithKeyA"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sectorIndex" type="int">
+</parameter>
+<parameter name="key" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="authenticateSectorWithKeyB"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sectorIndex" type="int">
+</parameter>
+<parameter name="key" type="byte[]">
+</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"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="blockIndex" type="int">
+</parameter>
+<parameter name="value" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="get"
+ return="android.nfc.tech.MifareClassic"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getBlockCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</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"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSize"
+ 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"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="increment"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="blockIndex" type="int">
+</parameter>
+<parameter name="value" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="readBlock"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="blockIndex" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="restore"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<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"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="transfer"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="blockIndex" type="int">
+</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"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="blockIndex" type="int">
+</parameter>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<field name="BLOCK_SIZE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KEY_DEFAULT"
+ type="byte[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KEY_MIFARE_APPLICATION_DIRECTORY"
+ type="byte[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KEY_NFC_FORUM"
+ type="byte[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SIZE_1K"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1024"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SIZE_2K"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2048"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SIZE_4K"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4096"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SIZE_MINI"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="320"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_CLASSIC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_PLUS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_PRO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="MifareUltralight"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="get"
+ return="android.nfc.tech.MifareUltralight"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="readPages"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pageOffset" type="int">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="writePage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<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"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_ULTRALIGHT_C"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TYPE_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Ndef"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="canMakeReadonly"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="get"
+ return="android.nfc.tech.Ndef"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getCachedNdefMessage"
+ return="android.nfc.NdefMessage"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMaxSize"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getNdefMessage"
+ return="android.nfc.NdefMessage"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="FormatException" type="android.nfc.FormatException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isWritable"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="makeReadonly"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="writeNdefMessage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msg" type="android.nfc.NdefMessage">
+</parameter>
+<exception name="FormatException" type="android.nfc.FormatException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<field name="MIFARE_CLASSIC"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="101"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NFC_FORUM_TYPE_1"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NFC_FORUM_TYPE_2"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NFC_FORUM_TYPE_3"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NFC_FORUM_TYPE_4"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="OTHER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="NdefFormatable"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="format"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="firstMessage" type="android.nfc.NdefMessage">
+</parameter>
+<exception name="FormatException" type="android.nfc.FormatException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="get"
+ return="android.nfc.tech.NdefFormatable"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+</class>
+<class name="NfcA"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="get"
+ return="android.nfc.tech.NfcA"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getAtqa"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSak"
+ return="short"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="NfcB"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="get"
+ return="android.nfc.tech.NfcB"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getApplicationData"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getProtocolInfo"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="NfcF"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="get"
+ return="android.nfc.tech.NfcF"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getManufacturer"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSystemCode"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<class name="NfcV"
+ extends="android.nfc.tech.BasicTagTechnology"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="get"
+ return="android.nfc.tech.NfcV"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="getDsfId"
+ return="byte"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getResponseFlags"
+ return="byte"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="transceive"
+ return="byte[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="byte[]">
+</parameter>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</class>
+<interface name="TagTechnology"
+ abstract="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="java.io.Closeable">
+</implements>
+<method name="close"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="connect"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<method name="getTag"
+ return="android.nfc.Tag"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="reconnect"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+</interface>
</package>
<package name="android.opengl"
>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 3c45080..8b6b819 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -655,7 +655,7 @@
boolean mCalled;
boolean mCheckedForLoaderManager;
boolean mLoadersStarted;
- private boolean mResumed;
+ /*package*/ boolean mResumed;
private boolean mStopped;
boolean mFinished;
boolean mStartedActivity;
@@ -4363,9 +4363,8 @@
mLastNonConfigurationInstances = null;
- // First call onResume() -before- setting mResumed, so we don't
- // send out any status bar / menu notifications the client makes.
mCalled = false;
+ // mResumed is set by the instrumentation
mInstrumentation.callActivityOnResume(this);
if (!mCalled) {
throw new SuperNotCalledException(
@@ -4374,7 +4373,6 @@
}
// Now really resume, and install the current status bar and menu.
- mResumed = true;
mCalled = false;
mFragments.dispatchResume();
@@ -4399,6 +4397,7 @@
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
+ mResumed = false;
}
final void performUserLeaving() {
@@ -4461,7 +4460,10 @@
}
}
- final boolean isResumed() {
+ /**
+ * @hide
+ */
+ public final boolean isResumed() {
return mResumed;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 960b943..8f9a76b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -193,6 +193,9 @@
final HashMap<IBinder, ProviderClientRecord> mLocalProviders
= new HashMap<IBinder, ProviderClientRecord>();
+ final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
+ = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
+
final GcIdler mGcIdler = new GcIdler();
boolean mGcIdlerScheduled = false;
@@ -1514,6 +1517,28 @@
}
}
+ public void registerOnActivityPausedListener(Activity activity,
+ OnActivityPausedListener listener) {
+ synchronized (mOnPauseListeners) {
+ ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
+ if (list == null) {
+ list = new ArrayList<OnActivityPausedListener>();
+ mOnPauseListeners.put(activity, list);
+ }
+ list.add(listener);
+ }
+ }
+
+ public void unregisterOnActivityPausedListener(Activity activity,
+ OnActivityPausedListener listener) {
+ synchronized (mOnPauseListeners) {
+ ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
+ if (list != null) {
+ list.remove(listener);
+ }
+ }
+ }
+
public final ActivityInfo resolveActivityInfo(Intent intent) {
ActivityInfo aInfo = intent.resolveActivityInfo(
mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
@@ -2454,6 +2479,17 @@
}
}
r.paused = true;
+
+ // Notify any outstanding on paused listeners
+ ArrayList<OnActivityPausedListener> listeners;
+ synchronized (mOnPauseListeners) {
+ listeners = mOnPauseListeners.remove(r.activity);
+ }
+ int size = (listeners != null ? listeners.size() : 0);
+ for (int i = 0; i < size; i++) {
+ listeners.get(i).onPaused(r.activity);
+ }
+
return state;
}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index ad811d8..cd278be 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1149,6 +1149,7 @@
* @param activity The activity being resumed.
*/
public void callActivityOnResume(Activity activity) {
+ activity.mResumed = true;
activity.onResume();
if (mActivityMonitors != null) {
diff --git a/core/java/android/app/OnActivityPausedListener.java b/core/java/android/app/OnActivityPausedListener.java
new file mode 100644
index 0000000..379f133
--- /dev/null
+++ b/core/java/android/app/OnActivityPausedListener.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 Google Inc.
+ *
+ * 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.app;
+
+/**
+ * A listener that is called when an Activity is paused. Since this is tracked client side
+ * it should not be trusted to represent the exact current state, but can be used as a hint
+ * for cleanup.
+ *
+ * @hide
+ */
+public interface OnActivityPausedListener {
+ /**
+ * Called when the given activity is paused.
+ */
+ public void onPaused(Activity activity);
+}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 4a75514..f079e42 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -25,6 +25,7 @@
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
import android.view.IRotationWatcher;
import android.view.IWindowManager;
import android.view.Surface;
@@ -489,6 +490,8 @@
private final Handler mHandler;
private SensorEvent mValuesPool;
public SparseBooleanArray mSensors = new SparseBooleanArray();
+ public SparseBooleanArray mFirstEvent = new SparseBooleanArray();
+ public SparseIntArray mSensorAccuracies = new SparseIntArray();
ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler) {
mSensorEventListener = listener;
@@ -499,10 +502,30 @@
mHandler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
- SensorEvent t = (SensorEvent)msg.obj;
- if (t.accuracy >= 0) {
- mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy);
+ final SensorEvent t = (SensorEvent)msg.obj;
+ final int handle = t.sensor.getHandle();
+
+ switch (t.sensor.getType()) {
+ // Only report accuracy for sensors that support it.
+ case Sensor.TYPE_MAGNETIC_FIELD:
+ case Sensor.TYPE_ORIENTATION:
+ // call onAccuracyChanged() only if the value changes
+ final int accuracy = mSensorAccuracies.get(handle);
+ if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
+ mSensorAccuracies.put(handle, t.accuracy);
+ mSensorEventListener.onAccuracyChanged(t.sensor, t.accuracy);
+ }
+ break;
+ default:
+ // For other sensors, just report the accuracy once
+ if (mFirstEvent.get(handle) == false) {
+ mFirstEvent.put(handle, true);
+ mSensorEventListener.onAccuracyChanged(
+ t.sensor, SENSOR_STATUS_ACCURACY_HIGH);
+ }
+ break;
}
+
mSensorEventListener.onSensorChanged(t);
returnToPool(t);
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 7e809f5..cab8ed2 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -221,6 +221,8 @@
/** {@hide} */
public static final int TYPE_DUMMY = 8;
+ /** {@hide} */
+ public static final int TYPE_ETHERNET = 9;
/** {@hide} TODO: Need to adjust this for WiMAX. */
public static final int MAX_RADIO_TYPE = TYPE_DUMMY;
/** {@hide} TODO: Need to adjust this for WiMAX. */
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index a663fb8..d439a48 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -16,8 +16,12 @@
package android.nfc;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+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;
@@ -44,6 +48,11 @@
NdefMessage localGet();
void localSet(in NdefMessage message);
void openTagConnection(in Tag tag);
+ void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
+ in IntentFilter[] filters, in TechListParcel techLists);
+ void disableForegroundDispatch(in ComponentName activity);
+ void enableForegroundNdefPush(in ComponentName activity, in NdefMessage msg);
+ void disableForegroundNdefPush(in ComponentName activity);
// Non-public methods
// TODO: check and complete
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 5d222d9..57dc38c 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -17,6 +17,7 @@
package android.nfc;
import android.nfc.NdefMessage;
+import android.nfc.TransceiveResult;
/**
* @hide
@@ -30,7 +31,7 @@
byte[] getUid(int nativeHandle);
boolean isNdef(int nativeHandle);
boolean isPresent(int nativeHandle);
- byte[] transceive(int nativeHandle, in byte[] data, boolean raw);
+ TransceiveResult transceive(int nativeHandle, in byte[] data, boolean raw);
int getLastError(int nativeHandle);
@@ -39,4 +40,7 @@
int ndefMakeReadOnly(int nativeHandle);
boolean ndefIsWritable(int nativeHandle);
int formatNdef(int nativeHandle, in byte[] key);
+
+ void setIsoDepTimeout(int timeout);
+ void resetIsoDepTimeout();
}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 758c8a0..4808032 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -18,11 +18,16 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Activity;
import android.app.ActivityThread;
+import android.app.OnActivityPausedListener;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.os.IBinder;
+import android.os.Parcel;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
@@ -43,7 +48,6 @@
*
* If any activities respond to this intent neither
* {@link #ACTION_TECHNOLOGY_DISCOVERED} or {@link #ACTION_TAG_DISCOVERED} will be started.
- * @hide
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
@@ -51,13 +55,12 @@
/**
* 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}
*
* If any activities respond to this intent {@link #ACTION_TAG_DISCOVERED} will not be started.
- * @hide
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_TECHNOLOGY_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
@@ -76,7 +79,6 @@
/**
* Mandatory Tag extra for the ACTION_TAG intents.
- * @hide
*/
public static final String EXTRA_TAG = "android.nfc.extra.TAG";
@@ -102,6 +104,20 @@
"android.nfc.action.TRANSACTION_DETECTED";
/**
+ * Broadcast Action: an RF field ON has been detected.
+ * @hide
+ */
+ public static final String ACTION_RF_FIELD_ON_DETECTED =
+ "android.nfc.action.RF_FIELD_ON_DETECTED";
+
+ /**
+ * Broadcast Action: an RF Field OFF has been detected.
+ * @hide
+ */
+ public static final String ACTION_RF_FIELD_OFF_DETECTED =
+ "android.nfc.action.RF_FIELD_OFF_DETECTED";
+
+ /**
* Broadcast Action: an adapter's state changed between enabled and disabled.
*
* The new value is stored in the extra EXTRA_NEW_BOOLEAN_STATE and just contains
@@ -197,8 +213,7 @@
// attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
// recovery
private static INfcAdapter sService;
-
- private final Context mContext;
+ private static INfcTag sTagService;
/**
* Helper to check if this device has FEATURE_NFC, but without using
@@ -235,6 +250,12 @@
Log.e(TAG, "could not retrieve NFC service");
return null;
}
+ try {
+ sTagService = sService.getNfcTagInterface();
+ } catch (RemoteException e) {
+ Log.e(TAG, "could not retrieve NFC Tag service");
+ return null;
+ }
}
return sService;
}
@@ -289,7 +310,6 @@
if (setupService() == null) {
throw new UnsupportedOperationException();
}
- mContext = context;
}
/**
@@ -297,10 +317,20 @@
* @hide
*/
public INfcAdapter getService() {
+ isEnabled(); // NOP call to recover sService if it is stale
return sService;
}
/**
+ * Returns the binder interface to the tag service.
+ * @hide
+ */
+ public INfcTag getTagService() {
+ isEnabled(); // NOP call to recover sTagService if it is stale
+ return sTagService;
+ }
+
+ /**
* NFC service dead - attempt best effort recovery
* @hide
*/
@@ -309,11 +339,21 @@
INfcAdapter service = getServiceInterface();
if (service == null) {
Log.e(TAG, "could not retrieve NFC service during service recovery");
+ // nothing more can be done now, sService is still stale, we'll hit
+ // this recovery path again later
return;
}
- /* assigning to sService is not thread-safe, but this is best-effort code
- * and on a well-behaved system should never happen */
+ // assigning to sService is not thread-safe, but this is best-effort code
+ // and on a well-behaved system should never happen
sService = service;
+ try {
+ sTagService = service.getNfcTagInterface();
+ } catch (RemoteException ee) {
+ Log.e(TAG, "could not retrieve NFC tag service during service recovery");
+ // nothing more can be done now, sService is still stale, we'll hit
+ // this recovery path again later
+ }
+
return;
}
@@ -374,6 +414,136 @@
}
/**
+ * 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. 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, or null to always dispatch
+ * @throws IllegalStateException
+ */
+ public void enableForegroundDispatch(Activity activity, PendingIntent intent,
+ IntentFilter[] filters, String[][] techLists) {
+ if (activity == null || intent == null) {
+ throw new NullPointerException();
+ }
+ if (!activity.isResumed()) {
+ throw new IllegalStateException("Foregorund dispatching can only be enabled " +
+ "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,
+ parcel);
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ }
+ }
+
+ /**
+ * Disables foreground activity dispatching setup with
+ * {@link #enableForegroundDispatch}.
+ *
+ * <p>This must be called before the Activity returns from
+ * it's <code>onPause()</code> or this method will throw an IllegalStateException.
+ *
+ * <p>This method must be called from the main thread.
+ */
+ public void disableForegroundDispatch(Activity activity) {
+ ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity,
+ mForegroundDispatchListener);
+ disableForegroundDispatchInternal(activity, false);
+ }
+
+ OnActivityPausedListener mForegroundDispatchListener = new OnActivityPausedListener() {
+ @Override
+ public void onPaused(Activity activity) {
+ disableForegroundDispatchInternal(activity, true);
+ }
+ };
+
+ void disableForegroundDispatchInternal(Activity activity, boolean force) {
+ try {
+ sService.disableForegroundDispatch(activity.getComponentName());
+ if (!force && !activity.isResumed()) {
+ throw new IllegalStateException("You must disable forgeground dispatching " +
+ "while your activity is still resumed");
+ }
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ }
+ }
+
+ /**
+ * 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) {
+ throw new NullPointerException();
+ }
+ if (!activity.isResumed()) {
+ throw new IllegalStateException("Foregorund NDEF push can only be enabled " +
+ "when your activity is resumed");
+ }
+ try {
+ ActivityThread.currentActivityThread().registerOnActivityPausedListener(activity,
+ mForegroundNdefPushListener);
+ sService.enableForegroundNdefPush(activity.getComponentName(), msg);
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ }
+ }
+
+ /**
+ * Disables foreground NDEF push setup with
+ * {@link #enableForegroundNdefPush}.
+ *
+ * <p>This must be called before the Activity returns from
+ * it's <code>onPause()</code> or this method will throw an IllegalStateException.
+ *
+ * <p>This method must be called from the main thread.
+ */
+ public void disableForegroundNdefPush(Activity activity) {
+ ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity,
+ mForegroundNdefPushListener);
+ disableForegroundNdefPushInternal(activity, false);
+ }
+
+ OnActivityPausedListener mForegroundNdefPushListener = new OnActivityPausedListener() {
+ @Override
+ public void onPaused(Activity activity) {
+ disableForegroundNdefPushInternal(activity, true);
+ }
+ };
+
+ void disableForegroundNdefPushInternal(Activity activity, boolean force) {
+ try {
+ sService.disableForegroundNdefPush(activity.getComponentName());
+ if (!force && !activity.isResumed()) {
+ throw new IllegalStateException("You must disable forgeground NDEF push " +
+ "while your activity is still resumed");
+ }
+ } catch (RemoteException e) {
+ attemptDeadServiceRecovery(e);
+ }
+ }
+
+ /**
* Set the NDEF Message that this NFC adapter should appear as to Tag
* readers.
* <p>
diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java
index 5f4c066..ea2846e 100755
--- a/core/java/android/nfc/NfcSecureElement.java
+++ b/core/java/android/nfc/NfcSecureElement.java
@@ -16,7 +16,7 @@
package android.nfc;
-import android.nfc.technology.TagTechnology;
+import android.nfc.tech.TagTechnology;
import android.os.RemoteException;
import android.util.Log;
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 7404950..aae75c9 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -16,36 +16,35 @@
package android.nfc;
-import android.nfc.technology.IsoDep;
-import android.nfc.technology.MifareClassic;
-import android.nfc.technology.MifareUltralight;
-import android.nfc.technology.NfcV;
-import android.nfc.technology.Ndef;
-import android.nfc.technology.NdefFormatable;
-import android.nfc.technology.NfcA;
-import android.nfc.technology.NfcB;
-import android.nfc.technology.NfcF;
-import android.nfc.technology.TagTechnology;
+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;
import android.os.Parcelable;
-import android.os.RemoteException;
import java.util.Arrays;
/**
* Represents a (generic) discovered tag.
* <p>
- * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags,
- * Sony Felica Tags.
+ * A tag is a passive NFC element, such as NFC Forum Tag's, MIFARE class Tags,
+ * Sony FeliCa Tags, etc.
* <p>
* Tag's have a type and usually have a UID.
* <p>
* {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra
* in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable
* and represents the state of the tag at the time of discovery. It can be
- * directly queried for its UID and Type, or used to create a {@link TagTechnology}
- * (with {@link Tag#getTechnology(int)}).
+ * directly queried for its UID and Type, or used to create a {@link TagTechnology} using the
+ * static <code>get()</code> methods on the varios tech classes.
* <p>
* A {@link Tag} can be used to create a {@link TagTechnology} only while the tag is in
* range. If it is removed and then returned to range, then the most recent
@@ -55,13 +54,14 @@
* time and calls on this class will retrieve those read-only properties, and
* not cause any further RF activity or block. Note however that arrays passed to and
* returned by this class are *not* cloned, so be careful not to modify them.
- * @hide
*/
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;
/*package*/ int mConnectedTechnology;
@@ -69,24 +69,26 @@
* Hidden constructor to be used by NFC service and internal classes.
* @hide
*/
- public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle) {
+ public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle,
+ INfcTag tagService) {
if (techList == null) {
throw new IllegalArgumentException("rawTargets cannot be null");
}
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;
+ mTagService = tagService;
mConnectedTechnology = -1;
}
/**
* Construct a mock Tag.
- * <p>This is an application constructed tag, so NfcAdapter methods on this
- * Tag such as {@link #getTechnology} may fail with
- * {@link IllegalArgumentException} since it does not represent a physical Tag.
+ * <p>This is an application constructed tag, so NfcAdapter methods on this Tag may fail
+ * with {@link IllegalArgumentException} since it does not represent a physical Tag.
* <p>This constructor might be useful for mock testing.
* @param id The tag identifier, can be null
* @param techList must not be null
@@ -94,7 +96,46 @@
*/
public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) {
// set serviceHandle to 0 to indicate mock tag
- return new Tag(id, techList, techListExtras, 0);
+ 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;
}
/**
@@ -119,19 +160,24 @@
* 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;
}
- /**
- * Returns the technology, or null if not present
- */
- public TagTechnology getTechnology(NfcAdapter adapter, int tech) {
+ /** @hide */
+ public boolean hasTech(int techType) {
+ for (int tech : mTechList) {
+ if (tech == techType) return true;
+ }
+ return false;
+ }
+
+ /** @hide */
+ public Bundle getTechExtras(int tech) {
int pos = -1;
for (int idx = 0; idx < mTechList.length; idx++) {
if (mTechList[idx] == tech) {
@@ -143,44 +189,12 @@
return null;
}
- Bundle extras = mTechExtras[pos];
- try {
- switch (tech) {
- case TagTechnology.NFC_A: {
- return new NfcA(adapter, this, extras);
- }
- case TagTechnology.NFC_B: {
- return new NfcB(adapter, this, extras);
- }
- case TagTechnology.ISO_DEP: {
- return new IsoDep(adapter, this, extras);
- }
- case TagTechnology.NFC_V: {
- return new NfcV(adapter, this, extras);
- }
- case TagTechnology.NDEF: {
- return new Ndef(adapter, this, tech, extras);
- }
- case TagTechnology.NDEF_FORMATABLE: {
- return new NdefFormatable(adapter, this, tech, extras);
- }
- case TagTechnology.NFC_F: {
- return new NfcF(adapter, this, extras);
- }
- case TagTechnology.MIFARE_CLASSIC: {
- return new MifareClassic(adapter, this, extras);
- }
- case TagTechnology.MIFARE_ULTRALIGHT: {
- return new MifareUltralight(adapter, this, extras);
- }
+ return mTechExtras[pos];
+ }
- default: {
- throw new UnsupportedOperationException("Tech " + tech + " not supported");
- }
- }
- } catch (RemoteException e) {
- return null;
- }
+ /** @hide */
+ public INfcTag getTagService() {
+ return mTagService;
}
@Override
@@ -222,25 +236,41 @@
@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.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();
+ int isMock = in.readInt();
+ if (isMock == 0) {
+ tagService = INfcTag.Stub.asInterface(in.readStrongBinder());
+ }
+ else {
+ tagService = null;
+ }
- return new Tag(id, techList, techExtras, serviceHandle);
+ return new Tag(id, techList, techExtras, serviceHandle, tagService);
}
@Override
@@ -249,7 +279,9 @@
}
};
- /*
+ /**
+ * For internal use only.
+ *
* @hide
*/
public synchronized void setConnectedTechnology(int technology) {
@@ -260,14 +292,18 @@
}
}
- /*
+ /**
+ * For internal use only.
+ *
* @hide
*/
public int getConnectedTechnology() {
return mConnectedTechnology;
}
- /*
+ /**
+ * For internal use only.
+ *
* @hide
*/
public void setTechnologyDisconnected() {
diff --git a/core/java/android/nfc/TagLostException.java b/core/java/android/nfc/TagLostException.java
new file mode 100644
index 0000000..1981d7c
--- /dev/null
+++ b/core/java/android/nfc/TagLostException.java
@@ -0,0 +1,29 @@
+/*
+ * 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 java.io.IOException;
+
+public class TagLostException extends IOException {
+ public TagLostException() {
+ super();
+ }
+
+ public TagLostException(String message) {
+ super(message);
+ }
+}
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/TransceiveResult.aidl b/core/java/android/nfc/TransceiveResult.aidl
new file mode 100644
index 0000000..98f92ee
--- /dev/null
+++ b/core/java/android/nfc/TransceiveResult.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 TransceiveResult;
diff --git a/core/java/android/nfc/TransceiveResult.java b/core/java/android/nfc/TransceiveResult.java
new file mode 100644
index 0000000..16244b8
--- /dev/null
+++ b/core/java/android/nfc/TransceiveResult.java
@@ -0,0 +1,90 @@
+/*
+ * 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;
+
+/**
+ * Class used to pipe transceive result from the NFC service.
+ *
+ * @hide
+ */
+public final class TransceiveResult implements Parcelable {
+ private final boolean mTagLost;
+ private final boolean mSuccess;
+ private final byte[] mResponseData;
+
+ public TransceiveResult(final boolean success, final boolean tagIsLost,
+ final byte[] data) {
+ mSuccess = success;
+ mTagLost = tagIsLost;
+ mResponseData = data;
+ }
+
+ public boolean isSuccessful() {
+ return mSuccess;
+ }
+
+ public boolean isTagLost() {
+ return mTagLost;
+ }
+
+ public byte[] getResponseData() {
+ return mResponseData;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mSuccess ? 1 : 0);
+ dest.writeInt(mTagLost ? 1 : 0);
+ if (mSuccess) {
+ dest.writeInt(mResponseData.length);
+ dest.writeByteArray(mResponseData);
+ }
+ }
+
+ public static final Parcelable.Creator<TransceiveResult> CREATOR =
+ new Parcelable.Creator<TransceiveResult>() {
+ @Override
+ public TransceiveResult createFromParcel(Parcel in) {
+ boolean success = (in.readInt() == 1) ? true : false;
+ boolean tagLost = (in.readInt() == 1) ? true : false;
+ byte[] responseData;
+
+ if (success) {
+ int responseLength = in.readInt();
+ responseData = new byte[responseLength];
+ in.readByteArray(responseData);
+ } else {
+ responseData = null;
+ }
+ return new TransceiveResult(success, tagLost, responseData);
+ }
+
+ @Override
+ public TransceiveResult[] newArray(int size) {
+ return new TransceiveResult[size];
+ }
+ };
+
+}
diff --git a/core/java/android/nfc/tech/BasicTagTechnology.java b/core/java/android/nfc/tech/BasicTagTechnology.java
new file mode 100644
index 0000000..32a850d
--- /dev/null
+++ b/core/java/android/nfc/tech/BasicTagTechnology.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.ErrorCodes;
+import android.nfc.Tag;
+import android.nfc.TagLostException;
+import android.nfc.TransceiveResult;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * A base class for tag technologies that are built on top of transceive().
+ */
+/* package */ abstract class BasicTagTechnology implements TagTechnology {
+ private static final String TAG = "NFC";
+
+ /*package*/ final Tag mTag;
+ /*package*/ boolean mIsConnected;
+ /*package*/ int mSelectedTechnology;
+
+ BasicTagTechnology(Tag tag, int tech) throws RemoteException {
+ mTag = tag;
+ mSelectedTechnology = tech;
+ }
+
+ @Override
+ public Tag getTag() {
+ return mTag;
+ }
+
+ /** Internal helper to throw IllegalStateException if the technology isn't connected */
+ void checkConnected() {
+ if ((mTag.getConnectedTechnology() != mSelectedTechnology) ||
+ (mTag.getConnectedTechnology() == -1)) {
+ throw new IllegalStateException("Call connect() first!");
+ }
+ }
+
+ /**
+ * Helper to indicate if {@link #connect} has succeeded.
+ * <p>
+ * Does not cause RF activity, and does not block.
+ * @return true if {@link #connect} has completed successfully and the {@link Tag} is believed
+ * to be within range. Applications must still handle {@link java.io.IOException}
+ * while using methods that require a connection in case the connection is lost after this
+ * method returns.
+ */
+ public boolean isConnected() {
+ if (!mIsConnected) {
+ return false;
+ }
+
+ try {
+ return mTag.getTagService().isPresent(mTag.getServiceHandle());
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ return false;
+ }
+ }
+
+ @Override
+ public void connect() throws IOException {
+ try {
+ int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(),
+ mSelectedTechnology);
+
+ if (errorCode == ErrorCodes.SUCCESS) {
+ // Store this in the tag object
+ mTag.setConnectedTechnology(mSelectedTechnology);
+ mIsConnected = true;
+ } else {
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ throw new IOException("NFC service died");
+ }
+ }
+
+ @Override
+ public void reconnect() throws IOException {
+ if (!mIsConnected) {
+ throw new IllegalStateException("Technology not connected yet");
+ }
+
+ try {
+ int errorCode = mTag.getTagService().reconnect(mTag.getServiceHandle());
+
+ if (errorCode != ErrorCodes.SUCCESS) {
+ mIsConnected = false;
+ mTag.setTechnologyDisconnected();
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ mIsConnected = false;
+ mTag.setTechnologyDisconnected();
+ Log.e(TAG, "NFC service dead", e);
+ throw new IOException("NFC service died");
+ }
+ }
+
+ @Override
+ 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
+ */
+ mTag.getTagService().reconnect(mTag.getServiceHandle());
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ } finally {
+ mIsConnected = false;
+ mTag.setTechnologyDisconnected();
+ }
+ }
+
+ /** Internal transceive */
+ /*package*/ byte[] transceive(byte[] data, boolean raw) throws IOException {
+ checkConnected();
+
+ try {
+ TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(),
+ data, raw);
+ if (result == null) {
+ throw new IOException("transceive failed");
+ } else {
+ if (result.isSuccessful()) {
+ return result.getResponseData();
+ } else {
+ if (result.isTagLost()) {
+ throw new TagLostException("Tag was lost.");
+ }
+ else {
+ throw new IOException("transceive failed");
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ throw new IOException("NFC service died");
+ }
+ }
+}
diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java
new file mode 100644
index 0000000..774982e
--- /dev/null
+++ b/core/java/android/nfc/tech/IsoDep.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as
+ * ISO1443-4.
+ *
+ * <p>You can acquire this kind of connection with {@link #get}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class IsoDep extends BasicTagTechnology {
+ private static final String TAG = "NFC";
+
+ /** @hide */
+ public static final String EXTRA_HI_LAYER_RESP = "hiresp";
+ /** @hide */
+ public static final String EXTRA_HIST_BYTES = "histbytes";
+
+ private byte[] mHiLayerResponse = null;
+ private byte[] mHistBytes = null;
+
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static IsoDep get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.ISO_DEP)) return null;
+ try {
+ return new IsoDep(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public IsoDep(Tag tag)
+ throws RemoteException {
+ super(tag, TagTechnology.ISO_DEP);
+ Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP);
+ if (extras != null) {
+ mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP);
+ mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
+ }
+ }
+
+ /**
+ * Sets the timeout of an IsoDep transceive transaction in milliseconds.
+ * If the transaction has not completed before the timeout,
+ * any ongoing {@link #transceive} operation will be
+ * aborted and the connection to the tag is lost. This setting is applied
+ * only to the {@link Tag} object linked to this technology and will be
+ * reset when {@link IsoDep#close} is called.
+ * The default transaction timeout is 300 milliseconds.
+ */
+ public void setTimeout(int timeout) {
+ try {
+ mTag.getTagService().setIsoDepTimeout(timeout);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ mTag.getTagService().resetIsoDepTimeout();
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service dead", e);
+ }
+ super.close();
+ }
+
+ /**
+ * Return the historical bytes if the tag is using {@link NfcA}, null otherwise.
+ */
+ public byte[] getHistoricalBytes() {
+ return mHistBytes;
+ }
+
+ /**
+ * Return the hi layer response bytes if the tag is using {@link NfcB}, null otherwise.
+ */
+ public byte[] getHiLayerResponse() {
+ return mHiLayerResponse;
+ }
+
+ /**
+ * Send data to a tag and receive the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with {@link #close}.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param data bytes to send
+ * @return bytes received in response
+ * @throws IOException if the target is lost or connection closed
+ */
+ public byte[] transceive(byte[] data) throws IOException {
+ return transceive(data, true);
+ }
+}
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
new file mode 100644
index 0000000..d337ead
--- /dev/null
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.Tag;
+import android.nfc.TagLostException;
+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).
+ *
+ * <p>Support for this technology type is optional. If the NFC stack doesn't support this technology
+ * MIFARE Classic tags will still be scanned, but will only show the NfcA technology.
+ *
+ * <p>MIFARE Classic tags have sectors that each contain blocks. The block size is constant at
+ * 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 #authenticateSectorWithKeyA(int, byte[])} or
+ * {@link #authenticateSectorWithKeyB(int, byte[])} to gain authorization for your request.
+ */
+public final class MifareClassic extends BasicTagTechnology {
+ /**
+ * The well-known default MIFARE read key. All keys are set to this at the factory.
+ * Using this key will effectively make the payload in the sector public.
+ */
+ public static final byte[] KEY_DEFAULT =
+ {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
+ /**
+ * The well-known, default MIFARE Application Directory read key.
+ */
+ public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY =
+ {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
+ /**
+ * The well-known, default read key for NDEF data on a MIFARE Classic
+ */
+ 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 contains 16 sectors, each holding 4 blocks. */
+ public static final int SIZE_1K = 1024;
+ /** The tag contains 32 sectors, each holding 4 blocks. */
+ public static final int SIZE_2K = 2048;
+ /**
+ * The tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors
+ * contain 16 blocks.
+ */
+ public static final int SIZE_4K = 4096;
+ /** The tag contains 5 sectors, each holding 4 blocks. */
+ public static final int SIZE_MINI = 320;
+
+ /** 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;
+ private int mSize;
+
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static MifareClassic get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.MIFARE_CLASSIC)) return null;
+ try {
+ return new MifareClassic(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public MifareClassic(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.MIFARE_CLASSIC);
+
+ NfcA a = NfcA.get(tag); // Mifare Classic is always based on NFC a
+
+ mIsEmulated = false;
+
+ switch (a.getSak()) {
+ 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 type of the tag, determined at discovery time */
+ public int getType() {
+ return mType;
+ }
+
+ /** 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;
+ }
+
+ /** 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;
+ }
+ }
+
+ /** Returns the total block count, determined at discovery time */
+ public int getBlockCount() {
+ return mSize / BLOCK_SIZE;
+ }
+
+ /** Returns the block count for the given sector, determined at discovery time */
+ public int getBlockCountInSector(int sectorIndex) {
+ validateSector(sectorIndex);
+
+ if (sectorIndex < 32) {
+ return 4;
+ } else {
+ return 16;
+ }
+ }
+
+ /** Return the sector index of a given block */
+ public int blockToSector(int blockIndex) {
+ validateBlock(blockIndex);
+
+ if (blockIndex < 32 * 4) {
+ return blockIndex / 4;
+ } else {
+ 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 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 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];
+
+ // First byte is the command
+ if (keyA) {
+ cmd[0] = 0x60; // phHal_eMifareAuthentA
+ } else {
+ cmd[0] = 0x61; // phHal_eMifareAuthentB
+ }
+
+ // Second byte is block address
+ // 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();
+ System.arraycopy(uid, uid.length - 4, cmd, 2, 4);
+
+ // Next 6 bytes are key
+ System.arraycopy(key, 0, cmd, 6, 6);
+
+ try {
+ if (transceive(cmd, false) != null) {
+ return true;
+ }
+ } catch (TagLostException e) {
+ throw e;
+ } catch (IOException e) {
+ // No need to deal with, will return false anyway
+ }
+ return false;
+ }
+
+ /**
+ * Read 16-byte block.
+ * <p>This requires a that the tag be connected.
+ * @throws IOException
+ */
+ public byte[] readBlock(int blockIndex) throws IOException {
+ validateBlock(blockIndex);
+ checkConnected();
+
+ byte[] cmd = { 0x30, (byte) blockIndex };
+ return transceive(cmd, false);
+ }
+
+ /**
+ * Write 16-byte block.
+ * <p>This requires a that the tag be connected.
+ * @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[] 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);
+
+ transceive(cmd, false);
+ }
+
+ /**
+ * Increment a value block, and store the result in temporary memory.
+ * @param blockIndex
+ * @throws IOException
+ */
+ public void increment(int blockIndex, int value) throws IOException {
+ validateBlock(blockIndex);
+ validateValueOperand(value);
+ checkConnected();
+
+ ByteBuffer cmd = ByteBuffer.allocate(6);
+ cmd.order(ByteOrder.LITTLE_ENDIAN);
+ cmd.put( (byte) 0xC1 );
+ cmd.put( (byte) blockIndex );
+ cmd.putInt(value);
+
+ transceive(cmd.array(), false);
+ }
+
+ /**
+ * Decrement a value block, and store the result in temporary memory.
+ * @param blockIndex
+ * @throws IOException
+ */
+ public void decrement(int blockIndex, int value) throws IOException {
+ validateBlock(blockIndex);
+ validateValueOperand(value);
+ checkConnected();
+
+ ByteBuffer cmd = ByteBuffer.allocate(6);
+ cmd.order(ByteOrder.LITTLE_ENDIAN);
+ cmd.put( (byte) 0xC0 );
+ cmd.put( (byte) blockIndex );
+ cmd.putInt(value);
+
+ transceive(cmd.array(), false);
+ }
+
+ /**
+ * Copy from temporary memory to value block.
+ * @param blockIndex
+ * @throws IOException
+ */
+ public void transfer(int blockIndex) throws IOException {
+ validateBlock(blockIndex);
+ checkConnected();
+
+ byte[] cmd = { (byte) 0xB0, (byte) blockIndex };
+
+ transceive(cmd, false);
+ }
+
+ /**
+ * Copy from value block to temporary memory.
+ * @param blockIndex
+ * @throws IOException
+ */
+ public void restore(int blockIndex) throws IOException {
+ validateBlock(blockIndex);
+ checkConnected();
+
+ byte[] cmd = { (byte) 0xC2, (byte) blockIndex };
+
+ transceive(cmd, false);
+ }
+
+ /**
+ * Send raw NfcA data to a tag and receive the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with {@link #close}.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ * <p>This requires a that the tag be connected.
+ *
+ * @param data bytes to send
+ * @return bytes received in response
+ * @throws IOException if the target is lost or connection closed
+ */
+ 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
new file mode 100644
index 0000000..b514f1c
--- /dev/null
+++ b/core/java/android/nfc/tech/MifareUltralight.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.Tag;
+import android.os.RemoteException;
+
+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 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;
+
+ /** 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;
+
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static MifareUltralight get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.MIFARE_ULTRALIGHT)) return null;
+ try {
+ return new MifareUltralight(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public MifareUltralight(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.MIFARE_ULTRALIGHT);
+
+ // Check if this could actually be a Mifare
+ NfcA a = NfcA.get(tag);
+
+ mType = TYPE_UNKNOWN;
+
+ 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.
+ * <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()
+ /**
+ * 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.
+ *
+ * @return 4 pages (16 bytes)
+ * @throws IOException
+ */
+ public byte[] readPages(int pageOffset) throws IOException {
+ validatePageOffset(pageOffset);
+ checkConnected();
+
+ byte[] cmd = { 0x30, (byte) pageOffset};
+ return transceive(cmd, false);
+ }
+
+ /**
+ * 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.
+ *
+ * @param pageOffset The offset of the page to write
+ * @param data The data to write
+ * @throws IOException
+ */
+ public void writePage(int pageOffset, byte[] data) throws IOException {
+ validatePageOffset(pageOffset);
+ checkConnected();
+
+ byte[] cmd = new byte[data.length + 2];
+ cmd[0] = (byte) 0xA2;
+ cmd[1] = (byte) pageOffset;
+ System.arraycopy(data, 0, cmd, 2, data.length);
+
+ transceive(cmd, false);
+ }
+
+ /**
+ * Send raw NfcA data to a tag and receive the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with {@link #close}.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ * <p>This requires a that the tag be connected.
+ *
+ * @param data bytes to send
+ * @return bytes received in response
+ * @throws IOException if the target is lost or connection closed
+ */
+ 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/technology/Ndef.java b/core/java/android/nfc/tech/Ndef.java
similarity index 69%
rename from core/java/android/nfc/technology/Ndef.java
rename to core/java/android/nfc/tech/Ndef.java
index 05872fe..c6804f9 100644
--- a/core/java/android/nfc/technology/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -14,30 +14,34 @@
* limitations under the License.
*/
-package android.nfc.technology;
+package android.nfc.tech;
import android.nfc.ErrorCodes;
import android.nfc.FormatException;
+import android.nfc.INfcTag;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.os.RemoteException;
+import android.util.Log;
import java.io.IOException;
/**
* 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 Tag#getTechnology(int)}.
+ * <p>You can acquire this kind of connection with {@link #get}.
*
* <p class="note"><strong>Note:</strong>
* Use of this class requires the {@link android.Manifest.permission#NFC}
* permission.
*/
public final class Ndef extends BasicTagTechnology {
+ private static final String TAG = "NFC";
+
/** @hide */
public static final int NDEF_MODE_READ_ONLY = 1;
/** @hide */
@@ -57,14 +61,12 @@
/** @hide */
public static final String EXTRA_NDEF_TYPE = "ndeftype";
- //TODO: consider removing OTHER entirely - and not allowing Ndef to
- // enumerate for tag types outside of (NFC Forum 1-4, MifareClassic)
public static final int OTHER = -1;
public static final int NFC_FORUM_TYPE_1 = 1;
public static final int NFC_FORUM_TYPE_2 = 2;
public static final int NFC_FORUM_TYPE_3 = 3;
public static final int NFC_FORUM_TYPE_4 = 4;
- public static final int MIFARE_CLASSIC = 105;
+ public static final int MIFARE_CLASSIC = 101;
private final int mMaxNdefSize;
private final int mCardState;
@@ -72,11 +74,27 @@
private final int mNdefType;
/**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static Ndef get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.NDEF)) return null;
+ try {
+ return new Ndef(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Internal constructor, to be used by NfcAdapter
* @hide
*/
- public Ndef(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
- super(adapter, tag, tech);
+ public Ndef(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.NDEF);
+ Bundle extras = tag.getTechExtras(TagTechnology.NDEF);
if (extras != null) {
mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH);
mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE);
@@ -97,15 +115,6 @@
}
/**
- * Get optional extra NDEF messages.
- * Some tags may contain extra NDEF messages, but not all
- * implementations will be able to read them.
- */
- public NdefMessage[] getExtraNdefMessage() throws IOException, FormatException {
- throw new UnsupportedOperationException();
- }
-
- /**
* Get NDEF tag type.
* <p>Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2},
* {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4},
@@ -148,11 +157,12 @@
checkConnected();
try {
+ INfcTag tagService = mTag.getTagService();
int serviceHandle = mTag.getServiceHandle();
- if (mTagService.isNdef(serviceHandle)) {
- NdefMessage msg = mTagService.ndefRead(serviceHandle);
+ if (tagService.isNdef(serviceHandle)) {
+ NdefMessage msg = tagService.ndefRead(serviceHandle);
if (msg == null) {
- int errorCode = mTagService.getLastError(serviceHandle);
+ int errorCode = tagService.getLastError(serviceHandle);
switch (errorCode) {
case ErrorCodes.ERROR_IO:
throw new IOException();
@@ -168,7 +178,7 @@
return null;
}
} catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
+ Log.e(TAG, "NFC service dead", e);
return null;
}
}
@@ -181,9 +191,10 @@
checkConnected();
try {
+ INfcTag tagService = mTag.getTagService();
int serviceHandle = mTag.getServiceHandle();
- if (mTagService.isNdef(serviceHandle)) {
- int errorCode = mTagService.ndefWrite(serviceHandle, msg);
+ if (tagService.isNdef(serviceHandle)) {
+ int errorCode = tagService.ndefWrite(serviceHandle, msg);
switch (errorCode) {
case ErrorCodes.SUCCESS:
break;
@@ -200,67 +211,54 @@
throw new IOException("Tag is not ndef");
}
} catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
+ Log.e(TAG, "NFC service dead", e);
}
}
/**
- * Attempt to write extra NDEF messages.
- * Implementations may be able to write extra NDEF
- * message after the first primary message, but it is not
- * guaranteed. Even if it can be written, other implementations
- * may not be able to read NDEF messages after the primary message.
- * It is recommended to use additional NDEF records instead.
- *
- * @throws IOException
+ * Indicates whether a tag can be made read-only with
+ * {@link #makeReadonly()}
*/
- public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException {
- checkConnected();
-
- throw new UnsupportedOperationException();
+ public boolean canMakeReadonly() {
+ if (mNdefType == NFC_FORUM_TYPE_1 || mNdefType == NFC_FORUM_TYPE_2) {
+ return true;
+ } else {
+ return false;
+ }
}
/**
- * Set the CC field to indicate this tag is read-only
+ * Sets the CC field to indicate this tag is read-only
+ * and permanently sets the lock bits to prevent any further NDEF
+ * modifications.
+ * This is a one-way process and can not be reverted!
* @throws IOException
*/
public boolean makeReadonly() throws IOException {
checkConnected();
try {
- int errorCode = mTagService.ndefMakeReadOnly(mTag.getServiceHandle());
- switch (errorCode) {
- case ErrorCodes.SUCCESS:
- return true;
- case ErrorCodes.ERROR_IO:
- throw new IOException();
- case ErrorCodes.ERROR_INVALID_PARAM:
- return false;
- default:
- // Should not happen
- throw new IOException();
- }
+ INfcTag tagService = mTag.getTagService();
+ if (tagService.isNdef(mTag.getServiceHandle())) {
+ int errorCode = tagService.ndefMakeReadOnly(mTag.getServiceHandle());
+ switch (errorCode) {
+ case ErrorCodes.SUCCESS:
+ return true;
+ case ErrorCodes.ERROR_IO:
+ throw new IOException();
+ case ErrorCodes.ERROR_INVALID_PARAM:
+ return false;
+ default:
+ // Should not happen
+ throw new IOException();
+ }
+ }
+ else {
+ throw new IOException("Tag is not ndef");
+ }
} catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
+ Log.e(TAG, "NFC service dead", e);
return false;
}
}
-
- /**
- * Attempt to use tag specific technology to really make
- * the tag read-only
- * For NFC Forum Type 1 and 2 only.
- */
- public void makeLowLevelReadonly() {
- checkConnected();
-
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] transceive(byte[] data) {
- checkConnected();
-
- throw new UnsupportedOperationException();
- }
}
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/tech/NdefFormatable.java
similarity index 70%
rename from core/java/android/nfc/technology/NdefFormatable.java
rename to core/java/android/nfc/tech/NdefFormatable.java
index 222c558..2919c43 100644
--- a/core/java/android/nfc/technology/NdefFormatable.java
+++ b/core/java/android/nfc/tech/NdefFormatable.java
@@ -14,34 +14,52 @@
* limitations under the License.
*/
-package android.nfc.technology;
+package android.nfc.tech;
import android.nfc.ErrorCodes;
import android.nfc.FormatException;
+import android.nfc.INfcTag;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
-import android.os.Bundle;
import android.os.RemoteException;
+import android.util.Log;
import java.io.IOException;
/**
* An interface to a {@link Tag} allowing to format the tag as NDEF.
*
- * <p>You can acquire this kind of interface with {@link Tag#getTechnology(int)}.
+ * <p>You can acquire this kind of connection with {@link #get}.
*
* <p class="note"><strong>Note:</strong>
* Use of this class requires the {@link android.Manifest.permission#NFC}
* permission.
*/
public final class NdefFormatable extends BasicTagTechnology {
+ private static final String TAG = "NFC";
+
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static NdefFormatable get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.NDEF_FORMATABLE)) return null;
+ try {
+ return new NdefFormatable(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
/**
* Internal constructor, to be used by NfcAdapter
* @hide
*/
- public NdefFormatable(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
- super(adapter, tag, tech);
+ public NdefFormatable(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.NDEF_FORMATABLE);
}
/**
@@ -52,10 +70,9 @@
checkConnected();
try {
- byte[] DEFAULT_KEY = {(byte)0xFF,(byte)0xFF,(byte)0xFF,
- (byte)0xFF,(byte)0xFF,(byte)0xFF};
int serviceHandle = mTag.getServiceHandle();
- int errorCode = mTagService.formatNdef(serviceHandle, DEFAULT_KEY);
+ INfcTag tagService = mTag.getTagService();
+ int errorCode = tagService.formatNdef(serviceHandle, MifareClassic.KEY_DEFAULT);
switch (errorCode) {
case ErrorCodes.SUCCESS:
break;
@@ -68,8 +85,8 @@
throw new IOException();
}
// Now check and see if the format worked
- if (mTagService.isNdef(serviceHandle)) {
- errorCode = mTagService.ndefWrite(serviceHandle, firstMessage);
+ if (tagService.isNdef(serviceHandle)) {
+ errorCode = tagService.ndefWrite(serviceHandle, firstMessage);
switch (errorCode) {
case ErrorCodes.SUCCESS:
break;
@@ -85,14 +102,7 @@
throw new IOException();
}
} catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
+ Log.e(TAG, "NFC service dead", e);
}
}
-
- @Override
- public byte[] transceive(byte[] data) {
- checkConnected();
-
- throw new UnsupportedOperationException();
- }
}
diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java
new file mode 100644
index 0000000..24badc4
--- /dev/null
+++ b/core/java/android/nfc/tech/NfcA.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * A low-level connection to a {@link Tag} using the NFC-A technology, also known as
+ * ISO1443-3A.
+ *
+ * <p>You can acquire this kind of connection with {@link #get}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NfcA extends BasicTagTechnology {
+ /** @hide */
+ public static final String EXTRA_SAK = "sak";
+ /** @hide */
+ public static final String EXTRA_ATQA = "atqa";
+
+ private short mSak;
+ private byte[] mAtqa;
+
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static NfcA get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.NFC_A)) return null;
+ try {
+ return new NfcA(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public NfcA(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.NFC_A);
+ Bundle extras = tag.getTechExtras(TagTechnology.NFC_A);
+ mSak = extras.getShort(EXTRA_SAK);
+ mAtqa = extras.getByteArray(EXTRA_ATQA);
+ }
+
+ /**
+ * Returns the ATQA/SENS_RES bytes discovered at tag discovery.
+ */
+ public byte[] getAtqa() {
+ return mAtqa;
+ }
+
+ /**
+ * Returns the SAK/SEL_RES discovered at tag discovery.
+ */
+ public short getSak() {
+ return mSak;
+ }
+
+ /**
+ * Send data to a tag and receive the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with {@link #close}.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param data bytes to send
+ * @return bytes received in response
+ * @throws IOException if the target is lost or connection closed
+ */
+ public byte[] transceive(byte[] data) throws IOException {
+ return transceive(data, true);
+ }
+}
diff --git a/core/java/android/nfc/technology/NfcB.java b/core/java/android/nfc/tech/NfcB.java
similarity index 60%
rename from core/java/android/nfc/technology/NfcB.java
rename to core/java/android/nfc/tech/NfcB.java
index 267c94d..abeef32 100644
--- a/core/java/android/nfc/technology/NfcB.java
+++ b/core/java/android/nfc/tech/NfcB.java
@@ -14,18 +14,19 @@
* limitations under the License.
*/
-package android.nfc.technology;
+package android.nfc.tech;
-import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Bundle;
import android.os.RemoteException;
+import java.io.IOException;
+
/**
* A low-level connection to a {@link Tag} using the NFC-B technology, also known as
* ISO1443-3B.
*
- * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
+ * <p>You can acquire this kind of connection with {@link #get}.
* Use this class to send and receive data with {@link #transceive transceive()}.
*
* <p>Applications must implement their own protocol stack on top of
@@ -44,9 +45,25 @@
private byte[] mAppData;
private byte[] mProtInfo;
- public NfcB(NfcAdapter adapter, Tag tag, Bundle extras)
- throws RemoteException {
- super(adapter, tag, TagTechnology.NFC_B);
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static NfcB get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.NFC_B)) return null;
+ try {
+ return new NfcB(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public NfcB(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.NFC_B);
+ Bundle extras = tag.getTechExtras(TagTechnology.NFC_B);
mAppData = extras.getByteArray(EXTRA_APPDATA);
mProtInfo = extras.getByteArray(EXTRA_PROTINFO);
}
@@ -67,4 +84,18 @@
return mProtInfo;
}
+ /**
+ * Send data to a tag and receive the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with {@link #close}.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param data bytes to send
+ * @return bytes received in response
+ * @throws IOException if the target is lost or connection closed
+ */
+ public byte[] transceive(byte[] data) throws IOException {
+ return transceive(data, true);
+ }
}
diff --git a/core/java/android/nfc/tech/NfcF.java b/core/java/android/nfc/tech/NfcF.java
new file mode 100644
index 0000000..f617739
--- /dev/null
+++ b/core/java/android/nfc/tech/NfcF.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * A low-level connection to a {@link Tag} using the NFC-F technology, also known as
+ * JIS6319-4.
+ *
+ * <p>You can acquire this kind of connection with {@link #get}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NfcF extends BasicTagTechnology {
+ /** @hide */
+ public static final String EXTRA_SC = "systemcode";
+ /** @hide */
+ public static final String EXTRA_PMM = "pmm";
+
+ private byte[] mSystemCode = null;
+ private byte[] mManufacturer = null;
+
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static NfcF get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.NFC_F)) return null;
+ try {
+ return new NfcF(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public NfcF(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.NFC_F);
+ Bundle extras = tag.getTechExtras(TagTechnology.NFC_F);
+ if (extras != null) {
+ mSystemCode = extras.getByteArray(EXTRA_SC);
+ mManufacturer = extras.getByteArray(EXTRA_PMM);
+ }
+ }
+
+ public byte[] getSystemCode() {
+ return mSystemCode;
+ }
+
+ public byte[] getManufacturer() {
+ return mManufacturer;
+ }
+
+ /**
+ * Send data to a tag and receive the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with {@link #close}.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param data bytes to send
+ * @return bytes received in response
+ * @throws IOException if the target is lost or connection closed
+ */
+ public byte[] transceive(byte[] data) throws IOException {
+ return transceive(data, true);
+ }
+}
diff --git a/core/java/android/nfc/tech/NfcV.java b/core/java/android/nfc/tech/NfcV.java
new file mode 100644
index 0000000..8e1f066
--- /dev/null
+++ b/core/java/android/nfc/tech/NfcV.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * A low-level connection to a {@link Tag} using NFC vicinity technology, also known as
+ * ISO15693.
+ *
+ * <p>You can acquire this kind of connection with {@link #get}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NfcV extends BasicTagTechnology {
+ /** @hide */
+ public static final String EXTRA_RESP_FLAGS = "respflags";
+
+ /** @hide */
+ public static final String EXTRA_DSFID = "dsfid";
+
+ private byte mRespFlags;
+ private byte mDsfId;
+
+ /**
+ * Returns an instance of this tech for the given tag. If the tag doesn't support
+ * this tech type null is returned.
+ *
+ * @param tag The tag to get the tech from
+ */
+ public static NfcV get(Tag tag) {
+ if (!tag.hasTech(TagTechnology.NFC_V)) return null;
+ try {
+ return new NfcV(tag);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /** @hide */
+ public NfcV(Tag tag) throws RemoteException {
+ super(tag, TagTechnology.NFC_V);
+ Bundle extras = tag.getTechExtras(TagTechnology.NFC_V);
+ mRespFlags = extras.getByte(EXTRA_RESP_FLAGS);
+ mDsfId = extras.getByte(EXTRA_DSFID);
+ }
+
+ public byte getResponseFlags() {
+ return mRespFlags;
+ }
+
+ public byte getDsfId() {
+ return mDsfId;
+ }
+
+ /**
+ * Send data to a tag and receive the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with {@link #close}.
+ * <p>Requires {@link android.Manifest.permission#NFC} permission.
+ *
+ * @param data bytes to send
+ * @return bytes received in response
+ * @throws IOException if the target is lost or connection closed
+ */
+ public byte[] transceive(byte[] data) throws IOException {
+ return transceive(data, true);
+ }
+}
diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java
new file mode 100644
index 0000000..c8ccdcf
--- /dev/null
+++ b/core/java/android/nfc/tech/TagTechnology.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010 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.tech;
+
+import android.nfc.Tag;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+public interface TagTechnology extends Closeable {
+ /**
+ * This technology is an instance of {@link NfcA}.
+ * <p>Support for this technology type is mandatory.
+ * @hide
+ */
+ public static final int NFC_A = 1;
+
+ /**
+ * This technology is an instance of {@link NfcB}.
+ * <p>Support for this technology type is mandatory.
+ * @hide
+ */
+ public static final int NFC_B = 2;
+
+ /**
+ * This technology is an instance of {@link IsoDep}.
+ * <p>Support for this technology type is mandatory.
+ * @hide
+ */
+ public static final int ISO_DEP = 3;
+
+ /**
+ * This technology is an instance of {@link NfcF}.
+ * <p>Support for this technology type is mandatory.
+ * @hide
+ */
+ public static final int NFC_F = 4;
+
+ /**
+ * This technology is an instance of {@link NfcV}.
+ * <p>Support for this technology type is mandatory.
+ * @hide
+ */
+ public static final int NFC_V = 5;
+
+ /**
+ * This technology is an instance of {@link Ndef}.
+ * <p>Support for this technology type is mandatory.
+ * @hide
+ */
+ public static final int NDEF = 6;
+
+ /**
+ * This technology is an instance of {@link NdefFormatable}.
+ * <p>Support for this technology type is mandatory.
+ * @hide
+ */
+ public static final int NDEF_FORMATABLE = 7;
+
+ /**
+ * This technology is an instance of {@link MifareClassic}.
+ * <p>Support for this technology type is optional. If a stack doesn't support this technology
+ * type tags using it must still be discovered and present the lower level radio interface
+ * technologies in use.
+ * @hide
+ */
+ public static final int MIFARE_CLASSIC = 8;
+
+ /**
+ * This technology is an instance of {@link MifareUltralight}.
+ * <p>Support for this technology type is optional. If a stack doesn't support this technology
+ * type tags using it must still be discovered and present the lower level radio interface
+ * technologies in use.
+ * @hide
+ */
+ public static final int MIFARE_ULTRALIGHT = 9;
+
+ /**
+ * Get the {@link Tag} object this technology came from.
+ */
+ public Tag getTag();
+
+ /**
+ * Opens a connection to the {@link Tag} enabling interactive commands. The command set
+ * varies by the technology type.
+ *
+ * <p>This method blocks until the connection has been established.
+ *
+ * <p>A call to {@link #close} from another thread will cancel a blocked call and cause an
+ * IOException to be thrown on the thread that is blocked.
+ *
+ * @see #reconnect()
+ * @see #close()
+ * @throws IOException if the target is lost, or connect canceled
+ */
+ public void connect() throws IOException;
+
+ /**
+ * Re-connect to the {@link Tag} associated with this connection. Reconnecting to a tag can be
+ * used to reset the state of the tag itself.
+ *
+ * <p>This method blocks until the connection is re-established.
+ *
+ * <p>A call to {@link #close} from another thread will cancel a blocked call and cause an
+ * IOException to be thrown on the thread that is blocked.
+ *
+ * @see #connect()
+ * @see #close()
+ * @throws IOException
+ */
+ public void reconnect() throws IOException;
+
+ /**
+ * Closes the connection to the {@link Tag}. This call is non-blocking and causes all blocking
+ * operations such as {@link #connect} to be canceled and immediately throw
+ * {@link java.io.IOException} on the thread that is blocked.
+ *
+ * <p>
+ * Once this method is called, this object cannot be re-used and should be discarded. Further
+ * calls to {@link #connect} will fail.
+ *
+ * @see #connect()
+ * @see #reconnect()
+ */
+ public void close() throws IOException;
+}
diff --git a/core/java/android/nfc/technology/BasicTagTechnology.java b/core/java/android/nfc/technology/BasicTagTechnology.java
deleted file mode 100644
index 553f6ec..0000000
--- a/core/java/android/nfc/technology/BasicTagTechnology.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import java.io.IOException;
-
-import android.nfc.INfcAdapter;
-import android.nfc.INfcTag;
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.nfc.ErrorCodes;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * A base class for tag technologies that are built on top of transceive().
- */
-/* package */ abstract class BasicTagTechnology implements TagTechnology {
-
- /*package*/ final Tag mTag;
- /*package*/ boolean mIsConnected;
- /*package*/ int mSelectedTechnology;
- private final NfcAdapter mAdapter;
-
- // Following fields are final after construction, except for
- // during attemptDeadServiceRecovery() when NFC crashes.
- // Not locked - we accept a best effort attempt when NFC crashes.
- /*package*/ INfcAdapter mService;
- /*package*/ INfcTag mTagService;
-
- private static final String TAG = "NFC";
-
- /**
- * @hide
- */
- public BasicTagTechnology(NfcAdapter adapter, 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);
- }
-
- mAdapter = adapter;
- mService = mAdapter.getService();
- try {
- mTagService = mService.getNfcTagInterface();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
- mTag = tag;
- mSelectedTechnology = tech;
- }
-
- /**
- * @hide
- */
- public BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException {
- this(adapter, tag, tag.getTechnologyList()[0]);
- }
-
- /** NFC service dead - attempt best effort recovery */
- /*package*/ void attemptDeadServiceRecovery(Exception e) {
- mAdapter.attemptDeadServiceRecovery(e);
- /* assigning to mService is not thread-safe, but this is best-effort code
- * and on a well-behaved system should never happen */
- mService = mAdapter.getService();
- try {
- mTagService = mService.getNfcTagInterface();
- } catch (RemoteException e2) {
- Log.e(TAG, "second RemoteException trying to recover from dead NFC service", e2);
- }
- }
-
- /**
- * Get the {@link Tag} this connection is associated with.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- */
- @Override
- public Tag getTag() {
- return mTag;
- }
-
- public void checkConnected() {
- if ((mTag.getConnectedTechnology() != getTechnologyId()) ||
- (mTag.getConnectedTechnology() == -1)) {
- throw new IllegalStateException("Call connect() first!");
- }
- }
-
- /**
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- */
- @Override
- public int getTechnologyId() {
- return mSelectedTechnology;
- }
-
- /**
- * Helper to indicate if {@link #transceive transceive()} calls might succeed.
- * <p>
- * Does not cause RF activity, and does not block.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- * @return true if {@link #connect} has completed successfully and the {@link Tag} is believed
- * to be within range. Applications must still handle {@link java.io.IOException}
- * while using {@link #transceive transceive()}, in case connection is lost after this method
- * returns true.
- */
- public boolean isConnected() {
- if (!mIsConnected) {
- return false;
- }
-
- try {
- return mTagService.isPresent(mTag.getServiceHandle());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- return false;
- }
- }
-
- /**
- * Connect to the {@link Tag} associated with this connection.
- * <p>
- * This method blocks until the connection is established.
- * <p>
- * {@link #close} can be called from another thread to cancel this connection
- * attempt.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- * @throws IOException if the target is lost, or connect canceled
- */
- @Override
- public void connect() throws IOException {
- try {
- int errorCode = mTagService.connect(mTag.getServiceHandle(), getTechnologyId());
-
- if (errorCode == ErrorCodes.SUCCESS) {
- // Store this in the tag object
- mTag.setConnectedTechnology(getTechnologyId());
- mIsConnected = true;
- } else {
- throw new IOException();
- }
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- throw new IOException("NFC service died");
- }
- }
-
- /**
- * Re-connect to the {@link Tag} associated with this connection.
- * <p>
- * Reconnecting to a tag can be used to reset the state of the tag itself.
- * This method blocks until the connection is re-established.
- * <p>
- * {@link #close} can be called from another thread to cancel this connection
- * attempt.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- * @throws IOException if the target is lost, or connect canceled
- */
- @Override
- public void reconnect() throws IOException {
- if (!mIsConnected) {
- throw new IllegalStateException("Technology not connected yet");
- } else {
- try {
- int errorCode = mTagService.reconnect(mTag.getServiceHandle());
-
- if (errorCode != ErrorCodes.SUCCESS) {
- mIsConnected = false;
- mTag.setTechnologyDisconnected();
- throw new IOException();
- }
- } catch (RemoteException e) {
- mIsConnected = false;
- mTag.setTechnologyDisconnected();
- attemptDeadServiceRecovery(e);
- throw new IOException("NFC service died");
- }
- }
- }
-
- /**
- * Close this connection.
- * <p>
- * Causes blocking operations such as {@link #transceive transceive()} or {@link #connect} to
- * be canceled and immediately throw {@link java.io.IOException}.
- * <p>
- * Once this method is called, this object cannot be re-used and should be discarded. Further
- * calls to {@link #transceive transceive()} or {@link #connect} will fail.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- */
- @Override
- public void close() {
- try {
- /* Note that we don't want to physically disconnect the tag,
- * but just reconnect to it to reset its state
- */
- mTagService.reconnect(mTag.getServiceHandle());
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- } finally {
- mIsConnected = false;
- mTag.setTechnologyDisconnected();
- }
- }
-
- /**
- * Send data to a tag and receive the response.
- * <p>
- * This method will block until the response is received. It can be canceled
- * with {@link #close}.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- *
- * @param data bytes to send
- * @return bytes received in response
- * @throws IOException if the target is lost or connection closed
- */
- public byte[] transceive(byte[] data) throws IOException {
- checkConnected();
-
- try {
- byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, true);
- if (response == null) {
- throw new IOException("transceive failed");
- }
- return response;
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- throw new IOException("NFC service died");
- }
- }
-}
diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java
deleted file mode 100644
index 32a7542..0000000
--- a/core/java/android/nfc/technology/IsoDep.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as
- * ISO1443-4.
- *
- * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
- * Use this class to send and receive data with {@link #transceive transceive()}.
- *
- * <p>Applications must implement their own protocol stack on top of
- * {@link #transceive transceive()}.
- *
- * <p class="note"><strong>Note:</strong>
- * Use of this class requires the {@link android.Manifest.permission#NFC}
- * permission.
- */
-public final class IsoDep extends BasicTagTechnology {
- /** @hide */
- public static final String EXTRA_HI_LAYER_RESP = "hiresp";
- /** @hide */
- public static final String EXTRA_HIST_BYTES = "histbytes";
-
- private byte[] mHiLayerResponse = null;
- private byte[] mHistBytes = null;
-
- public IsoDep(NfcAdapter adapter, Tag tag, Bundle extras)
- throws RemoteException {
- super(adapter, tag, TagTechnology.ISO_DEP);
- if (extras != null) {
- mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP);
- mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
- }
- }
-
- /**
- * 3A only
- */
- public byte[] getHistoricalBytes() { return mHistBytes; }
-
- /**
- * 3B only
- */
- public byte[] getHiLayerResponse() { return mHiLayerResponse; }
-}
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
deleted file mode 100644
index 799f0a78..0000000
--- a/core/java/android/nfc/technology/MifareClassic.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import java.io.IOException;
-
-/**
- * Concrete class for TagTechnology.MIFARE_CLASSIC
- *
- * Mifare classic has n sectors, with varying sizes, although
- * they are at least the same pattern for any one mifare classic
- * product. Each sector has two keys. Authentication with the correct
- * key is needed before access to any sector.
- *
- * Each sector has k blocks.
- * Block size is constant across the whole mifare classic family.
- */
-public final class MifareClassic extends BasicTagTechnology {
- /**
- * The well-known, default MIFARE read key.
- * Use this key to effectively make the payload in this sector
- * public.
- */
- public static final byte[] KEY_DEFAULT =
- {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
- /**
- * The well-known, default Mifare Application Directory read key.
- */
- public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY =
- {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
- /**
- * The well-known, default read key for NDEF data on a Mifare Classic
- */
- public static final byte[] KEY_NFC_FORUM =
- {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
-
- public static final int TYPE_CLASSIC = 0;
- public static final int TYPE_PLUS = 1;
- public static final int TYPE_PRO = 2;
- public static final int TYPE_DESFIRE = 3;
- public static final int TYPE_ULTRALIGHT = 4;
- public static final int TYPE_UNKNOWN = 5;
-
- public static final int SIZE_1K = 1024;
- public static final int SIZE_2K = 2048;
- public static final int SIZE_4K = 4096;
- public static final int SIZE_MINI = 320;
- public static final int SIZE_UNKNOWN = 0;
-
- private boolean mIsEmulated;
- private int mType;
- private int mSize;
-
- public MifareClassic(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
- super(adapter, tag, TagTechnology.MIFARE_CLASSIC);
-
- // Check if this could actually be a Mifare
- NfcA a = (NfcA) tag.getTechnology(adapter, TagTechnology.NFC_A);
- //short[] ATQA = getATQA(tag);
-
- mIsEmulated = false;
- mType = TYPE_UNKNOWN;
- mSize = SIZE_UNKNOWN;
-
- switch (a.getSak()) {
- case 0x00:
- // could be UL or UL-C
- mType = TYPE_ULTRALIGHT;
- break;
- 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
- mType = TYPE_DESFIRE;
- } 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;
- default:
- // Unknown mifare
- mType = TYPE_UNKNOWN;
- mSize = SIZE_UNKNOWN;
- break;
- }
- }
-
- // Immutable data known at discovery time
- public int getSize() {
- return mSize;
- }
-
- public int getType() {
- return mType;
- }
-
- public boolean isEmulated() {
- return mIsEmulated;
- }
-
- 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;
- }
- }
- }
-
- public int getSectorSize(int sector) {
- return getBlockCount(sector) * 16;
- }
-
- public int getTotalBlockCount() {
- int totalBlocks = 0;
- for (int sec = 0; sec < getSectorCount(); sec++) {
- totalBlocks += getSectorSize(sec);
- }
-
- return totalBlocks;
- }
-
- public int getBlockCount(int sector) {
- if (sector >= getSectorCount()) {
- throw new IllegalArgumentException("this card only has " + getSectorCount() +
- " sectors");
- }
-
- if (sector <= 32) {
- return 4;
- } else {
- return 16;
- }
- }
-
- private byte firstBlockInSector(int sector) {
- if (sector < 32) {
- return (byte) ((sector * 4) & 0xff);
- } else {
- return (byte) ((32 * 4 + ((sector - 32) * 16)) & 0xff);
- }
- }
-
- // Methods that require connect()
- /**
- * Authenticate for a given block.
- * Note that this will authenticate the entire sector the block belongs to.
- */
- public boolean authenticateBlock(int block, byte[] key, boolean keyA) {
- checkConnected();
-
- byte[] cmd = new byte[12];
-
- // First byte is the command
- if (keyA) {
- cmd[0] = 0x60; // phHal_eMifareAuthentA
- } else {
- cmd[0] = 0x61; // phHal_eMifareAuthentB
- }
-
- // Second byte is block address
- cmd[1] = (byte) block;
-
- // Next 4 bytes are last 4 bytes of UID
- byte[] uid = getTag().getId();
- System.arraycopy(uid, uid.length - 4, cmd, 2, 4);
-
- // Next 6 bytes are key
- System.arraycopy(key, 0, cmd, 6, 6);
-
- try {
- if ((transceive(cmd) != null)) {
- return true;
- }
- } catch (IOException e) {
- // No need to deal with, will return false anyway
- }
- return false;
- }
-
- /**
- * Authenticate for a given sector.
- */
- public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
- 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.
- * @throws IOException
- */
- public byte[] readBlock(int sector, int block) throws IOException {
- checkConnected();
-
- byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
- return readBlock(addr);
-
- }
-
- /**
- * Reads absolute block index.
- * @throws IOException
- */
- public byte[] readBlock(int block) throws IOException {
- checkConnected();
-
- byte addr = (byte) block;
- byte[] blockread_cmd = { 0x30, addr };
-
- return transceive(blockread_cmd);
- }
-
- /**
- * Writes absolute block index.
- * @throws IOException
- */
- public void writeBlock(int block, byte[] data) throws IOException {
- 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);
-
- transceive(blockwrite_cmd);
- }
-
- /**
- * Writes relative block in sector.
- * @throws IOException
- */
- public void writeBlock(int sector, int block, byte[] data) throws IOException {
- checkConnected();
-
- byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
-
- writeBlock(addr, data);
- }
-
- public void increment(int block) throws IOException {
- checkConnected();
-
- byte addr = (byte) block;
- byte[] incr_cmd = { (byte) 0xC1, (byte) block };
-
- transceive(incr_cmd);
- }
-
- public void decrement(int block) throws IOException {
- checkConnected();
-
- byte addr = (byte) block;
- byte[] decr_cmd = { (byte) 0xC0, (byte) block };
-
- transceive(decr_cmd);
- }
-
- public void transfer(int block) throws IOException {
- checkConnected();
-
- byte addr = (byte) block;
- byte[] trans_cmd = { (byte) 0xB0, (byte) block };
-
- transceive(trans_cmd);
- }
-
- public void restore(int block) throws IOException {
- checkConnected();
-
- byte addr = (byte) block;
- byte[] rest_cmd = { (byte) 0xC2, (byte) block };
-
- transceive(rest_cmd);
- }
-
- /**
- * Send data to a tag and receive the response.
- * <p>
- * This method will block until the response is received. It can be canceled
- * with {@link #close}.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- *
- * @param data bytes to send
- * @return bytes received in response
- * @throws IOException if the target is lost or connection closed
- */
- @Override
- public byte[] transceive(byte[] data) throws IOException {
- checkConnected();
-
- try {
- byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
- if (response == null) {
- throw new IOException("transceive failed");
- }
- return response;
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- throw new IOException("NFC service died");
- }
- }
-}
diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java
deleted file mode 100644
index 7103b4d..0000000
--- a/core/java/android/nfc/technology/MifareUltralight.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import java.io.IOException;
-
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * Concrete class for TagTechnology.MIFARE_ULTRALIGHT
- *
- * Mifare classic has n sectors, with varying sizes, although
- * they are at least the same pattern for any one mifare classic
- * product. Each sector has two keys. Authentication with the correct
- * key is needed before access to any sector.
- *
- * Each sector has k blocks.
- * Block size is constant across the whole mifare classic family.
- */
-public final class MifareUltralight extends BasicTagTechnology {
- public static final int TYPE_ULTRALIGHT = 1;
- public static final int TYPE_ULTRALIGHT_C = 2;
- public static final int TYPE_UNKNOWN = 10;
-
- private static final int NXP_MANUFACTURER_ID = 0x04;
-
- private int mType;
-
- public MifareUltralight(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
- super(adapter, tag, TagTechnology.MIFARE_ULTRALIGHT);
-
- // Check if this could actually be a Mifare
- NfcA a = (NfcA) tag.getTechnology(adapter, TagTechnology.NFC_A);
-
- mType = TYPE_UNKNOWN;
-
- if( a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID ) {
- // could be UL or UL-C
- mType = TYPE_ULTRALIGHT;
- }
- }
-
- public int getType() {
- return mType;
- }
-
- // Methods that require connect()
- /**
- * @throws IOException
- */
- public byte[] readBlock(int block) throws IOException {
- checkConnected();
-
- byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead
- return transceive(blockread_cmd);
- }
-
- /**
- * @throws IOException
- */
- public byte[] readOTP() throws IOException {
- checkConnected();
-
- return readBlock(3); // OTP is at page 3
- }
-
- public void writePage(int block, byte[] data) throws IOException {
- checkConnected();
-
- byte[] pagewrite_cmd = new byte[data.length + 2];
- pagewrite_cmd[0] = (byte) 0xA2;
- pagewrite_cmd[1] = (byte) block;
- System.arraycopy(data, 0, pagewrite_cmd, 2, data.length);
-
- transceive(pagewrite_cmd);
- }
-
- public void writeBlock(int block, byte[] data) throws IOException {
- checkConnected();
-
- byte[] blockwrite_cmd = new byte[data.length + 2];
- blockwrite_cmd[0] = (byte) 0xA0;
- blockwrite_cmd[1] = (byte) block;
- System.arraycopy(data, 0, blockwrite_cmd, 2, data.length);
-
- transceive(blockwrite_cmd);
- }
-
- /**
- * Send data to a tag and receive the response.
- * <p>
- * This method will block until the response is received. It can be canceled
- * with {@link #close}.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- *
- * @param data bytes to send
- * @return bytes received in response
- * @throws IOException if the target is lost or connection closed
- */
- @Override
- public byte[] transceive(byte[] data) throws IOException {
- checkConnected();
-
- try {
- byte[] response = mTagService.transceive(mTag.getServiceHandle(), data, false);
- if (response == null) {
- throw new IOException("transceive failed");
- }
- return response;
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- throw new IOException("NFC service died");
- }
- }
-
-}
diff --git a/core/java/android/nfc/technology/NfcA.java b/core/java/android/nfc/technology/NfcA.java
deleted file mode 100644
index ef46762..0000000
--- a/core/java/android/nfc/technology/NfcA.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * A low-level connection to a {@link Tag} using the NFC-A technology, also known as
- * ISO1443-3A.
- *
- * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
- * Use this class to send and receive data with {@link #transceive transceive()}.
- *
- * <p>Applications must implement their own protocol stack on top of
- * {@link #transceive transceive()}.
- *
- * <p class="note"><strong>Note:</strong>
- * Use of this class requires the {@link android.Manifest.permission#NFC}
- * permission.
- */
-public final class NfcA extends BasicTagTechnology {
- /** @hide */
- public static final String EXTRA_SAK = "sak";
- /** @hide */
- public static final String EXTRA_ATQA = "atqa";
-
- private short mSak;
- private byte[] mAtqa;
-
- public NfcA(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
- super(adapter, tag, TagTechnology.NFC_A);
- mSak = extras.getShort(EXTRA_SAK);
- mAtqa = extras.getByteArray(EXTRA_ATQA);
- }
-
- /**
- * Returns the ATQA/SENS_RES bytes discovered at tag discovery.
- */
- public byte[] getAtqa() {
- return mAtqa;
- }
-
- /**
- * Returns the SAK/SEL_RES discovered at tag discovery.
- */
- public short getSak() {
- return mSak;
- }
-}
diff --git a/core/java/android/nfc/technology/NfcF.java b/core/java/android/nfc/technology/NfcF.java
deleted file mode 100644
index 6741ac8..0000000
--- a/core/java/android/nfc/technology/NfcF.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * A low-level connection to a {@link Tag} using the NFC-F technology, also known as
- * JIS6319-4.
- *
- * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
- * Use this class to send and receive data with {@link #transceive transceive()}.
- *
- * <p>Applications must implement their own protocol stack on top of
- * {@link #transceive transceive()}.
- *
- * <p class="note"><strong>Note:</strong>
- * Use of this class requires the {@link android.Manifest.permission#NFC}
- * permission.
- */
-public final class NfcF extends BasicTagTechnology {
- /** @hide */
- public static final String EXTRA_SC = "systemcode";
- /** @hide */
- public static final String EXTRA_PMM = "pmm";
-
- private byte[] mSystemCode = null;
- private byte[] mManufacturer = null;
-
- public NfcF(NfcAdapter adapter, Tag tag, Bundle extras)
- throws RemoteException {
- super(adapter, tag, TagTechnology.NFC_F);
- if (extras != null) {
- mSystemCode = extras.getByteArray(EXTRA_SC);
- mManufacturer = extras.getByteArray(EXTRA_PMM);
- }
- }
-
- public byte[] getSystemCode() {
- return mSystemCode;
- }
-
- public byte[] getManufacturer() {
- return mManufacturer;
- }
-}
diff --git a/core/java/android/nfc/technology/NfcV.java b/core/java/android/nfc/technology/NfcV.java
deleted file mode 100644
index 460de6a..0000000
--- a/core/java/android/nfc/technology/NfcV.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import android.nfc.NfcAdapter;
-import android.nfc.Tag;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * A low-level connection to a {@link Tag} using the NFC-V technology, also known as
- * ISO15693.
- *
- * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
- * Use this class to send and receive data with {@link #transceive transceive()}.
- *
- * <p>Applications must implement their own protocol stack on top of
- * {@link #transceive transceive()}.
- *
- * <p class="note"><strong>Note:</strong>
- * Use of this class requires the {@link android.Manifest.permission#NFC}
- * permission.
- */
-public final class NfcV extends BasicTagTechnology {
- /** @hide */
- public static final String EXTRA_RESP_FLAGS = "respflags";
-
- /** @hide */
- public static final String EXTRA_DSFID = "dsfid";
-
- private byte mRespFlags;
- private byte mDsfId;
-
- public NfcV(NfcAdapter adapter, Tag tag, Bundle extras)
- throws RemoteException {
- super(adapter, tag, TagTechnology.NFC_V);
- mRespFlags = extras.getByte(EXTRA_RESP_FLAGS);
- mDsfId = extras.getByte(EXTRA_DSFID);
- }
-
- public byte getResponseFlags() {
- return mRespFlags;
- }
-
- public byte getDsfId() {
- return mDsfId;
- }
-}
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
deleted file mode 100644
index 62216c1..0000000
--- a/core/java/android/nfc/technology/TagTechnology.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2010 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.technology;
-
-import android.nfc.Tag;
-
-import java.io.IOException;
-
-public interface TagTechnology {
- /**
- * This object is an instance of {@link NfcA}
- */
- public static final int NFC_A = 1;
-
- /**
- * This object is an instance of {@link NfcB}
- */
- public static final int NFC_B = 2;
-
- /**
- * This object is an instance of {@link IsoDep}
- */
- public static final int ISO_DEP = 3;
-
- /**
- * This object is an instance of {@link NfcF}
- */
- public static final int NFC_F = 4;
-
- /**
- * This object is an instance of {@link NfcV}
- */
- public static final int NFC_V = 5;
-
- /**
- * This object is an instance of {@link Ndef}
- */
- public static final int NDEF = 6;
-
- /**
- * This object is an instance of {@link NdefFormatable}
- */
- public static final int NDEF_FORMATABLE = 7;
-
- /**
- * This object is an instance of {@link MifareClassic}
- */
- public static final int MIFARE_CLASSIC = 8;
-
- /**
- * This object is an instance of {@link MifareUltralight}
- */
- public static final int MIFARE_ULTRALIGHT = 9;
-
- /**
- * Returns the technology type for this tag connection.
- */
- public int getTechnologyId();
-
- /**
- * Get the backing tag object.
- */
- public Tag getTag();
-
- /**
- * @throws IOException
- */
- public void connect() throws IOException;
-
- /**
- * @throws IOException
- */
- public void reconnect() throws IOException;
-
- /**
- * Non-blocking. Immediately causes all blocking calls
- * to throw IOException.
- */
- public void close();
-}
diff --git a/core/java/android/nfc/technology/package.html b/core/java/android/nfc/technology/package.html
deleted file mode 100644
index 26b8a32..0000000
--- a/core/java/android/nfc/technology/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<HTML>
-<BODY>
-{@hide}
-</BODY>
-</HTML>
\ No newline at end of file
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index c46d2c5..6d7b7ce 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -512,10 +512,17 @@
Intent intent = new Intent("android.intent.action.START_TTS_SERVICE");
intent.addCategory("android.intent.category.TTS");
- mContext.bindService(intent, mServiceConnection,
- Context.BIND_AUTO_CREATE);
- // TODO handle case where the binding works (should always work) but
- // the plugin fails
+ boolean bound = mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+ if (!bound) {
+ Log.e("TextToSpeech.java", "initTts() failed to bind to service");
+ if (mInitListener != null) {
+ mInitListener.onInit(ERROR);
+ }
+ } else {
+ // initialization listener will be called inside ServiceConnection
+ Log.i("TextToSpeech.java", "initTts() successfully bound to service");
+ }
+ // TODO handle plugin failures
}
@@ -765,8 +772,9 @@
{
synchronized (mStartLock) {
int result = ERROR;
- Log.i("TTS", "speak() queueMode=" + queueMode);
+ Log.i("TextToSpeech.java - speak", "speak text of length " + text.length());
if (!mStarted) {
+ Log.e("TextToSpeech.java - speak", "service isn't started");
return result;
}
try {
@@ -1264,10 +1272,13 @@
*/
public int synthesizeToFile(String text, HashMap<String,String> params,
String filename) {
- Log.i("TTS", "synthesizeToFile()");
+ Log.i("TextToSpeech.java", "synthesizeToFile()");
synchronized (mStartLock) {
int result = ERROR;
+ Log.i("TextToSpeech.java - synthesizeToFile", "synthesizeToFile text of length "
+ + text.length());
if (!mStarted) {
+ Log.e("TextToSpeech.java - synthesizeToFile", "service isn't started");
return result;
}
try {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 38ac37d..70f90d3 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -50,6 +50,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/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index b682947..b3b80f6 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4087,7 +4087,7 @@
// we have gone through a significant charge (from a very low
// level to a now very high level).
if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
- || level >= 95
+ || level >= 90
|| (mDischargeCurrentLevel < 20 && level >= 80)) {
doWrite = true;
resetAllStatsLocked();
diff --git a/core/java/com/android/internal/widget/DigitalClock.java b/core/java/com/android/internal/widget/DigitalClock.java
index bc749d8..0885b6e 100644
--- a/core/java/com/android/internal/widget/DigitalClock.java
+++ b/core/java/com/android/internal/widget/DigitalClock.java
@@ -34,6 +34,7 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import java.lang.ref.WeakReference;
import java.text.DateFormatSymbols;
import java.util.Calendar;
@@ -54,26 +55,45 @@
private TextView mTimeDisplayForeground;
private AmPm mAmPm;
private ContentObserver mFormatChangeObserver;
- private boolean mLive = true;
- private boolean mAttached;
+ private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
/* called by system on minute ticks */
private final Handler mHandler = new Handler();
- private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (mLive && intent.getAction().equals(
- Intent.ACTION_TIMEZONE_CHANGED)) {
- mCalendar = Calendar.getInstance();
- }
- // Post a runnable to avoid blocking the broadcast.
- mHandler.post(new Runnable() {
- public void run() {
- updateTime();
+ private BroadcastReceiver mIntentReceiver;
+
+ private static class TimeChangedReceiver extends BroadcastReceiver {
+ private WeakReference<DigitalClock> mClock;
+ private Context mContext;
+
+ public TimeChangedReceiver(DigitalClock clock) {
+ mClock = new WeakReference<DigitalClock>(clock);
+ mContext = clock.getContext();
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ // Post a runnable to avoid blocking the broadcast.
+ final boolean timezoneChanged =
+ intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
+ final DigitalClock clock = mClock.get();
+ if (clock != null) {
+ clock.mHandler.post(new Runnable() {
+ public void run() {
+ if (timezoneChanged) {
+ clock.mCalendar = Calendar.getInstance();
}
+ clock.updateTime();
+ }
});
+ } else {
+ try {
+ mContext.unregisterReceiver(this);
+ } catch (RuntimeException e) {
+ // Shouldn't happen
+ }
}
- };
+ }
+ };
static class AmPm {
private TextView mAmPm;
@@ -99,14 +119,27 @@
}
}
- private class FormatChangeObserver extends ContentObserver {
- public FormatChangeObserver() {
+ private static class FormatChangeObserver extends ContentObserver {
+ private WeakReference<DigitalClock> mClock;
+ private Context mContext;
+ public FormatChangeObserver(DigitalClock clock) {
super(new Handler());
+ mClock = new WeakReference<DigitalClock>(clock);
+ mContext = clock.getContext();
}
@Override
public void onChange(boolean selfChange) {
- setDateFormat();
- updateTime();
+ DigitalClock digitalClock = mClock.get();
+ if (digitalClock != null) {
+ digitalClock.setDateFormat();
+ digitalClock.updateTime();
+ } else {
+ try {
+ mContext.getContentResolver().unregisterContentObserver(this);
+ } catch (RuntimeException e) {
+ // Shouldn't happen
+ }
+ }
}
}
@@ -139,11 +172,11 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- if (mAttached) return;
- mAttached = true;
+ mAttached++;
- if (mLive) {
- /* monitor time ticks, time changed, timezone */
+ /* monitor time ticks, time changed, timezone */
+ if (mIntentReceiver == null) {
+ mIntentReceiver = new TimeChangedReceiver(this);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
@@ -152,9 +185,11 @@
}
/* monitor 12/24-hour display preference */
- mFormatChangeObserver = new FormatChangeObserver();
- mContext.getContentResolver().registerContentObserver(
- Settings.System.CONTENT_URI, true, mFormatChangeObserver);
+ if (mFormatChangeObserver == null) {
+ mFormatChangeObserver = new FormatChangeObserver(this);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.CONTENT_URI, true, mFormatChangeObserver);
+ }
updateTime();
}
@@ -163,16 +198,19 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- if (!mAttached) return;
- mAttached = false;
+ mAttached--;
- if (mLive) {
+ if (mIntentReceiver != null) {
mContext.unregisterReceiver(mIntentReceiver);
}
- mContext.getContentResolver().unregisterContentObserver(
- mFormatChangeObserver);
- }
+ if (mFormatChangeObserver != null) {
+ mContext.getContentResolver().unregisterContentObserver(
+ mFormatChangeObserver);
+ }
+ mFormatChangeObserver = null;
+ mIntentReceiver = null;
+ }
void updateTime(Calendar c) {
mCalendar = c;
@@ -180,9 +218,7 @@
}
private void updateTime() {
- if (mLive) {
- mCalendar.setTimeInMillis(System.currentTimeMillis());
- }
+ mCalendar.setTimeInMillis(System.currentTimeMillis());
CharSequence newTime = DateFormat.format(mFormat, mCalendar);
mTimeDisplayBackground.setText(newTime);
@@ -195,8 +231,4 @@
? M24 : M12;
mAmPm.setShowAmPm(mFormat.equals(M12));
}
-
- void setLive(boolean live) {
- mLive = live;
- }
}
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..ed49307
--- /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. To let users capture scenes in new ways, it adds built-in support for time-lapse video recording. 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 a83ca8e..0bb830c 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
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 4113463..499b31f 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 e8d97e7..53d5515 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/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/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 7cf7b07..9b67fee 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -52,6 +52,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>
@@ -158,10 +168,7 @@
<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 212d3c0..97ca8ab0 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -103,8 +103,10 @@
<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>If you enabled snapshots for an AVD, they are automatically captured. The emulator also now restores to the state when
- it last closed almost instantly.</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>
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index 2216824..01ae23f 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -266,13 +266,13 @@
int32_t mode = data.readInt32();
status_t res = turnElectronBeamOff(mode);
reply->writeInt32(res);
- }
+ } break;
case TURN_ELECTRON_BEAM_ON: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
int32_t mode = data.readInt32();
status_t res = turnElectronBeamOn(mode);
reply->writeInt32(res);
- }
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
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/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index 5c20811..2253eb2 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -25,7 +25,8 @@
<application>
<uses-library android:name="android.test.runner" />
<activity android:label="@string/app_name"
- android:name="MediaFrameworkTest">
+ android:name="MediaFrameworkTest"
+ android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
diff --git a/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java b/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java
index 840c5e1..c4feefd 100644
--- a/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/AccountUnlockScreen.java
@@ -62,8 +62,8 @@
*/
private static final int AWAKE_POKE_MILLIS = 30000;
- private final KeyguardScreenCallback mCallback;
- private final LockPatternUtils mLockPatternUtils;
+ private KeyguardScreenCallback mCallback;
+ private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
private TextView mTopHeader;
@@ -159,7 +159,10 @@
if (mCheckingDialog != null) {
mCheckingDialog.hide();
}
- mUpdateMonitor.removeCallback(this);
+ mUpdateMonitor.removeCallback(this); // this must be first
+ mCallback = null;
+ mLockPatternUtils = null;
+ mUpdateMonitor = null;
}
/** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index 32c016d..edab690 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -229,8 +229,8 @@
mKeyguardHost.postDelayed(new Runnable() {
public void run() {
synchronized (KeyguardViewManager.this) {
- mKeyguardHost.removeView(lastView);
lastView.cleanUp();
+ mKeyguardHost.removeView(lastView);
}
}
}, 500);
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 822be46..886b85f 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -495,8 +495,10 @@
public void cleanUp() {
((KeyguardScreen) mLockScreen).onPause();
((KeyguardScreen) mLockScreen).cleanUp();
+ this.removeView(mLockScreen);
((KeyguardScreen) mUnlockScreen).onPause();
((KeyguardScreen) mUnlockScreen).cleanUp();
+ this.removeView(mUnlockScreen);
}
private boolean isSecure() {
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 1b810d5..2bc57b5 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -59,9 +59,9 @@
private Status mStatus = Status.Normal;
- private final LockPatternUtils mLockPatternUtils;
- private final KeyguardUpdateMonitor mUpdateMonitor;
- private final KeyguardScreenCallback mCallback;
+ private LockPatternUtils mLockPatternUtils;
+ private KeyguardUpdateMonitor mUpdateMonitor;
+ private KeyguardScreenCallback mCallback;
private SlidingTab mSlidingTab;
private TextView mScreenLocked;
@@ -659,7 +659,10 @@
/** {@inheritDoc} */
public void cleanUp() {
- mUpdateMonitor.removeCallback(this);
+ mUpdateMonitor.removeCallback(this); // this must be first
+ mLockPatternUtils = null;
+ mUpdateMonitor = null;
+ mCallback = null;
}
/** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
index 6815d50..6c6c2cc8 100644
--- a/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PatternUnlockScreen.java
@@ -62,9 +62,9 @@
private int mTotalFailedPatternAttempts = 0;
private CountDownTimer mCountdownTimer = null;
- private final LockPatternUtils mLockPatternUtils;
- private final KeyguardUpdateMonitor mUpdateMonitor;
- private final KeyguardScreenCallback mCallback;
+ private LockPatternUtils mLockPatternUtils;
+ private KeyguardUpdateMonitor mUpdateMonitor;
+ private KeyguardScreenCallback mCallback;
/**
* whether there is a fallback option available when the pattern is forgotten.
@@ -362,6 +362,9 @@
/** {@inheritDoc} */
public void cleanUp() {
mUpdateMonitor.removeCallback(this);
+ mLockPatternUtils = null;
+ mUpdateMonitor = null;
+ mCallback = null;
}
@Override
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index e4086c4..2c81c34 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -1835,7 +1835,8 @@
AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET |
AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) &&
- (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) &&
+ ((getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) ||
+ (stream == AudioSystem::SYSTEM)) &&
streamDesc.mCanBeMuted) {
volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
// when the phone is ringing we must consider that music could have been paused just before
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 5e1e7d5..436eff0 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -80,7 +80,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/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 5806de2..d75aef6 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -8043,6 +8043,14 @@
sharedUser = orig.sharedUser;
}
+ public void copyFrom(PackageSetting base) {
+ super.copyFrom((PackageSettingBase) base);
+
+ userId = base.userId;
+ sharedUser = base.sharedUser;
+ pkg = base.pkg;
+ }
+
@Override
public String toString() {
return "PackageSetting{"
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 4424e5b..88d9436 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -402,7 +402,6 @@
/** Current network is eHRPD */
public static final int NETWORK_TYPE_EHRPD = 14;
-
/**
* Returns a constant indicating the radio technology (network type)
* currently in use on the device for data transmission.
diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java
index 43fae69..7abae09 100644
--- a/telephony/java/com/android/internal/telephony/CallManager.java
+++ b/telephony/java/com/android/internal/telephony/CallManager.java
@@ -905,6 +905,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 9479a2d..91b19a9 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -434,7 +434,6 @@
mWakeLock.release();
}
}
-
break;
}
}
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index f9bc0e9..7373cbb 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -309,7 +309,9 @@
}
public boolean getMute() {
- return foregroundCall.getMute();
+ return (foregroundCall.getState().isAlive()
+ ? foregroundCall.getMute()
+ : backgroundCall.getMute());
}
public Call getForegroundCall() {