Merge "DOC CHANGE: Fix bug in Testing doc" into gingerbread
diff --git a/Android.mk b/Android.mk
index 6dc39eb..ab30c6e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -116,6 +116,14 @@
core/java/android/net/IConnectivityManager.aidl \
core/java/android/net/INetworkManagementEventObserver.aidl \
core/java/android/net/IThrottleManager.aidl \
+ core/java/android/nfc/ILlcpConnectionlessSocket.aidl \
+ core/java/android/nfc/ILlcpServiceSocket.aidl \
+ core/java/android/nfc/ILlcpSocket.aidl \
+ core/java/android/nfc/INdefTag.aidl \
+ core/java/android/nfc/INfcAdapter.aidl \
+ core/java/android/nfc/INfcTag.aidl \
+ core/java/android/nfc/IP2pInitiator.aidl \
+ core/java/android/nfc/IP2pTarget.aidl \
core/java/android/os/IHardwareService.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkManagementService.aidl \
@@ -159,14 +167,6 @@
core/java/com/android/internal/view/IInputMethodClient.aidl \
core/java/com/android/internal/view/IInputMethodManager.aidl \
core/java/com/android/internal/view/IInputMethodSession.aidl \
- core/java/com/trustedlogic/trustednfc/android/ILlcpConnectionlessSocket.aidl \
- core/java/com/trustedlogic/trustednfc/android/ILlcpServiceSocket.aidl \
- core/java/com/trustedlogic/trustednfc/android/ILlcpSocket.aidl \
- core/java/com/trustedlogic/trustednfc/android/INdefTag.aidl \
- core/java/com/trustedlogic/trustednfc/android/INfcManager.aidl \
- core/java/com/trustedlogic/trustednfc/android/INfcTag.aidl \
- core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl \
- core/java/com/trustedlogic/trustednfc/android/IP2pTarget.aidl \
location/java/android/location/IGeocodeProvider.aidl \
location/java/android/location/IGpsStatusListener.aidl \
location/java/android/location/IGpsStatusProvider.aidl \
@@ -249,6 +249,10 @@
frameworks/base/core/java/android/content/res/Configuration.aidl \
frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \
frameworks/base/core/java/android/net/Uri.aidl \
+ frameworks/base/core/java/android/nfc/NdefMessage.aidl \
+ frameworks/base/core/java/android/nfc/NdefRecord.aidl \
+ frameworks/base/core/java/android/nfc/Tag.aidl \
+ frameworks/base/core/java/android/nfc/NdefTag.aidl \
frameworks/base/core/java/android/os/Bundle.aidl \
frameworks/base/core/java/android/os/DropBoxManager.aidl \
frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 5618eaa..da1d46f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -68,6 +68,8 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libreverbtest_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/lib/soundfx/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/storage/*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/trustedlogic)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/current.xml b/api/current.xml
index 5fd7a1b..0efc466 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -24649,6 +24649,17 @@
visibility="public"
>
</field>
+<field name="COLUMN_MEDIAPROVIDER_URI"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""mediaprovider_uri""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="COLUMN_MEDIA_TYPE"
type="java.lang.String"
transient="false"
@@ -102984,6 +102995,33 @@
</package>
<package name="android.nfc"
>
+<class name="FormatException"
+ extends="java.lang.Exception"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="FormatException"
+ type="android.nfc.FormatException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<constructor name="FormatException"
+ type="android.nfc.FormatException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="message" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
<class name="NdefMessage"
extends="java.lang.Object"
abstract="false"
@@ -103323,6 +103361,632 @@
>
</field>
</class>
+<class name="NdefTag"
+ extends="android.nfc.Tag"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="getNdefMessages"
+ return="android.nfc.NdefMessage[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getNdefMessages"
+ return="android.nfc.NdefMessage[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="target" type="java.lang.String">
+</parameter>
+</method>
+<method name="getNdefTargets"
+ return="java.lang.String[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_MIFARE_CLASSIC"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""type_mifare_classic""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_OTHER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""other""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_TYPE_1"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""type_1""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_TYPE_2"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""type_2""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_TYPE_3"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""type_3""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_TYPE_4"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""type_4""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="NdefTagConnection"
+ extends="android.nfc.RawTagConnection"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getModeHint"
+ return="int"
+ 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="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="readNdefMessages"
+ 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="writeNdefMessage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="message" type="android.nfc.NdefMessage">
+</parameter>
+<exception name="FormatException" type="android.nfc.FormatException">
+</exception>
+<exception name="IOException" type="java.io.IOException">
+</exception>
+</method>
+<field name="NDEF_MODE_READ_ONCE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NDEF_MODE_READ_ONLY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NDEF_MODE_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="5"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NDEF_MODE_WRITE_MANY"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="NDEF_MODE_WRITE_ONCE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="NfcAdapter"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="createNdefTagConnection"
+ return="android.nfc.NdefTagConnection"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.NdefTag">
+</parameter>
+</method>
+<method name="createNdefTagConnection"
+ return="android.nfc.NdefTagConnection"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.NdefTag">
+</parameter>
+<parameter name="target" type="java.lang.String">
+</parameter>
+</method>
+<method name="createRawTagConnection"
+ return="android.nfc.RawTagConnection"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+</method>
+<method name="createRawTagConnection"
+ return="android.nfc.RawTagConnection"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tag" type="android.nfc.Tag">
+</parameter>
+<parameter name="target" type="java.lang.String">
+</parameter>
+</method>
+<method name="getDefaultAdapter"
+ return="android.nfc.NfcAdapter"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getLocalNdefMessage"
+ return="android.nfc.NdefMessage"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isTagDiscoveryEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setLocalNdefMessage"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="message" type="android.nfc.NdefMessage">
+</parameter>
+</method>
+<field name="ACTION_NDEF_TAG_DISCOVERED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.nfc.action.NDEF_TAG_DISCOVERED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_TAG_DISCOVERED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.nfc.action.TAG_DISCOVERED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ 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="RawTagConnection"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="close"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</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="getTagTarget"
+ return="java.lang.String"
+ 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="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="Tag"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<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="getRawTargets"
+ 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>
+<field name="TARGET_ISO_14443_3A"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""iso14443_3a""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_ISO_14443_3B"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""iso14443_3b""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_ISO_14443_3B_PRIME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""iso14443_3b""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_ISO_14443_4"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""iso14443_4""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_ISO_15693"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""iso15693""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_JIS_X_6319_4"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""jis_x_6319_4""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_OTHER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""other""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TARGET_TOPAZ"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""topaz""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
</package>
<package name="android.opengl"
>
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index c08f1fc..fda08f6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -102,9 +102,6 @@
import android.accounts.AccountManager;
import android.accounts.IAccountManager;
import android.app.admin.DevicePolicyManager;
-import com.trustedlogic.trustednfc.android.NfcManager;
-import com.trustedlogic.trustednfc.android.INfcManager;
-
import com.android.internal.os.IDropBoxManagerService;
import java.io.File;
@@ -173,7 +170,6 @@
private static ThrottleManager sThrottleManager;
private static WifiManager sWifiManager;
private static LocationManager sLocationManager;
- private static NfcManager sNfcManager;
private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
new HashMap<String, SharedPreferencesImpl>();
@@ -972,8 +968,6 @@
return getClipboardManager();
} else if (WALLPAPER_SERVICE.equals(name)) {
return getWallpaperManager();
- } else if (NFC_SERVICE.equals(name)) {
- return getNfcManager();
} else if (DROPBOX_SERVICE.equals(name)) {
return getDropBoxManager();
} else if (DEVICE_POLICY_SERVICE.equals(name)) {
@@ -1209,21 +1203,6 @@
return mDownloadManager;
}
- private NfcManager getNfcManager()
- {
- synchronized (sSync) {
- if (sNfcManager == null) {
- IBinder b = ServiceManager.getService(NFC_SERVICE);
- if (b == null) {
- return null;
- }
- INfcManager service = INfcManager.Stub.asInterface(b);
- sNfcManager = new NfcManager(service, mMainThread.getHandler());
- }
- }
- return sNfcManager;
- }
-
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 00d8ae3..a25aa6f 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -28,7 +28,6 @@
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.provider.Downloads;
-import android.util.Log;
import android.util.Pair;
import java.io.File;
@@ -136,6 +135,12 @@
*/
public final static String COLUMN_LAST_MODIFIED_TIMESTAMP = "last_modified_timestamp";
+ /**
+ * The URI to the corresponding entry in MediaProvider for this downloaded entry. It is
+ * used to delete the entries from MediaProvider database when it is deleted from the
+ * downloaded list.
+ */
+ public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
/**
* Value of {@link #COLUMN_STATUS} when the download is waiting to start.
@@ -266,6 +271,7 @@
// this array must contain all public columns
private static final String[] COLUMNS = new String[] {
COLUMN_ID,
+ COLUMN_MEDIAPROVIDER_URI,
COLUMN_TITLE,
COLUMN_DESCRIPTION,
COLUMN_URI,
@@ -281,6 +287,7 @@
// columns to request from DownloadProvider
private static final String[] UNDERLYING_COLUMNS = new String[] {
Downloads.Impl._ID,
+ Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
Downloads.COLUMN_TITLE,
Downloads.COLUMN_DESCRIPTION,
Downloads.COLUMN_URI,
@@ -677,6 +684,9 @@
selectionParts.add(Downloads.Impl.COLUMN_IS_VISIBLE_IN_DOWNLOADS_UI + " != '0'");
}
+ // only return rows which are not marked 'deleted = 1'
+ selectionParts.add(Downloads.Impl.COLUMN_DELETED + " != '1'");
+
String selection = joinStrings(" AND ", selectionParts);
String orderDirection = (mOrderDirection == ORDER_ASCENDING ? "ASC" : "DESC");
String orderBy = mOrderByColumn + " " + orderDirection;
@@ -743,6 +753,26 @@
}
/**
+ * Marks the specified download as 'to be deleted'. This is done when a completed download
+ * is to be removed but the row was stored without enough info to delete the corresponding
+ * metadata from Mediaprovider database. Actual cleanup of this row is done in DownloadService.
+ *
+ * @param ids the IDs of the downloads to be marked 'deleted'
+ * @return the number of downloads actually updated
+ * @hide
+ */
+ public int markRowDeleted(long... ids) {
+ if (ids == null || ids.length == 0) {
+ // called with nothing to remove!
+ throw new IllegalArgumentException("input param 'ids' can't be null");
+ }
+ ContentValues values = new ContentValues();
+ values.put(Downloads.Impl.COLUMN_DELETED, 1);
+ return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),
+ getWhereArgsForIds(ids));
+ }
+
+ /**
* Cancel downloads and remove them from the download manager. Each download will be stopped if
* it was running, and it will no longer be accessible through the download manager. If a file
* was already downloaded to external storage, it will not be deleted.
@@ -950,6 +980,9 @@
if (column.equals(COLUMN_MEDIA_TYPE)) {
return getUnderlyingString(Downloads.COLUMN_MIME_TYPE);
}
+ if (column.equals(COLUMN_MEDIAPROVIDER_URI)) {
+ return getUnderlyingString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
+ }
assert column.equals(COLUMN_LOCAL_URI);
return getLocalUri();
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index df1d960..71aefbc 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -56,7 +56,7 @@
*/
public final class BluetoothDeviceProfileState extends HierarchicalStateMachine {
private static final String TAG = "BluetoothDeviceProfileState";
- private static final boolean DBG = true; //STOPSHIP - Change to false
+ private static final boolean DBG = false;
public static final int CONNECT_HFP_OUTGOING = 1;
public static final int CONNECT_HFP_INCOMING = 2;
@@ -136,6 +136,10 @@
Message msg = new Message();
msg.what = AUTO_CONNECT_PROFILES;
sendMessageDelayed(msg, AUTO_CONNECT_DELAY);
+ } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
+ // This is technically not needed, but we can get stuck sometimes.
+ // For example, if incoming A2DP fails, we are not informed by Bluez
+ sendMessage(TRANSITION_TO_STABLE);
}
}
};
@@ -175,6 +179,7 @@
filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
+ filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
mContext.registerReceiver(mBroadcastReceiver, filter);
@@ -217,7 +222,7 @@
private class BondedDevice extends HierarchicalState {
@Override
protected void enter() {
- log("Entering ACL Connected state with: " + getCurrentMessage().what);
+ Log.i(TAG, "Entering ACL Connected state with: " + getCurrentMessage().what);
Message m = new Message();
m.copyFrom(getCurrentMessage());
sendMessageAtFrontOfQueue(m);
@@ -295,14 +300,18 @@
@Override
protected void enter() {
- log("Entering OutgoingHandsfree state with: " + getCurrentMessage().what);
+ Log.i(TAG, "Entering OutgoingHandsfree state with: " + getCurrentMessage().what);
mCommand = getCurrentMessage().what;
if (mCommand != CONNECT_HFP_OUTGOING &&
mCommand != DISCONNECT_HFP_OUTGOING) {
Log.e(TAG, "Error: OutgoingHandsfree state with command:" + mCommand);
}
mStatus = processCommand(mCommand);
- if (!mStatus) sendMessage(TRANSITION_TO_STABLE);
+ if (!mStatus) {
+ sendMessage(TRANSITION_TO_STABLE);
+ mService.sendProfileStateMessage(BluetoothProfileState.HFP,
+ BluetoothProfileState.TRANSITION_TO_STABLE);
+ }
}
@Override
@@ -386,14 +395,18 @@
@Override
protected void enter() {
- log("Entering IncomingHandsfree state with: " + getCurrentMessage().what);
+ Log.i(TAG, "Entering IncomingHandsfree state with: " + getCurrentMessage().what);
mCommand = getCurrentMessage().what;
if (mCommand != CONNECT_HFP_INCOMING &&
mCommand != DISCONNECT_HFP_INCOMING) {
Log.e(TAG, "Error: IncomingHandsfree state with command:" + mCommand);
}
mStatus = processCommand(mCommand);
- if (!mStatus) sendMessage(TRANSITION_TO_STABLE);
+ if (!mStatus) {
+ sendMessage(TRANSITION_TO_STABLE);
+ mService.sendProfileStateMessage(BluetoothProfileState.HFP,
+ BluetoothProfileState.TRANSITION_TO_STABLE);
+ }
}
@Override
@@ -454,14 +467,18 @@
@Override
protected void enter() {
- log("Entering OutgoingA2dp state with: " + getCurrentMessage().what);
+ Log.i(TAG, "Entering OutgoingA2dp state with: " + getCurrentMessage().what);
mCommand = getCurrentMessage().what;
if (mCommand != CONNECT_A2DP_OUTGOING &&
mCommand != DISCONNECT_A2DP_OUTGOING) {
Log.e(TAG, "Error: OutgoingA2DP state with command:" + mCommand);
}
mStatus = processCommand(mCommand);
- if (!mStatus) sendMessage(TRANSITION_TO_STABLE);
+ if (!mStatus) {
+ sendMessage(TRANSITION_TO_STABLE);
+ mService.sendProfileStateMessage(BluetoothProfileState.A2DP,
+ BluetoothProfileState.TRANSITION_TO_STABLE);
+ }
}
@Override
@@ -516,7 +533,7 @@
}
break;
case DISCONNECT_A2DP_OUTGOING:
- processCommand(DISCONNECT_A2DP_OUTGOING);
+ deferMessage(message);
break;
case DISCONNECT_A2DP_INCOMING:
// Ignore, will be handled by Bluez
@@ -542,14 +559,18 @@
@Override
protected void enter() {
- log("Entering IncomingA2dp state with: " + getCurrentMessage().what);
+ Log.i(TAG, "Entering IncomingA2dp state with: " + getCurrentMessage().what);
mCommand = getCurrentMessage().what;
if (mCommand != CONNECT_A2DP_INCOMING &&
mCommand != DISCONNECT_A2DP_INCOMING) {
Log.e(TAG, "Error: IncomingA2DP state with command:" + mCommand);
}
mStatus = processCommand(mCommand);
- if (!mStatus) sendMessage(TRANSITION_TO_STABLE);
+ if (!mStatus) {
+ sendMessage(TRANSITION_TO_STABLE);
+ mService.sendProfileStateMessage(BluetoothProfileState.A2DP,
+ BluetoothProfileState.TRANSITION_TO_STABLE);
+ }
}
@Override
@@ -622,7 +643,7 @@
}
synchronized boolean processCommand(int command) {
- log("Processing command:" + command);
+ Log.i(TAG, "Processing command:" + command);
switch(command) {
case CONNECT_HFP_OUTGOING:
if (mHeadsetService != null) {
diff --git a/core/java/android/bluetooth/BluetoothProfileState.java b/core/java/android/bluetooth/BluetoothProfileState.java
index 946dcaa..686ff7c 100644
--- a/core/java/android/bluetooth/BluetoothProfileState.java
+++ b/core/java/android/bluetooth/BluetoothProfileState.java
@@ -40,13 +40,13 @@
*/
public class BluetoothProfileState extends HierarchicalStateMachine {
- private static final boolean DBG = true; // STOPSHIP - change to false.
+ private static final boolean DBG = true;
private static final String TAG = "BluetoothProfileState";
- public static int HFP = 0;
- public static int A2DP = 1;
+ public static final int HFP = 0;
+ public static final int A2DP = 1;
- private static int TRANSITION_TO_STABLE = 100;
+ static final int TRANSITION_TO_STABLE = 100;
private int mProfile;
private BluetoothDevice mPendingDevice;
@@ -57,7 +57,7 @@
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
-
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
int newState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0);
if (mProfile == HFP && (newState == BluetoothHeadset.STATE_CONNECTED ||
@@ -70,6 +70,10 @@
newState == BluetoothA2dp.STATE_DISCONNECTED)) {
sendMessage(TRANSITION_TO_STABLE);
}
+ } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
+ if (device.equals(mPendingDevice)) {
+ sendMessage(TRANSITION_TO_STABLE);
+ }
}
}
};
@@ -84,6 +88,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
+ filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
context.registerReceiver(mBroadcastReceiver, filter);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7242803..de8e3f4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5268,10 +5268,15 @@
}
first = false;
b.append("dat=");
- if (mData.getScheme().equalsIgnoreCase("tel")) {
- b.append("tel:xxx-xxx-xxxx");
- } else if (mData.getScheme().equalsIgnoreCase("smsto")) {
- b.append("smsto:xxx-xxx-xxxx");
+ String scheme = mData.getScheme();
+ if (scheme != null) {
+ if (scheme.equalsIgnoreCase("tel")) {
+ b.append("tel:xxx-xxx-xxxx");
+ } else if (scheme.equalsIgnoreCase("smsto")) {
+ b.append("smsto:xxx-xxx-xxxx");
+ } else {
+ b.append(mData);
+ }
} else {
b.append(mData);
}
diff --git a/core/java/android/content/res/ObbInfo.java b/core/java/android/content/res/ObbInfo.java
index 5d6ed44..b653f9f 100644
--- a/core/java/android/content/res/ObbInfo.java
+++ b/core/java/android/content/res/ObbInfo.java
@@ -48,6 +48,13 @@
*/
public int flags;
+ /**
+ * The salt for the encryption algorithm.
+ *
+ * @hide
+ */
+ public byte[] salt;
+
// Only allow things in this package to instantiate.
/* package */ ObbInfo() {
}
@@ -75,6 +82,7 @@
dest.writeString(packageName);
dest.writeInt(version);
dest.writeInt(flags);
+ dest.writeByteArray(salt);
}
public static final Parcelable.Creator<ObbInfo> CREATOR
@@ -93,5 +101,6 @@
packageName = source.readString();
version = source.readInt();
flags = source.readInt();
+ salt = source.createByteArray();
}
}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/ErrorCodes.java b/core/java/android/nfc/ErrorCodes.java
similarity index 83%
rename from core/java/com/trustedlogic/trustednfc/android/internal/ErrorCodes.java
rename to core/java/android/nfc/ErrorCodes.java
index ca3b7e0..5b76d84 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/ErrorCodes.java
+++ b/core/java/android/nfc/ErrorCodes.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * 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
+ * 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,
@@ -14,19 +14,13 @@
* limitations under the License.
*/
-/**
- * File : ErrorCodes.java
- * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
- * Created : 26-02-2010
- */
-
-package com.trustedlogic.trustednfc.android.internal;
+package android.nfc;
/**
* This class defines all the error codes that can be returned by the service
* and producing an exception on the application level. These are needed since
* binders does not support exceptions.
- *
+ *
* @hide
*/
public class ErrorCodes {
@@ -40,7 +34,7 @@
}
public static final int SUCCESS = 0;
-
+
public static final int ERROR_IO = -1;
public static final int ERROR_CANCELLED = -2;
@@ -58,34 +52,29 @@
public static final int ERROR_WRITE = -7;
public static final int ERROR_INVALID_PARAM = -8;
-
+
public static final int ERROR_INSUFFICIENT_RESOURCES = -9;
-
+
public static final int ERROR_SOCKET_CREATION = -10;
-
+
public static final int ERROR_SOCKET_NOT_CONNECTED = -11;
-
+
public static final int ERROR_BUFFER_TO_SMALL = -12;
public static final int ERROR_SAP_USED = -13;
-
+
public static final int ERROR_SERVICE_NAME_USED = -14;
-
+
public static final int ERROR_SOCKET_OPTIONS = -15;
-
+
public static final int ERROR_NFC_ON = -16;
-
+
public static final int ERROR_NOT_INITIALIZED = -17;
-
+
public static final int ERROR_SE_ALREADY_SELECTED = -18;
-
+
public static final int ERROR_SE_CONNECTED = -19;
-
+
public static final int ERROR_NO_SE_CONNECTED = -20;
-
-
-
-
-
-
-}
+
+}
\ No newline at end of file
diff --git a/core/java/android/nfc/FormatException.java b/core/java/android/nfc/FormatException.java
new file mode 100644
index 0000000..21a7c3b
--- /dev/null
+++ b/core/java/android/nfc/FormatException.java
@@ -0,0 +1,28 @@
+/*
+ * 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;
+
+//TODO(npelly) javadoc or consider alternatives
+public class FormatException extends Exception {
+ public FormatException() {
+ super();
+ }
+
+ public FormatException(String message) {
+ super(message);
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl b/core/java/android/nfc/ILlcpConnectionlessSocket.aidl
similarity index 69%
copy from core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
copy to core/java/android/nfc/ILlcpConnectionlessSocket.aidl
index 96819ae..c6d84e5 100644
--- a/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
+++ b/core/java/android/nfc/ILlcpConnectionlessSocket.aidl
@@ -14,19 +14,17 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
+
+import android.nfc.LlcpPacket;
/**
- * TODO
- *
- * {@hide}
+ * @hide
*/
-interface IP2pInitiator
+interface ILlcpConnectionlessSocket
{
-
- byte[] getGeneralBytes(int nativeHandle);
- int getMode(int nativeHandle);
- byte[] receive(int nativeHandle);
- boolean send(int nativeHandle, in byte[] data);
-
+ void close(int nativeHandle);
+ int getSap(int nativeHandle);
+ LlcpPacket receiveFrom(int nativeHandle);
+ int sendTo(int nativeHandle, in LlcpPacket packet);
}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/ILlcpServiceSocket.aidl b/core/java/android/nfc/ILlcpServiceSocket.aidl
similarity index 73%
rename from core/java/com/trustedlogic/trustednfc/android/ILlcpServiceSocket.aidl
rename to core/java/android/nfc/ILlcpServiceSocket.aidl
index 5eb1f3c..c3108dc 100644
--- a/core/java/com/trustedlogic/trustednfc/android/ILlcpServiceSocket.aidl
+++ b/core/java/android/nfc/ILlcpServiceSocket.aidl
@@ -14,19 +14,15 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
/**
- * TODO
- *
* {@hide}
*/
interface ILlcpServiceSocket
{
-
- int accept(int nativeHandle);
- void close(int nativeHandle);
- int getAcceptTimeout(int nativeHandle);
- void setAcceptTimeout(int nativeHandle, int timeout);
-
-}
\ No newline at end of file
+ int accept(int nativeHandle);
+ void close(int nativeHandle);
+ int getAcceptTimeout(int nativeHandle);
+ void setAcceptTimeout(int nativeHandle, int timeout);
+}
diff --git a/core/java/android/nfc/ILlcpSocket.aidl b/core/java/android/nfc/ILlcpSocket.aidl
new file mode 100644
index 0000000..dda5628
--- /dev/null
+++ b/core/java/android/nfc/ILlcpSocket.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * @hide
+ */
+interface ILlcpSocket
+{
+ int close(int nativeHandle);
+ int connect(int nativeHandle, int sap);
+ int connectByName(int nativeHandle, String sn);
+ int getConnectTimeout(int nativeHandle);
+ int getLocalSap(int nativeHandle);
+ int getLocalSocketMiu(int nativeHandle);
+ int getLocalSocketRw(int nativeHandle);
+ int getRemoteSocketMiu(int nativeHandle);
+ int getRemoteSocketRw(int nativeHandle);
+ int receive(int nativeHandle, out byte[] receiveBuffer);
+ int send(int nativeHandle, in byte[] data);
+ void setConnectTimeout(int nativeHandle, int timeout);
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/INdefTag.aidl b/core/java/android/nfc/INdefTag.aidl
similarity index 78%
rename from core/java/com/trustedlogic/trustednfc/android/INdefTag.aidl
rename to core/java/android/nfc/INdefTag.aidl
index 1f8d1a4..d131ebe 100644
--- a/core/java/com/trustedlogic/trustednfc/android/INdefTag.aidl
+++ b/core/java/android/nfc/INdefTag.aidl
@@ -14,19 +14,15 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
-import com.trustedlogic.trustednfc.android.NdefMessage;
+import android.nfc.NdefMessage;
/**
- * TODO
- *
- * {@hide}
+ * @hide
*/
interface INdefTag
{
-
NdefMessage read(int nativeHandle);
- boolean write(int nativeHandle, in NdefMessage msg);
-
+ boolean write(int nativeHandle, in NdefMessage msg);
}
\ No newline at end of file
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
new file mode 100644
index 0000000..7743ceb
--- /dev/null
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import android.nfc.NdefMessage;
+import android.nfc.Tag;
+import android.nfc.ILlcpSocket;
+import android.nfc.ILlcpServiceSocket;
+import android.nfc.ILlcpConnectionlessSocket;
+import android.nfc.INfcTag;
+import android.nfc.IP2pTarget;
+import android.nfc.IP2pInitiator;
+
+/**
+ * @hide
+ */
+interface INfcAdapter
+{
+ ILlcpSocket getLlcpInterface();
+ ILlcpConnectionlessSocket getLlcpConnectionlessInterface();
+ ILlcpServiceSocket getLlcpServiceInterface();
+ INfcTag getNfcTagInterface();
+ IP2pTarget getP2pTargetInterface();
+ IP2pInitiator getP2pInitiatorInterface();
+
+ // NfcAdapter-class related methods
+ boolean isEnabled();
+ NdefMessage localGet();
+ void localSet(in NdefMessage message);
+ void openTagConnection(in Tag tag);
+
+ // Non-public methods
+ // TODO: check and complete
+ int createLlcpConnectionlessSocket(int sap);
+ int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
+ int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
+ int deselectSecureElement();
+ boolean disable();
+ boolean enable();
+ String getProperties(String param);
+ int[] getSecureElementList();
+ int getSelectedSecureElement();
+ int selectSecureElement(int seId);
+ int setProperties(String param, String value);
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
similarity index 62%
rename from core/java/com/trustedlogic/trustednfc/android/INfcTag.aidl
rename to core/java/android/nfc/INfcTag.aidl
index 79543c4..2171434 100644
--- a/core/java/com/trustedlogic/trustednfc/android/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -14,25 +14,26 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
-import com.trustedlogic.trustednfc.android.NdefMessage;
+import android.nfc.NdefMessage;
/**
- * TODO
- *
- * {@hide}
+ * @hide
*/
interface INfcTag
{
-
- int close(int nativeHandle);
- int connect(int nativeHandle);
- String getType(int nativeHandle);
- byte[] getUid(int nativeHandle);
+ int close(int nativeHandle);
+ int connect(int nativeHandle);
+ String getType(int nativeHandle);
+ byte[] getUid(int nativeHandle);
boolean isNdef(int nativeHandle);
- byte[] transceive(int nativeHandle, in byte[] data);
-
+ byte[] transceive(int nativeHandle, in byte[] data);
+
+ int getLastError(int nativeHandle);
+
NdefMessage read(int nativeHandle);
- boolean write(int nativeHandle, in NdefMessage msg);
+ int write(int nativeHandle, in NdefMessage msg);
+ int makeReadOnly(int nativeHandle);
+ int getModeHint(int nativeHandle);
}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl b/core/java/android/nfc/IP2pInitiator.aidl
similarity index 72%
rename from core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
rename to core/java/android/nfc/IP2pInitiator.aidl
index 96819ae..931f1f8 100644
--- a/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
+++ b/core/java/android/nfc/IP2pInitiator.aidl
@@ -14,19 +14,15 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
/**
- * TODO
- *
- * {@hide}
+ * @hide
*/
interface IP2pInitiator
{
-
- byte[] getGeneralBytes(int nativeHandle);
- int getMode(int nativeHandle);
- byte[] receive(int nativeHandle);
- boolean send(int nativeHandle, in byte[] data);
-
+ byte[] getGeneralBytes(int nativeHandle);
+ int getMode(int nativeHandle);
+ byte[] receive(int nativeHandle);
+ boolean send(int nativeHandle, in byte[] data);
}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl b/core/java/android/nfc/IP2pTarget.aidl
similarity index 69%
copy from core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
copy to core/java/android/nfc/IP2pTarget.aidl
index 96819ae..ddaaed42 100644
--- a/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
+++ b/core/java/android/nfc/IP2pTarget.aidl
@@ -14,19 +14,16 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
/**
- * TODO
- *
- * {@hide}
+ * @hide
*/
-interface IP2pInitiator
+interface IP2pTarget
{
-
- byte[] getGeneralBytes(int nativeHandle);
- int getMode(int nativeHandle);
- byte[] receive(int nativeHandle);
- boolean send(int nativeHandle, in byte[] data);
-
+ byte[] getGeneralBytes(int nativeHandle);
+ int getMode(int nativeHandle);
+ int connect(int nativeHandle);
+ boolean disconnect(int nativeHandle);
+ byte[] transceive(int nativeHandle, in byte[] data);
}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.aidl b/core/java/android/nfc/LlcpPacket.aidl
similarity index 92%
rename from core/java/com/trustedlogic/trustednfc/android/LlcpPacket.aidl
rename to core/java/android/nfc/LlcpPacket.aidl
index 297a1fe..80f424d 100644
--- a/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.aidl
+++ b/core/java/android/nfc/LlcpPacket.aidl
@@ -14,6 +14,9 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
-parcelable LlcpPacket;
+/**
+ * @hide
+ */
+parcelable LlcpPacket;
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.java b/core/java/android/nfc/LlcpPacket.java
similarity index 71%
rename from core/java/com/trustedlogic/trustednfc/android/LlcpPacket.java
rename to core/java/android/nfc/LlcpPacket.java
index af79023..9919dc4 100644
--- a/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.java
+++ b/core/java/android/nfc/LlcpPacket.java
@@ -14,76 +14,35 @@
* limitations under the License.
*/
-/**
- * File : LLCPPacket.java
- * Original-Author : Trusted Logic S.A. (Daniel Tomas)
- * Created : 25-02-2010
- */
-
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Represents a LLCP packet received in a LLCP Connectionless communication;
- *
- * @since AA02.01
* @hide
*/
public class LlcpPacket implements Parcelable {
- private int mRemoteSap;
+ private final int mRemoteSap;
- private byte[] mDataBuffer;
-
- /**
- * Creator class, needed when implementing from Parcelable
- * {@hide}
- */
- public static final Parcelable.Creator<LlcpPacket> CREATOR = new Parcelable.Creator<LlcpPacket>() {
- public LlcpPacket createFromParcel(Parcel in) {
- // Remote SAP
- short sap = (short)in.readInt();
-
- // Data Buffer
- int dataLength = in.readInt();
- byte[] data = new byte[dataLength];
- in.readByteArray(data);
-
- return new LlcpPacket(sap, data);
- }
-
- public LlcpPacket[] newArray(int size) {
- return new LlcpPacket[size];
- }
- };
-
+ private final byte[] mDataBuffer;
/**
* Creates a LlcpPacket to be sent to a remote Service Access Point number
* (SAP)
- *
+ *
* @param sap Remote Service Access Point number
* @param data Data buffer
- * @since AA02.01
*/
public LlcpPacket(int sap, byte[] data) {
- mRemoteSap = sap;
+ mRemoteSap = sap;
mDataBuffer = data;
}
-
- /**
- * @hide
- */
- public LlcpPacket() {
- }
/**
* Returns the remote Service Access Point number
- *
- * @return remoteSap
- * @since AA02.01
*/
public int getRemoteSap() {
return mRemoteSap;
@@ -91,29 +50,36 @@
/**
* Returns the data buffer
- *
- * @return data
- * @since AA02.01
*/
public byte[] getDataBuffer() {
return mDataBuffer;
}
- /**
- * (Parcelable) Describe the parcel
- * {@hide}
- */
public int describeContents() {
return 0;
}
- /**
- * (Parcelable) Convert current object to a Parcel
- * {@hide}
- */
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mRemoteSap);
dest.writeInt(mDataBuffer.length);
- dest.writeByteArray(mDataBuffer);
+ dest.writeByteArray(mDataBuffer);
}
-}
+
+ public static final Parcelable.Creator<LlcpPacket> CREATOR = new Parcelable.Creator<LlcpPacket>() {
+ public LlcpPacket createFromParcel(Parcel in) {
+ // Remote SAP
+ short sap = (short)in.readInt();
+
+ // Data Buffer
+ int dataLength = in.readInt();
+ byte[] data = new byte[dataLength];
+ in.readByteArray(data);
+
+ return new LlcpPacket(sap, data);
+ }
+
+ public LlcpPacket[] newArray(int size) {
+ return new LlcpPacket[size];
+ }
+ };
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl b/core/java/android/nfc/NdefMessage.aidl
similarity index 92%
rename from core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
rename to core/java/android/nfc/NdefMessage.aidl
index e60f4e8..378b9d0 100644
--- a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
+++ b/core/java/android/nfc/NdefMessage.aidl
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package com.trustedlogic.trustednfc.android;
+
+package android.nfc;
parcelable NdefMessage;
diff --git a/core/java/android/nfc/NdefMessage.java b/core/java/android/nfc/NdefMessage.java
index 557f651..fcff2c9 100644
--- a/core/java/android/nfc/NdefMessage.java
+++ b/core/java/android/nfc/NdefMessage.java
@@ -20,8 +20,6 @@
import android.os.Parcel;
import android.os.Parcelable;
-import java.lang.UnsupportedOperationException;
-
/**
* NDEF Message data.
* <p>
@@ -29,23 +27,34 @@
* records.
*/
public class NdefMessage implements Parcelable {
+ private static final byte FLAG_MB = (byte) 0x80;
+ private static final byte FLAG_ME = (byte) 0x40;
+
+ private final NdefRecord[] mRecords;
+
+ //TODO(npelly) FormatException
/**
* Create an NDEF message from raw bytes.
* <p>
* Validation is performed to make sure the Record format headers are valid,
* and the ID + TYPE + PAYLOAD fields are of the correct size.
+ * @throws FormatException
*
* @hide
*/
- public NdefMessage(byte[] data) {
- throw new UnsupportedOperationException();
+ public NdefMessage(byte[] data) throws FormatException {
+ mRecords = null; // stop compiler complaints about final field
+ if (parseNdefMessage(data) == -1) {
+ throw new FormatException("Error while parsing NDEF message");
+ }
}
/**
* Create an NDEF message from NDEF records.
*/
public NdefMessage(NdefRecord[] records) {
- throw new UnsupportedOperationException();
+ mRecords = new NdefRecord[records.length];
+ System.arraycopy(records, 0, mRecords, 0, records.length);
}
/**
@@ -54,7 +63,7 @@
* @return array of zero or more NDEF records.
*/
public NdefRecord[] getRecords() {
- throw new UnsupportedOperationException();
+ return mRecords.clone();
}
/**
@@ -64,26 +73,62 @@
* @hide
*/
public byte[] toByteArray() {
- throw new UnsupportedOperationException();
+ //TODO(nxp): do not return null
+ //TODO(nxp): allocate the byte array once, copy each record once
+ //TODO(nxp): process MB and ME flags outside loop
+ if ((mRecords == null) || (mRecords.length == 0))
+ return null;
+
+ byte[] msg = {};
+
+ for (int i = 0; i < mRecords.length; i++) {
+ byte[] record = mRecords[i].toByteArray();
+ byte[] tmp = new byte[msg.length + record.length];
+
+ /* Make sure the Message Begin flag is set only for the first record */
+ if (i == 0) {
+ record[0] |= FLAG_MB;
+ } else {
+ record[0] &= ~FLAG_MB;
+ }
+
+ /* Make sure the Message End flag is set only for the last record */
+ if (i == (mRecords.length - 1)) {
+ record[0] |= FLAG_ME;
+ } else {
+ record[0] &= ~FLAG_ME;
+ }
+
+ System.arraycopy(msg, 0, tmp, 0, msg.length);
+ System.arraycopy(record, 0, tmp, msg.length, record.length);
+
+ msg = tmp;
+ }
+
+ return msg;
}
- @Override
public int describeContents() {
return 0;
}
- @Override
public void writeToParcel(Parcel dest, int flags) {
- throw new UnsupportedOperationException();
+ dest.writeInt(mRecords.length);
+ dest.writeTypedArray(mRecords, flags);
}
public static final Parcelable.Creator<NdefMessage> CREATOR =
new Parcelable.Creator<NdefMessage>() {
public NdefMessage createFromParcel(Parcel in) {
- throw new UnsupportedOperationException();
+ int recordsLength = in.readInt();
+ NdefRecord[] records = new NdefRecord[recordsLength];
+ in.readTypedArray(records, NdefRecord.CREATOR);
+ return new NdefMessage(records);
}
public NdefMessage[] newArray(int size) {
- throw new UnsupportedOperationException();
+ return new NdefMessage[size];
}
};
+
+ private native int parseNdefMessage(byte[] data);
}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefRecord.aidl b/core/java/android/nfc/NdefRecord.aidl
similarity index 92%
rename from core/java/com/trustedlogic/trustednfc/android/NdefRecord.aidl
rename to core/java/android/nfc/NdefRecord.aidl
index 9d95174..10f89d0 100644
--- a/core/java/com/trustedlogic/trustednfc/android/NdefRecord.aidl
+++ b/core/java/android/nfc/NdefRecord.aidl
@@ -14,6 +14,6 @@
* limitations under the License.
*/
-package com.trustedlogic.trustednfc.android;
+package android.nfc;
-parcelable NdefRecord;
+parcelable NdefRecord;
\ No newline at end of file
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 54cbbeb..c08f2ed 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -138,6 +138,18 @@
*/
public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs"
+ private static final byte FLAG_MB = (byte) 0x80;
+ private static final byte FLAG_ME = (byte) 0x40;
+ private static final byte FLAG_CF = (byte) 0x20;
+ private static final byte FLAG_SR = (byte) 0x10;
+ private static final byte FLAG_IL = (byte) 0x08;
+
+ private final byte mFlags;
+ private final short mTnf;
+ private final byte[] mType;
+ private final byte[] mId;
+ private final byte[] mPayload;
+
/**
* Construct an NDEF Record.
* <p>
@@ -153,7 +165,29 @@
* must not be null
*/
public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) {
- throw new UnsupportedOperationException();
+ /* check arguments */
+ if ((type == null) || (id == null) || (payload == null)) {
+ throw new IllegalArgumentException("Illegal null argument");
+ }
+
+ /* generate flag */
+ byte flags = FLAG_MB | FLAG_ME;
+
+ /* Determine if it is a short record */
+ if(payload.length < 0xFF) {
+ flags |= FLAG_SR;
+ }
+
+ /* Determine if an id is present */
+ if(id.length != 0) {
+ flags |= FLAG_IL;
+ }
+
+ mFlags = flags;
+ mTnf = tnf;
+ mType = type.clone();
+ mId = id.clone();
+ mPayload = payload.clone();
}
/**
@@ -174,7 +208,7 @@
* TNF is the top-level type.
*/
public short getTnf() {
- throw new UnsupportedOperationException();
+ return mTnf;
}
/**
@@ -184,21 +218,21 @@
* payload format.
*/
public byte[] getType() {
- throw new UnsupportedOperationException();
+ return mType.clone();
}
/**
* Returns the variable length ID.
*/
public byte[] getId() {
- throw new UnsupportedOperationException();
+ return mId.clone();
}
/**
* Returns the variable length payload.
*/
public byte[] getPayload() {
- throw new UnsupportedOperationException();
+ return mPayload.clone();
}
/**
@@ -206,26 +240,43 @@
* @hide
*/
public byte[] toByteArray() {
- throw new UnsupportedOperationException();
+ return generate(mFlags, mTnf, mType, mId, mPayload);
}
- @Override
public int describeContents() {
return 0;
}
- @Override
public void writeToParcel(Parcel dest, int flags) {
- throw new UnsupportedOperationException();
+ dest.writeInt(mTnf);
+ dest.writeInt(mType.length);
+ dest.writeByteArray(mType);
+ dest.writeInt(mId.length);
+ dest.writeByteArray(mId);
+ dest.writeInt(mPayload.length);
+ dest.writeByteArray(mPayload);
}
public static final Parcelable.Creator<NdefRecord> CREATOR =
new Parcelable.Creator<NdefRecord>() {
public NdefRecord createFromParcel(Parcel in) {
- throw new UnsupportedOperationException();
+ short tnf = (short)in.readInt();
+ int typeLength = in.readInt();
+ byte[] type = new byte[typeLength];
+ in.readByteArray(type);
+ int idLength = in.readInt();
+ byte[] id = new byte[idLength];
+ in.readByteArray(id);
+ int payloadLength = in.readInt();
+ byte[] payload = new byte[payloadLength];
+ in.readByteArray(payload);
+
+ return new NdefRecord(tnf, type, id, payload);
}
public NdefRecord[] newArray(int size) {
- throw new UnsupportedOperationException();
+ return new NdefRecord[size];
}
};
+
+ private native byte[] generate(short flags, short tnf, byte[] type, byte[] id, byte[] data);
}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl b/core/java/android/nfc/NdefTag.aidl
similarity index 89%
copy from core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
copy to core/java/android/nfc/NdefTag.aidl
index e60f4e8..288f667 100644
--- a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
+++ b/core/java/android/nfc/NdefTag.aidl
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package com.trustedlogic.trustednfc.android;
-parcelable NdefMessage;
+package android.nfc;
+
+parcelable NdefTag;
\ No newline at end of file
diff --git a/core/java/android/nfc/NdefTag.java b/core/java/android/nfc/NdefTag.java
new file mode 100644
index 0000000..25303c3
--- /dev/null
+++ b/core/java/android/nfc/NdefTag.java
@@ -0,0 +1,118 @@
+/*
+ * 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;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * NdefTag is a Tag that has NDEF messages or can store NDEF messages.
+ * <p>
+ * NDEF Tag's contain zero or more NDEF Messages in addition to the basic
+ * Tag properties of UID and Type.
+ * <p>
+ * NDEF Tag's that have been initialized will usually contain a single NDEF
+ * Message (and that Message can contain multiple NDEF Records). However it
+ * is possible for NDEF Tag's to contain multiple NDEF Messages.
+ * <p>
+ * This class is a immutable data class that contains the contents of the NDEF
+ * Message(s) as read at Tag discovery time.
+ * <p>
+ * NfcAdapter.createNdefTagConnection() can be used to modify the contents of
+ * some NDEF Tag's.
+ */
+public class NdefTag extends Tag implements Parcelable {
+ private final NdefMessage[] mMessages;
+
+ /**
+ * Hidden constructor to be used by NFC service when a
+ * tag is discovered and by Parcelable methods.
+ * @hide
+ */
+ public NdefTag(int type, byte[] uid, int nativeHandle, NdefMessage[] messages) {
+ super(type, true, uid, nativeHandle);
+ mMessages = messages.clone();
+ }
+
+ /**
+ * Get all NDEF Messages.
+ * <p>
+ * This retrieves the NDEF Messages that were found on the Tag at discovery
+ * time. It does not cause any further RF activity, and does not block.
+ * <p>
+ * Most tags only contain a single NDEF message.
+ *
+ * @return NDEF Messages found at Tag discovery
+ */
+ public NdefMessage[] getNdefMessages() {
+ return mMessages.clone();
+ }
+
+ /**
+ * Get only the NDEF Messages from a single NDEF target on a tag.
+ */
+ public NdefMessage[] getNdefMessages(String target) {
+ //TODO(nxp): new api method
+ throw new UnsupportedOperationException();
+ }
+
+ /** TODO(npelly):
+ * - check that any single tag can only have one of each NDEF type
+ * - ok to include mifare_classic?
+ */
+ public static final String TARGET_TYPE_1 = "type_1";
+ public static final String TARGET_TYPE_2 = "type_2";
+ public static final String TARGET_TYPE_3 = "type_3";
+ public static final String TARGET_TYPE_4 = "type_4";
+ public static final String TARGET_MIFARE_CLASSIC = "type_mifare_classic";
+ public static final String TARGET_OTHER = "other";
+
+ /**
+ * Return the
+ *
+ * @return
+ */
+ public String[] getNdefTargets() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(mMessages.length);
+ dest.writeTypedArray(mMessages, flags);
+ }
+
+ public static final Parcelable.Creator<NdefTag> CREATOR =
+ new Parcelable.Creator<NdefTag>() {
+ public NdefTag createFromParcel(Parcel in) {
+ Tag tag = Tag.CREATOR.createFromParcel(in);
+ int messagesLength = in.readInt();
+ NdefMessage[] messages = new NdefMessage[messagesLength];
+ in.readTypedArray(messages, NdefMessage.CREATOR);
+ return new NdefTag(tag.mType, tag.mUid, tag.mNativeHandle, messages);
+ }
+ public NdefTag[] newArray(int size) {
+ return new NdefTag[size];
+ }
+ };
+}
\ No newline at end of file
diff --git a/core/java/android/nfc/NdefTagConnection.java b/core/java/android/nfc/NdefTagConnection.java
new file mode 100644
index 0000000..0696b37
--- /dev/null
+++ b/core/java/android/nfc/NdefTagConnection.java
@@ -0,0 +1,167 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * NdefTagConnection is a connection to an NDEF target on an NDEF tag.
+ */
+public class NdefTagConnection extends RawTagConnection {
+ public static final int NDEF_MODE_READ_ONCE = 1;
+ public static final int NDEF_MODE_READ_ONLY = 2;
+ public static final int NDEF_MODE_WRITE_ONCE = 3;
+ public static final int NDEF_MODE_WRITE_MANY = 4;
+ public static final int NDEF_MODE_UNKNOWN = 5;
+
+ private static final String TAG = "NFC";
+
+ /**
+ * Internal constructor, to be used by NfcAdapter
+ * @hide
+ */
+ NdefTagConnection(INfcAdapter service, NdefTag tag) throws RemoteException {
+ super(service, tag);
+ }
+
+ /**
+ * Read NDEF message(s).
+ * This will always return the most up to date payload, and can block.
+ * It can be canceled with close().
+ * Most NDEF tags will contain just one NDEF message.
+ * <p>
+ * @throws FormatException if the tag is not NDEF formatted
+ * @throws IOException if the target is lost or connection closed
+ * @throws FormatException
+ */
+ public NdefMessage[] readNdefMessages() throws IOException, FormatException {
+ //TODO(nxp): do not use getLastError(), it is racy
+ try {
+ NdefMessage[] msgArray = new NdefMessage[1];
+ NdefMessage msg = mTagService.read(mTag.mNativeHandle);
+ if (msg == null) {
+ int errorCode = mTagService.getLastError(mTag.mNativeHandle);
+ switch (errorCode) {
+ case ErrorCodes.ERROR_IO:
+ throw new IOException();
+ case ErrorCodes.ERROR_INVALID_PARAM:
+ throw new FormatException();
+ default:
+ // Should not happen
+ throw new IOException();
+ }
+ }
+ msgArray[0] = msg;
+ return msgArray;
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died");
+ return null;
+ }
+ }
+
+ /**
+ * Attempt to write an NDEF message to a tag.
+ * This method will block until the data is written. It can be canceled
+ * with close().
+ * Many tags are write-once, so use this method carefully.
+ * Specification allows for multiple NDEF messages per NDEF tag, but it is
+ * encourage to only write one message, this so API only takes a single
+ * message. Use NdefRecord to write several records to a single tag.
+ * For write-many tags, use makeReadOnly() after this method to attempt
+ * to prevent further modification. For write-once tags this is not
+ * neccesary.
+ * Requires NFC_WRITE permission.
+ * @throws FormatException if the tag is not suitable for NDEF messages
+ * @throws IOException if the target is lost or connection closed or the
+ * write failed
+ */
+ public void writeNdefMessage(NdefMessage message) throws IOException, FormatException {
+ try {
+ int errorCode = mTagService.write(mTag.mNativeHandle, message);
+ switch (errorCode) {
+ case ErrorCodes.SUCCESS:
+ break;
+ case ErrorCodes.ERROR_IO:
+ throw new IOException();
+ case ErrorCodes.ERROR_INVALID_PARAM:
+ throw new FormatException();
+ default:
+ // Should not happen
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died");
+ }
+ }
+
+ /**
+ * Attempts to make the NDEF data in this tag read-only.
+ * This method will block until the action is complete. It can be canceled
+ * with close().
+ * Requires NFC_WRITE permission.
+ * @return true if the tag is now read-only
+ * @throws IOException if the target is lost, or connection closed
+ */
+ public boolean makeReadOnly() throws IOException {
+ try {
+ int errorCode = mTagService.makeReadOnly(mTag.mNativeHandle);
+ 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();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died");
+ return false;
+ }
+ }
+
+ /**
+ * Read/Write mode hint.
+ * Provides a hint if further reads or writes are likely to suceed.
+ * @return one of NDEF_MODE
+ * @throws IOException if the target is lost or connection closed
+ */
+ public int getModeHint() throws IOException {
+ try {
+ int result = mTagService.getModeHint(mTag.mNativeHandle);
+ if (ErrorCodes.isError(result)) {
+ switch (result) {
+ case ErrorCodes.ERROR_IO:
+ throw new IOException();
+ default:
+ // Should not happen
+ throw new IOException();
+ }
+ }
+ return result;
+
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died");
+ return NDEF_MODE_UNKNOWN;
+ }
+ }
+}
\ No newline at end of file
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
new file mode 100644
index 0000000..02b9fb71
--- /dev/null
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -0,0 +1,302 @@
+/*
+ * 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;
+
+import java.lang.UnsupportedOperationException;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+import android.nfc.INfcAdapter;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+//TODO(npelly) permission {@link android.Manifest.permission#NFC_MODIFY}
+/**
+ * Represents a local NFC Adapter.
+ * <p>
+ * Use the static {@link #getDefaultAdapter} method to get the default NFC
+ * Adapter for this Android device. Most Android devices will have only one NFC
+ * Adapter, and {@link #getDefaultAdapter} returns the singleton object.
+ * <p>
+ * {@link NfcAdapter} can be used to create {@link RawTagConnection} or
+ * {@link NdefTagConnection} connections to modify or perform low level access
+ * to NFC Tags.
+ * <p class="note">
+ * <strong>Note:</strong> Some methods require the
+ * TODO permission.
+ */
+public final class NfcAdapter {
+ /**
+ * Intent to start an activity when a non-NDEF tag is discovered.
+ * TODO(npelly) finalize decision on using CATEGORY or DATA URI to provide a
+ * hint for applications to filter the tag type.
+ * TODO(npelly) probably combine these two intents since tags aren't that simple
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
+
+ /**
+ * Intent to start an activity when a NDEF tag is discovered. TODO(npelly)
+ * finalize decision on using CATEGORY or DATA URI to provide a hint for
+ * applications to filter the tag type.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_NDEF_TAG_DISCOVERED =
+ "android.nfc.action.NDEF_TAG_DISCOVERED";
+
+ /**
+ * Mandatory Tag extra for the ACTION_TAG and ACTION_NDEF_TAG intents.
+ */
+ public static final String EXTRA_TAG = "android.nfc.extra.TAG";
+
+ /**
+ * Broadcast Action: a transaction with a secure element has been detected.
+ * <p>
+ * Always contains the extra field
+ * {@link android.nfc.NfcAdapter#EXTRA_AID}
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_TRANSACTION_DETECTED =
+ "android.nfc.action.TRANSACTION_DETECTED";
+
+ /**
+ * Mandatory byte array extra field in
+ * {@link android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED}.
+ * <p>
+ * Contains the AID of the applet involved in the transaction.
+ * @hide
+ */
+ public static final String EXTRA_AID = "android.nfc.extra.AID";
+
+ /**
+ * LLCP link status: The LLCP link is activated.
+ * @hide
+ */
+ public static final int LLCP_LINK_STATE_ACTIVATED = 0;
+
+ /**
+ * LLCP link status: The LLCP link is deactivated.
+ * @hide
+ */
+ public static final int LLCP_LINK_STATE_DEACTIVATED = 1;
+
+ /**
+ * Broadcast Action: the LLCP link state changed.
+ * <p>
+ * Always contains the extra field
+ * {@link android.nfc.NfcAdapter#EXTRA_LLCP_LINK_STATE_CHANGED}.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_LLCP_LINK_STATE_CHANGED =
+ "android.nfc.action.LLCP_LINK_STATE_CHANGED";
+
+ /**
+ * Used as int extra field in
+ * {@link android.nfc.NfcAdapter#ACTION_LLCP_LINK_STATE_CHANGED}.
+ * <p>
+ * It contains the new state of the LLCP link.
+ * @hide
+ */
+ public static final String EXTRA_LLCP_LINK_STATE_CHANGED = "android.nfc.extra.LLCP_LINK_STATE";
+
+ /**
+ * Tag Reader Discovery mode
+ * @hide
+ */
+ private static final int DISCOVERY_MODE_TAG_READER = 0;
+
+ /**
+ * NFC-IP1 Peer-to-Peer mode Enables the manager to act as a peer in an
+ * NFC-IP1 communication. Implementations should not assume that the
+ * controller will end up behaving as an NFC-IP1 target or initiator and
+ * should handle both cases, depending on the type of the remote peer type.
+ * @hide
+ */
+ private static final int DISCOVERY_MODE_NFCIP1 = 1;
+
+ /**
+ * Card Emulation mode Enables the manager to act as an NFC tag. Provided
+ * that a Secure Element (an UICC for instance) is connected to the NFC
+ * controller through its SWP interface, it can be exposed to the outside
+ * NFC world and be addressed by external readers the same way they would
+ * with a tag.
+ * <p>
+ * Which Secure Element is exposed is implementation-dependent.
+ *
+ * @hide
+ */
+ private static final int DISCOVERY_MODE_CARD_EMULATION = 2;
+
+ private static final String TAG = "NFC";
+
+ private static boolean sIsInitialized = false;
+ private static NfcAdapter sAdapter;
+
+ private final INfcAdapter mService;
+
+ private NfcAdapter(INfcAdapter service) {
+ mService = service;
+ }
+
+ /**
+ * Get a handle to the default NFC Adapter on this Android device.
+ * <p>
+ * Most Android devices will only have one NFC Adapter (NFC Controller).
+ *
+ * @return the default NFC adapter, or null if no NFC adapter exists
+ */
+ public static NfcAdapter getDefaultAdapter() {
+ synchronized (NfcAdapter.class) {
+ if (sIsInitialized) {
+ return sAdapter;
+ }
+ sIsInitialized = true;
+
+ // TODO(npelly): check which method to use here to get the service
+ IBinder b = ServiceManager.getService(Context.NFC_SERVICE);
+ if (b == null) {
+ return null; // This device does not have NFC
+ }
+
+ sAdapter = new NfcAdapter(INfcAdapter.Stub.asInterface(b));
+ return sAdapter;
+ }
+ }
+
+ /**
+ * Return true if this NFC Adapter is enabled to discover new tags.
+ * <p>
+ * If this method returns false, then applications should request the user
+ * turn on NFC tag discovery in Settings.
+ *
+ * @return true if this NFC Adapter is enabled to discover new tags
+ */
+ public boolean isTagDiscoveryEnabled() {
+ try {
+ return mService.isEnabled();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in isEnabled()", e);
+ return false;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public boolean enableTagDiscovery() {
+ try {
+ return mService.enable();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in enable()", e);
+ return false;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public boolean disableTagDiscovery() {
+ try {
+ return mService.disable();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in disable()", e);
+ return false;
+ }
+ }
+
+ /**
+ * Set the NDEF Message that this NFC adapter should appear as to Tag
+ * readers.
+ * <p>
+ * Any Tag reader can read the contents of the local tag when it is in
+ * proximity, without any further user confirmation.
+ * <p>
+ * The implementation of this method must either
+ * <ul>
+ * <li>act as a passive tag containing this NDEF message
+ * <li>provide the NDEF message on over LLCP to peer NFC adapters
+ * </ul>
+ * The NDEF message is preserved across reboot.
+ * <p>
+ * Requires NFC_WRITE permission
+ *
+ * @param message NDEF message to make public
+ */
+ public void setLocalNdefMessage(NdefMessage message) {
+ try {
+ mService.localSet(message);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died", e);
+ }
+ }
+
+ /**
+ * Get the NDEF Message that this adapter appears as to Tag readers.
+ * <p>
+ * Requires NFC_WRITE permission
+ *
+ * @return NDEF Message that is publicly readable
+ */
+ public NdefMessage getLocalNdefMessage() {
+ try {
+ return mService.localGet();
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died", e);
+ return null;
+ }
+ }
+
+ /**
+ * Create a raw tag connection to the default Target
+ */
+ public RawTagConnection createRawTagConnection(Tag tag) {
+ try {
+ return new RawTagConnection(mService, tag);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died", e);
+ return null;
+ }
+ }
+
+ /**
+ * Create a raw tag connection to the specified Target
+ */
+ public RawTagConnection createRawTagConnection(Tag tag, String target) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Create an NDEF tag connection to the default Target
+ */
+ public NdefTagConnection createNdefTagConnection(NdefTag tag) {
+ try {
+ return new NdefTagConnection(mService, tag);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died", e);
+ return null;
+ }
+ }
+
+ /**
+ * Create an NDEF tag connection to the specified Target
+ */
+ public NdefTagConnection createNdefTagConnection(NdefTag tag, String target) {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/core/java/android/nfc/RawTagConnection.java b/core/java/android/nfc/RawTagConnection.java
new file mode 100644
index 0000000..67a836f
--- /dev/null
+++ b/core/java/android/nfc/RawTagConnection.java
@@ -0,0 +1,139 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * RawTagConnection is a low-level connection to a Tag.
+ * <p>
+ * The only data transfer method that TagConnection offers is transceive().
+ * Applications must implement there own protocol stack on top of transceive().
+ * <p>
+ * Use NfcAdapter.createRawTagConnection() to create a RawTagConnection object.
+ *
+ * * <p class="note"><strong>Note:</strong>
+ * Most methods require the {@link android.Manifest.permission#BLUETOOTH}
+ * permission and some also require the
+ * {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+
+ */
+public class RawTagConnection {
+
+ /*package*/ final INfcAdapter mService;
+ /*package*/ final INfcTag mTagService;
+ /*package*/ final Tag mTag;
+ /*package*/ boolean mIsConnected;
+
+ private static final String TAG = "NFC";
+
+ /* package private */ RawTagConnection(INfcAdapter service, Tag tag) throws RemoteException {
+ mService = service;
+ mTagService = service.getNfcTagInterface();
+ mService.openTagConnection(tag); // TODO(nxp): don't connect until connect()
+ mTag = tag;
+ }
+
+ /**
+ * Get the Tag this connection is associated with.
+ */
+ public Tag getTag() {
+ return mTag;
+ }
+
+ public String getTagTarget() {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Helper to indicate if transceive() calls might succeed.
+ * <p>
+ * Does not cause RF activity, and does not block.
+ * <p>
+ * Returns true if connect() has completed successfully, and the Tag is not
+ * yet known to be out of range. Applications must still handle IOException
+ * while using transceive().
+ */
+ public boolean isConnected() {
+ // TODO(nxp): update mIsConnected when tag goes out of range -
+ // but do not do an active prescence check in
+ // isConnected()
+ return mIsConnected;
+ }
+
+ /**
+ * Connect to tag.
+ * <p>
+ * This method blocks until the connection is established.
+ * <p>
+ * close() can be called from another thread to cancel this connection
+ * attempt.
+ *
+ * @throws IOException if the target is lost, or connect canceled
+ */
+ public void connect() throws IOException {
+ //TODO(nxp): enforce exclusivity
+ mIsConnected = true;
+ }
+
+ /**
+ * Close tag connection.
+ * <p>
+ * Causes blocking operations such as transceive() or connect() to
+ * be canceled and immediately throw IOException.
+ * <p>
+ * This object cannot be re-used after calling close(). Further calls
+ * to transceive() or connect() will fail.
+ */
+ public void close() {
+ mIsConnected = false;
+ try {
+ mTagService.close(mTag.mNativeHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died", e);
+ }
+ }
+
+ /**
+ * Send data to a tag, and return the response.
+ * <p>
+ * This method will block until the response is received. It can be canceled
+ * with close().
+ * <p>
+ * Requires NFC_WRITE 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 {
+ try {
+ byte[] response = mTagService.transceive(mTag.mNativeHandle, data);
+ if (response == null) {
+ throw new IOException("transcieve failed");
+ }
+ return response;
+ } catch (RemoteException e) {
+ Log.e(TAG, "NFC service died", e);
+ throw new IOException("NFC service died");
+ }
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl b/core/java/android/nfc/Tag.aidl
similarity index 89%
copy from core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
copy to core/java/android/nfc/Tag.aidl
index e60f4e8..312261e 100644
--- a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
+++ b/core/java/android/nfc/Tag.aidl
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package com.trustedlogic.trustednfc.android;
-parcelable NdefMessage;
+package android.nfc;
+
+parcelable Tag;
\ No newline at end of file
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
new file mode 100644
index 0000000..8f731e7
--- /dev/null
+++ b/core/java/android/nfc/Tag.java
@@ -0,0 +1,215 @@
+/*
+ * 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;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Immutable data class, represents a discovered tag.
+ * <p>
+ * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags,
+ * Sony Felica Tags.
+ * <p>
+ * Tag's have a type and usually have a UID.
+ * <p>
+ * Tag objects are passed to applications via the NfcAdapter.EXTRA_TAG extra
+ * in NfcAdapter.ACTION_TAG_DISCOVERED intents. The 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 TagConnection
+ * (NfcAdapter.createTagConnection()).
+ * <p>
+ * This Tag object can only be used to create a TagConnection while it is in
+ * range. If it is removed and then returned to range then the most recent
+ * Tag object (in ACTION_TAG_DISCOVERED) should be used to create a
+ * TagConnection.
+ */
+public class Tag implements Parcelable {
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_ISO14443_A = 1; /* phNfc_eISO14443_A_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_ISO14443_4A = 2; /* phNfc_eISO14443_4A_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_ISO14443_3A = 3; /* phNfc_eISO14443_3A_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_MIFARE = 4; /* phNfc_eMifare_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_ISO14443_B = 5; /* phNfc_eISO14443_B_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_ISO14443_4B = 6; /* phNfc_eISO14443_4B_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_ISO14443_B_PRIME = 7; /* phNfc_eISO14443_BPrime_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_FELICA = 8; /* phNfc_eFelica_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_JEWEL = 9; /* phNfc_eJewel_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_ISO15693 = 10; /* phNfc_eISO15693_PICC */
+
+ /**
+ * @hide
+ */
+ public static final int NFC_TAG_OTHER = 11; /* phNfc_ePICC_DevType */
+
+
+ public static final String TARGET_ISO_14443_3A = "iso14443_3a";
+
+ public static final String TARGET_ISO_14443_3B = "iso14443_3b";
+
+ public static final String TARGET_ISO_14443_3B_PRIME = "iso14443_3b";
+
+ public static final String TARGET_ISO_14443_4 = "iso14443_4";
+
+ public static final String TARGET_ISO_15693 = "iso15693";
+
+ public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4";
+
+ public static final String TARGET_TOPAZ = "topaz";
+
+ public static final String TARGET_OTHER = "other";
+
+ /*package*/ final int mType;
+ /*package*/ final boolean mIsNdef;
+ /*package*/ final byte[] mUid;
+ /*package*/ final int mNativeHandle;
+
+ /**
+ * Hidden constructor to be used by NFC service only.
+ * @hide
+ */
+ public Tag(int type, boolean isNdef, byte[] uid, int nativeHandle) {
+ mType = type;
+ mIsNdef = isNdef;
+ mUid = uid.clone();
+ mNativeHandle = nativeHandle;
+ }
+
+ /**
+ * For use by NfcService only.
+ * @hide
+ */
+ public int getHandle() {
+ return mNativeHandle;
+ }
+
+ /**
+ * Return the available targets that this NFC adapter can use to create
+ * a RawTagConnection.
+ *
+ * @return
+ */
+ public String[] getRawTargets() {
+ //TODO
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get the Tag type.
+ * <p>
+ * The Tag type is one of the NFC_TAG constants. It is read at discovery
+ * time and this method does not cause any further RF activity and does not
+ * block.
+ *
+ * @return a NFC_TAG constant
+ * @hide
+ */
+ public int getType() {
+ return mType;
+ }
+
+ /**
+ * Get the Tag Identifier (if it has one).
+ * <p>
+ * Tag ID is usually a serial number for the tag.
+ * <p>
+ * The Tag ID is read at discovery time and this method does not cause any
+ * further RF activity and does not block.
+ *
+ * @return ID, or null if it does not exist
+ */
+ public byte[] getId() {
+ if (mUid.length > 0) {
+ return mUid.clone();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ boolean[] booleans = new boolean[] {mIsNdef};
+ dest.writeInt(mType);
+ dest.writeBooleanArray(booleans);
+ dest.writeInt(mUid.length);
+ dest.writeByteArray(mUid);
+ dest.writeInt(mNativeHandle);
+ }
+
+ public static final Parcelable.Creator<Tag> CREATOR =
+ new Parcelable.Creator<Tag>() {
+ public Tag createFromParcel(Parcel in) {
+ boolean[] booleans = new boolean[1];
+ int type = in.readInt();
+ in.readBooleanArray(booleans);
+ boolean isNdef = booleans[0];
+ int uidLength = in.readInt();
+ byte[] uid = new byte[uidLength];
+ in.readByteArray(uid);
+ int nativeHandle = in.readInt();
+
+ return new Tag(type, isNdef, uid, nativeHandle);
+ }
+ public Tag[] newArray(int size) {
+ return new Tag[size];
+ }
+ };
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/OnObbStateChangeListener.java b/core/java/android/os/storage/OnObbStateChangeListener.java
index 950195b..1fb1782 100644
--- a/core/java/android/os/storage/OnObbStateChangeListener.java
+++ b/core/java/android/os/storage/OnObbStateChangeListener.java
@@ -67,9 +67,9 @@
public static final int ERROR_ALREADY_MOUNTED = 24;
/**
- * The current application does not have permission to use this OBB because
- * the OBB indicates it's owned by a different package or the key used to
- * open it is incorrect. Returned in status messages from calls made via
+ * The current application does not have permission to use this OBB. This
+ * could be because the OBB indicates it's owned by a different package or
+ * some other error. Returned in status messages from calls made via
* {@link StorageManager}
*/
public static final int ERROR_PERMISSION_DENIED = 25;
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 8fd0e0a..72bf6b0 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -300,6 +300,15 @@
*/
public static final String COLUMN_DESCRIPTION = "description";
+ /**
+ * Set to true if this download is deleted. It is completely removed from the database
+ * when MediaProvider database also deletes the metadata asociated with this downloaded file.
+ * <P>Type: BOOLEAN</P>
+ * <P>Owner can Read</P>
+ * @hide
+ */
+ public static final String COLUMN_DELETED = "deleted";
+
/*
* Lists the destinations that an application can specify for a download.
*/
@@ -881,6 +890,23 @@
public static final String COLUMN_BYPASS_RECOMMENDED_SIZE_LIMIT =
"bypass_recommended_size_limit";
+ /**
+ * Set to true if this download is deleted. It is completely removed from the database
+ * when MediaProvider database also deletes the metadata asociated with this downloaded file.
+ * <P>Type: BOOLEAN</P>
+ * <P>Owner can Read</P>
+ */
+ public static final String COLUMN_DELETED = "deleted";
+
+ /**
+ * The URI to the corresponding entry in MediaProvider for this downloaded entry. It is
+ * used to delete the entries from MediaProvider database when it is deleted from the
+ * downloaded list.
+ * <P>Type: TEXT</P>
+ * <P>Owner can Read</P>
+ */
+ public static final String COLUMN_MEDIAPROVIDER_URI = "mediaprovider_uri";
+
/*
* Lists the destinations that an application can specify for a download.
*/
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index a52a221..5cbfe74 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -71,7 +71,6 @@
private final BluetoothService mBluetoothService;
private final BluetoothAdapter mAdapter;
private int mTargetA2dpState;
- private boolean mAdjustedPriority = false;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -326,7 +325,10 @@
String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
- // State is DISCONNECTED
+ // State is DISCONNECTED and we are connecting.
+ if (getSinkPriority(device) < BluetoothA2dp.PRIORITY_AUTO_CONNECT) {
+ setSinkPriority(device, BluetoothA2dp.PRIORITY_AUTO_CONNECT);
+ }
handleSinkStateChange(device, state, BluetoothA2dp.STATE_CONNECTING);
if (!connectSinkNative(path)) {
@@ -491,14 +493,10 @@
mTargetA2dpState = -1;
if (getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF &&
- state == BluetoothA2dp.STATE_CONNECTING ||
state == BluetoothA2dp.STATE_CONNECTED) {
// We have connected or attempting to connect.
// Bump priority
setSinkPriority(device, BluetoothA2dp.PRIORITY_AUTO_CONNECT);
- }
-
- if (state == BluetoothA2dp.STATE_CONNECTED) {
// We will only have 1 device with AUTO_CONNECT priority
// To be backward compatible set everyone else to have PRIORITY_ON
adjustOtherSinkPriorities(device);
@@ -515,14 +513,11 @@
}
private void adjustOtherSinkPriorities(BluetoothDevice connectedDevice) {
- if (!mAdjustedPriority) {
- for (BluetoothDevice device : mAdapter.getBondedDevices()) {
- if (getSinkPriority(device) >= BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
- !device.equals(connectedDevice)) {
- setSinkPriority(device, BluetoothA2dp.PRIORITY_ON);
- }
+ for (BluetoothDevice device : mAdapter.getBondedDevices()) {
+ if (getSinkPriority(device) >= BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
+ !device.equals(connectedDevice)) {
+ setSinkPriority(device, BluetoothA2dp.PRIORITY_ON);
}
- mAdjustedPriority = true;
}
}
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 94f80cc..c877c5c 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -512,7 +512,14 @@
authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF;
if (authorized) {
Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address);
- mBluetoothService.notifyIncomingA2dpConnection(address);
+ // Some headsets try to connect AVCTP before AVDTP - against the recommendation
+ // If AVCTP connection fails, we get stuck in IncomingA2DP state in the state
+ // machine. We don't handle AVCTP signals currently. We only send
+ // intents for AVDTP state changes. We need to handle both of them in
+ // some cases. For now, just don't move to incoming state in this case.
+ if (!BluetoothUuid.isAvrcpTarget(uuid)) {
+ mBluetoothService.notifyIncomingA2dpConnection(address);
+ }
} else {
Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address);
}
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 71b4ee2..4d4d309 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2227,6 +2227,16 @@
mA2dpService = a2dpService;
}
+ public void sendProfileStateMessage(int profile, int cmd) {
+ Message msg = new Message();
+ msg.what = cmd;
+ if (profile == BluetoothProfileState.HFP) {
+ mHfpProfileState.sendMessage(msg);
+ } else if (profile == BluetoothProfileState.A2DP) {
+ mA2dpProfileState.sendMessage(msg);
+ }
+ }
+
private static void log(String msg) {
Log.d(TAG, msg);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6df5445..040bf15 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -784,6 +784,11 @@
private EdgeGlow mEdgeGlowBottom;
private EdgeGlow mEdgeGlowLeft;
private EdgeGlow mEdgeGlowRight;
+ /*
+ * These manage the delta the user has pulled beyond the edges.
+ */
+ private int mOverscrollDeltaX;
+ private int mOverscrollDeltaY;
// Used to match key downs and key ups
private boolean mGotKeyDown;
@@ -2569,17 +2574,59 @@
boolean clampedY) {
mInOverScrollMode = false;
int maxX = computeMaxScrollX();
+ int maxY = computeMaxScrollY();
if (maxX == 0) {
// do not over scroll x if the page just fits the screen
scrollX = pinLocX(scrollX);
} else if (scrollX < 0 || scrollX > maxX) {
mInOverScrollMode = true;
}
- if (scrollY < 0 || scrollY > computeMaxScrollY()) {
+ if (scrollY < 0 || scrollY > maxY) {
mInOverScrollMode = true;
}
+ int oldX = mScrollX;
+ int oldY = mScrollY;
+
super.scrollTo(scrollX, scrollY);
+
+ // Only show overscroll bars if there was no movement in any direction
+ // as a result of scrolling.
+ if (mEdgeGlowTop != null && oldY == mScrollY && oldX == mScrollX) {
+ // Don't show left/right glows if we fit the whole content.
+ // Also don't show if there was vertical movement.
+ if (maxX > 0) {
+ final int pulledToX = oldX + mOverscrollDeltaX;
+ if (pulledToX < 0) {
+ mEdgeGlowLeft.onPull((float) mOverscrollDeltaX / getWidth());
+ if (!mEdgeGlowRight.isFinished()) {
+ mEdgeGlowRight.onRelease();
+ }
+ } else if (pulledToX > maxX) {
+ mEdgeGlowRight.onPull((float) mOverscrollDeltaX / getWidth());
+ if (!mEdgeGlowLeft.isFinished()) {
+ mEdgeGlowLeft.onRelease();
+ }
+ }
+ mOverscrollDeltaX = 0;
+ }
+
+ if (maxY > 0 || getOverScrollMode() == OVER_SCROLL_ALWAYS) {
+ final int pulledToY = oldY + mOverscrollDeltaY;
+ if (pulledToY < 0) {
+ mEdgeGlowTop.onPull((float) mOverscrollDeltaY / getHeight());
+ if (!mEdgeGlowBottom.isFinished()) {
+ mEdgeGlowBottom.onRelease();
+ }
+ } else if (pulledToY > maxY) {
+ mEdgeGlowBottom.onPull((float) mOverscrollDeltaY / getHeight());
+ if (!mEdgeGlowTop.isFinished()) {
+ mEdgeGlowTop.onRelease();
+ }
+ }
+ mOverscrollDeltaY = 0;
+ }
+ }
}
/**
@@ -3947,6 +3994,16 @@
// requestFormData, and it needs to have the correct nodePointer.
mWebTextView.setNodePointer(nodePointer);
mWebTextView.setType(nativeFocusCandidateType());
+ Rect paddingRect = nativeFocusCandidatePaddingRect();
+ if (paddingRect != null) {
+ // Use contentToViewDimension since these are the dimensions of
+ // the padding.
+ mWebTextView.setPadding(
+ contentToViewDimension(paddingRect.left),
+ contentToViewDimension(paddingRect.top),
+ contentToViewDimension(paddingRect.right),
+ contentToViewDimension(paddingRect.bottom));
+ }
if (null == text) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "rebuildWebTextView null == text");
@@ -5039,6 +5096,8 @@
if (!mAllowPanAndScale) {
return true;
}
+ mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
+ mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
}
x = mScaleDetector.getFocusX();
y = mScaleDetector.getFocusY();
@@ -5550,42 +5609,16 @@
final int oldY = mScrollY;
final int rangeX = computeMaxScrollX();
final int rangeY = computeMaxScrollY();
+
+ if (mEdgeGlowTop != null) {
+ // Save the deltas for overscroll glow.
+ mOverscrollDeltaX = deltaX;
+ mOverscrollDeltaY = deltaY;
+ }
+
overScrollBy(deltaX, deltaY, oldX, oldY,
rangeX, rangeY,
mOverscrollDistance, mOverscrollDistance, true);
-
- if (mEdgeGlowTop != null) {
- // Don't show left/right glows if we fit the whole content.
- if (rangeX > 0) {
- final int pulledToX = oldX + deltaX;
- if (pulledToX < 0) {
- mEdgeGlowLeft.onPull((float) deltaX / getWidth());
- if (!mEdgeGlowRight.isFinished()) {
- mEdgeGlowRight.onRelease();
- }
- } else if (pulledToX > rangeX) {
- mEdgeGlowRight.onPull((float) deltaX / getWidth());
- if (!mEdgeGlowLeft.isFinished()) {
- mEdgeGlowLeft.onRelease();
- }
- }
- }
-
- if (rangeY > 0 || getOverScrollMode() == OVER_SCROLL_ALWAYS) {
- final int pulledToY = oldY + deltaY;
- if (pulledToY < 0) {
- mEdgeGlowTop.onPull((float) deltaY / getHeight());
- if (!mEdgeGlowBottom.isFinished()) {
- mEdgeGlowBottom.onRelease();
- }
- } else if (pulledToY > rangeY) {
- mEdgeGlowBottom.onPull((float) deltaY / getHeight());
- if (!mEdgeGlowTop.isFinished()) {
- mEdgeGlowTop.onRelease();
- }
- }
- }
- }
}
if (!getSettings().getBuiltInZoomControls()) {
boolean showPlusMinus = mMinZoomScale < mMaxZoomScale;
@@ -7839,6 +7872,13 @@
/* package */ native int nativeFocusCandidateMaxLength();
/* package */ native String nativeFocusCandidateName();
private native Rect nativeFocusCandidateNodeBounds();
+ /**
+ * @return A Rect with left, top, right, bottom set to the corresponding
+ * padding values in the focus candidate, if it is a textfield/textarea with
+ * a style. Otherwise return null. This is not actually a rectangle; Rect
+ * is being used to pass four integers.
+ */
+ private native Rect nativeFocusCandidatePaddingRect();
/* package */ native int nativeFocusCandidatePointer();
private native String nativeFocusCandidateText();
private native int nativeFocusCandidateTextSize();
diff --git a/core/java/android/widget/EdgeGlow.java b/core/java/android/widget/EdgeGlow.java
index c1a389a..416be86 100644
--- a/core/java/android/widget/EdgeGlow.java
+++ b/core/java/android/widget/EdgeGlow.java
@@ -33,10 +33,10 @@
private static final int RECEDE_TIME = 1000;
// Time it will take before a pulled glow begins receding
- private static final int PULL_TIME = 250;
+ private static final int PULL_TIME = 167;
// Time it will take for a pulled glow to decay to partial strength before release
- private static final int PULL_DECAY_TIME = 10000;
+ private static final int PULL_DECAY_TIME = 1000;
private static final float MAX_ALPHA = 0.8f;
private static final float HELD_EDGE_ALPHA = 0.7f;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5be52c4..9080f96 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -92,6 +92,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
+import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.view.ViewRoot;
@@ -4446,6 +4447,7 @@
}
hideControllers();
+ stopTextSelectionMode();
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
@@ -6852,8 +6854,17 @@
}
private void prepareCursorControllers() {
+ boolean windowSupportsHandles = false;
+
+ ViewGroup.LayoutParams params = getRootView().getLayoutParams();
+ if (params instanceof WindowManager.LayoutParams) {
+ WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
+ windowSupportsHandles = windowParams.type < WindowManager.LayoutParams.FIRST_SUB_WINDOW
+ || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
+ }
+
// TODO Add an extra android:cursorController flag to disable the controller?
- if (mCursorVisible && mLayout != null) {
+ if (windowSupportsHandles && mCursorVisible && mLayout != null) {
if (mInsertionPointCursorController == null) {
mInsertionPointCursorController = new InsertionPointCursorController();
}
@@ -6861,7 +6872,7 @@
mInsertionPointCursorController = null;
}
- if (textCanBeSelected() && mLayout != null) {
+ if (windowSupportsHandles && textCanBeSelected() && mLayout != null) {
if (mSelectionModifierCursorController == null) {
mSelectionModifierCursorController = new SelectionModifierCursorController();
}
diff --git a/core/java/com/android/internal/app/ShutdownThread.java b/core/java/com/android/internal/app/ShutdownThread.java
index d1aff2a..714b259 100644
--- a/core/java/com/android/internal/app/ShutdownThread.java
+++ b/core/java/com/android/internal/app/ShutdownThread.java
@@ -33,6 +33,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.Vibrator;
import android.os.storage.IMountService;
import android.os.storage.IMountShutdownObserver;
@@ -60,6 +61,9 @@
private static boolean mReboot;
private static String mRebootReason;
+ // Provides shutdown assurance in case the system_server is killed
+ public static final String SHUTDOWN_ACTION_PROPERTY = "sys.shutdown.requested";
+
// static instance of this thread
private static final ShutdownThread sInstance = new ShutdownThread();
@@ -195,7 +199,17 @@
actionDone();
}
};
-
+
+ /*
+ * Write a system property in case the system_server reboots before we
+ * get to the actual hardware restart. If that happens, we'll retry at
+ * the beginning of the SystemServer startup.
+ */
+ {
+ String reason = (mReboot ? "1" : "0") + (mRebootReason != null ? mRebootReason : "");
+ SystemProperties.set(SHUTDOWN_ACTION_PROPERTY, reason);
+ }
+
Log.i(TAG, "Sending shutdown broadcast...");
// First send the high-level shut down broadcast.
@@ -325,10 +339,21 @@
}
}
- if (mReboot) {
- Log.i(TAG, "Rebooting, reason: " + mRebootReason);
+ rebootOrShutdown(mReboot, mRebootReason);
+ }
+
+ /**
+ * Do not call this directly. Use {@link #reboot(Context, String, boolean)}
+ * or {@link #shutdown(Context, boolean)} instead.
+ *
+ * @param reboot true to reboot or false to shutdown
+ * @param reason reason for reboot
+ */
+ public static void rebootOrShutdown(boolean reboot, String reason) {
+ if (reboot) {
+ Log.i(TAG, "Rebooting, reason: " + reason);
try {
- Power.reboot(mRebootReason);
+ Power.reboot(reason);
} catch (Exception e) {
Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
}
diff --git a/core/java/com/trustedlogic/trustednfc/android/ILlcpConnectionlessSocket.aidl b/core/java/com/trustedlogic/trustednfc/android/ILlcpConnectionlessSocket.aidl
deleted file mode 100644
index 35746ad..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/ILlcpConnectionlessSocket.aidl
+++ /dev/null
@@ -1,34 +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 com.trustedlogic.trustednfc.android;
-
-import com.trustedlogic.trustednfc.android.LlcpPacket;
-
-/**
- * TODO
- *
- * {@hide}
- */
-interface ILlcpConnectionlessSocket
-{
-
- void close(int nativeHandle);
- int getSap(int nativeHandle);
- LlcpPacket receiveFrom(int nativeHandle);
- int sendTo(int nativeHandle, in LlcpPacket packet);
-
-}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/ILlcpSocket.aidl b/core/java/com/trustedlogic/trustednfc/android/ILlcpSocket.aidl
deleted file mode 100644
index e9169d8..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/ILlcpSocket.aidl
+++ /dev/null
@@ -1,41 +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 com.trustedlogic.trustednfc.android;
-
-/**
- * TODO
- *
- * {@hide}
- */
-interface ILlcpSocket
-{
-
- int close(int nativeHandle);
- int connect(int nativeHandle, int sap);
- int connectByName(int nativeHandle, String sn);
- int getConnectTimeout(int nativeHandle);
- int getLocalSap(int nativeHandle);
- int getLocalSocketMiu(int nativeHandle);
- int getLocalSocketRw(int nativeHandle);
- int getRemoteSocketMiu(int nativeHandle);
- int getRemoteSocketRw(int nativeHandle);
- int receive(int nativeHandle, out byte[] receiveBuffer);
- int send(int nativeHandle, in byte[] data);
- void setConnectTimeout(int nativeHandle, int timeout);
-
-}
-
diff --git a/core/java/com/trustedlogic/trustednfc/android/INfcManager.aidl b/core/java/com/trustedlogic/trustednfc/android/INfcManager.aidl
deleted file mode 100644
index ce36ab2..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/INfcManager.aidl
+++ /dev/null
@@ -1,61 +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 com.trustedlogic.trustednfc.android;
-
-import com.trustedlogic.trustednfc.android.ILlcpSocket;
-import com.trustedlogic.trustednfc.android.ILlcpServiceSocket;
-import com.trustedlogic.trustednfc.android.ILlcpConnectionlessSocket;
-import com.trustedlogic.trustednfc.android.INfcTag;
-import com.trustedlogic.trustednfc.android.IP2pTarget;
-import com.trustedlogic.trustednfc.android.IP2pInitiator;
-
-
-/**
- * Interface that allows controlling NFC activity.
- *
- * {@hide}
- */
-interface INfcManager
-{
-
- ILlcpSocket getLlcpInterface();
- ILlcpConnectionlessSocket getLlcpConnectionlessInterface();
- ILlcpServiceSocket getLlcpServiceInterface();
- INfcTag getNfcTagInterface();
- IP2pTarget getP2pTargetInterface();
- IP2pInitiator getP2pInitiatorInterface();
-
- void cancel();
- int createLlcpConnectionlessSocket(int sap);
- int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
- int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
- int deselectSecureElement();
- boolean disable();
- boolean enable();
- int getOpenTimeout();
- String getProperties(String param);
- int[] getSecureElementList();
- int getSelectedSecureElement();
- boolean isEnabled();
- int openP2pConnection();
- int openTagConnection();
- int selectSecureElement(int seId);
- void setOpenTimeout(int timeout);
- int setProperties(String param, String value);
-
-}
-
diff --git a/core/java/com/trustedlogic/trustednfc/android/IP2pTarget.aidl b/core/java/com/trustedlogic/trustednfc/android/IP2pTarget.aidl
deleted file mode 100644
index 8dcdf18..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/IP2pTarget.aidl
+++ /dev/null
@@ -1,33 +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 com.trustedlogic.trustednfc.android;
-
-/**
- * TODO
- *
- * {@hide}
- */
-interface IP2pTarget
-{
-
- byte[] getGeneralBytes(int nativeHandle);
- int getMode(int nativeHandle);
- int connect(int nativeHandle);
- boolean disconnect(int nativeHandle);
- byte[] transceive(int nativeHandle, in byte[] data);
-
-}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpConnectionlessSocket.java b/core/java/com/trustedlogic/trustednfc/android/LlcpConnectionlessSocket.java
index 0270626..eccdeb13 100644
--- a/core/java/com/trustedlogic/trustednfc/android/LlcpConnectionlessSocket.java
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpConnectionlessSocket.java
@@ -24,7 +24,9 @@
import java.io.IOException;
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+import android.nfc.ErrorCodes;
+import android.nfc.ILlcpConnectionlessSocket;
+import android.nfc.LlcpPacket;
import android.os.RemoteException;
import android.util.Log;
@@ -32,19 +34,19 @@
/**
* LlcpConnectionlessSocket represents a LLCP Connectionless object to be used
* in a connectionless communication
- *
+ *
* @since AA02.01
* @hide
*/
public class LlcpConnectionlessSocket {
-
-
+
+
private static final String TAG = "LlcpConnectionlessSocket";
/**
* The handle returned by the NFC service and used to identify the LLCP connectionless socket in
* every call of this class.
- *
+ *
* @hide
*/
protected int mHandle;
@@ -52,15 +54,15 @@
/**
* The entry point for LLCP Connectionless socket operations.
- *
+ *
* @hide
*/
protected ILlcpConnectionlessSocket mService;
-
-
+
+
/**
* Internal constructor for the LlcpConnectionlessSocket class.
- *
+ *
* @param service The entry point to the Nfc Service for LLCP Connectionless socket class.
* @param handle The handle returned by the NFC service and used to identify
* the socket in subsequent calls.
@@ -73,7 +75,7 @@
/**
* Send data to a specific LLCP Connectionless client
- *
+ *
* @param packet Service Access Point number related to a LLCP
* Connectionless client and a data buffer to send
* @throws IOException if the LLCP link has been lost or deactivated.
@@ -93,7 +95,7 @@
/**
* Receive data from a LLCP Connectionless client
- *
+ *
* @return data data received from a specific LLCP Connectionless client
* @throws IOException if the LLCP link has been lost or deactivated.
* @see LlcpPacket
@@ -106,7 +108,7 @@
return packet;
}else{
// Handle potential errors
- throw new IOException();
+ throw new IOException();
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in receiveFrom(): ", e);
@@ -116,7 +118,7 @@
/**
* Close the created Connectionless socket.
- *
+ *
* @since AA02.01
*/
public void close() {
@@ -129,13 +131,13 @@
/**
* Returns the local Service Access Point number of the socket
- *
+ *
* @return sap
* @since AA02.01
*/
public int getSap() {
int sap = 0;
-
+
try {
sap = mService.getSap(mHandle);
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpServiceSocket.java b/core/java/com/trustedlogic/trustednfc/android/LlcpServiceSocket.java
index a152ecb1..1bdf72f 100644
--- a/core/java/com/trustedlogic/trustednfc/android/LlcpServiceSocket.java
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpServiceSocket.java
@@ -24,7 +24,9 @@
import java.io.IOException;
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+import android.nfc.ErrorCodes;
+import android.nfc.ILlcpSocket;
+import android.nfc.ILlcpServiceSocket;
import android.os.RemoteException;
import android.util.Log;
@@ -32,7 +34,7 @@
/**
* LlcpServiceSocket represents a LLCP Service to be used in a
* Connection-oriented communication
- *
+ *
* @since AA02.01
* @hide
*/
@@ -43,19 +45,19 @@
/**
* The handle returned by the NFC service and used to identify the LLCP
* Service socket in every call of this class.
- *
+ *
* @hide
*/
protected int mHandle;
/**
* The entry point for LLCP Service socket operations.
- *
+ *
* @hide
*/
protected ILlcpServiceSocket mService;
-
- private ILlcpSocket mLlcpSocketService;
+
+ private final ILlcpSocket mLlcpSocketService;
static LlcpException convertErrorToLlcpException(int errorCode) {
return convertErrorToLlcpException(errorCode, null);
@@ -83,7 +85,7 @@
/**
* Internal constructor for the LlcpServiceSocket class.
- *
+ *
* @param service
* The entry point to the Nfc Service for LlcpServiceSocket
* class.
@@ -101,14 +103,14 @@
/**
* Wait for incomming connection request from a LLCP client and accept this
* request
- *
+ *
* @return socket object to be used to communicate with a LLCP client
- *
+ *
* @throws IOException
* if the llcp link is lost or deactivated
* @throws LlcpException
* if not enough ressources are available
- *
+ *
* @see LlcpSocket
* @since AA02.01
*/
@@ -124,7 +126,7 @@
throw convertErrorToLlcpException(handle);
}
}
-
+
// Build the public LlcpSocket object
return new LlcpSocket(mLlcpSocketService, handle);
} catch (RemoteException e) {
@@ -136,7 +138,7 @@
/**
* Set the timeout for the accept request
- *
+ *
* @param timeout
* value of the timeout for the accept request
* @since AA02.01
@@ -151,7 +153,7 @@
/**
* Get the timeout value of the accept request
- *
+ *
* @return mTimeout
* @since AA02.01
*/
@@ -166,7 +168,7 @@
/**
* Close the created Llcp Service socket
- *
+ *
* @since AA02.01
*/
public void close() {
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpSocket.java b/core/java/com/trustedlogic/trustednfc/android/LlcpSocket.java
index e47160c..ebde3e1 100644
--- a/core/java/com/trustedlogic/trustednfc/android/LlcpSocket.java
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpSocket.java
@@ -24,7 +24,8 @@
import java.io.IOException;
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+import android.nfc.ErrorCodes;
+import android.nfc.ILlcpSocket;
import android.os.RemoteException;
import android.util.Log;
@@ -32,7 +33,7 @@
/**
* LlcpClientSocket represents a LLCP Connection-Oriented client to be used in a
* connection-oriented communication
- *
+ *
* @since AA02.01
* @hide
*/
@@ -43,14 +44,14 @@
/**
* The handle returned by the NFC service and used to identify the LLCP
* socket in every call of this class.
- *
+ *
* @hide
*/
protected int mHandle;
/**
* The entry point for LLCP socket operations.
- *
+ *
* @hide
*/
protected ILlcpSocket mService;
@@ -84,7 +85,7 @@
/**
* Internal constructor for the LlcpSocket class.
- *
+ *
* @param service
* The entry point to the Nfc Service for LlcpServiceSocket
* class.
@@ -100,7 +101,7 @@
/**
* Connect request to a specific LLCP Service by its SAP.
- *
+ *
* @param sap
* Service Access Point number of the LLCP Service
* @throws IOException
@@ -128,7 +129,7 @@
/**
* Connect request to a specific LLCP Service by its Service Name.
- *
+ *
* @param sn
* Service Name of the LLCP Service
* @throws IOException
@@ -156,7 +157,7 @@
/**
* Set the timeout for the connect request
- *
+ *
* @param timeout
* timeout value for the connect request
* @since AA02.01
@@ -171,7 +172,7 @@
/**
* Get the timeout value of the connect request
- *
+ *
* @return mTimeout
* @since AA02.01
*/
@@ -187,7 +188,7 @@
/**
* Disconnect request to the connected LLCP socket and close the created
* socket.
- *
+ *
* @throws IOException
* if the LLCP has been lost or deactivated.
* @since AA02.01
@@ -206,7 +207,7 @@
/**
* Send data to the connected LLCP Socket.
- *
+ *
* @throws IOException
* if the LLCP has been lost or deactivated.
* @since AA02.01
@@ -220,12 +221,12 @@
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in send(): ", e);
- }
+ }
}
/**
* Receive data from the connected LLCP socket
- *
+ *
* @param receiveBuffer
* a buffer for the received data
* @return length length of the data received
@@ -242,14 +243,14 @@
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in send(): ", e);
- }
-
+ }
+
return receivedLength;
}
-
+
/**
* Returns the local Service Access Point number of the socket
- *
+ *
* @return localSap
* @since AA02.01
*/
@@ -264,7 +265,7 @@
/**
* Returns the local Maximum Information Unit(MIU) of the socket
- *
+ *
* @return miu
* @since AA02.01
*/
@@ -279,7 +280,7 @@
/**
* Returns the local Receive Window(RW) of the socket
- *
+ *
* @return rw
* @since AA02.01
*/
@@ -296,7 +297,7 @@
* Returns the remote Maximum Information Unit(MIU) of the socket.
* <p>
* This method must be called when the socket is in CONNECTED_STATE
- *
+ *
* @return remoteMiu
* @throws LlcpException
* if the LlcpClientSocket is not in a CONNECTED_STATE
@@ -320,7 +321,7 @@
* Returns the remote Receive Window(RW) of the connected remote socket.
* <p>
* This method must be called when the socket is in CONNECTED_STATE
- *
+ *
* @return rw
* @throws LlcpException
* if the LlcpClientSocket is not in a CONNECTED_STATE
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.java b/core/java/com/trustedlogic/trustednfc/android/NdefMessage.java
deleted file mode 100644
index f03b604..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.java
+++ /dev/null
@@ -1,160 +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.
- */
-
-/**
- * File : NDEFMessage.java
- * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
- * Created : 05-10-2009
- */
-
-package com.trustedlogic.trustednfc.android;
-
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents an NDEF message as specified by the <a
- * href="http://www.nfc-forum.org/">NFC Forum</a>.
- *
- * @see NdefRecord
- *
- * @since AA01.04
- * @hide
- */
-public class NdefMessage implements Parcelable {
- /* Flag values */
- private static final int FLAG_MB = 0x80;
- private static final int FLAG_ME = 0x40;
- private static final int FLAG_CF = 0x20;
- private static final int FLAG_SR = 0x10;
- private static final int FLAG_IL = 0x08;
-
- /**
- * Array of {@link NdefRecord} composing this message.
- */
- private NdefRecord[] mRecords;
-
- /**
- * Builds an NDEF message.
- *
- * @param data raw NDEF message data
- *
- * @throws NFCException
- */
- public NdefMessage(byte[] data) throws NfcException {
- if (parseNdefMessage(data) == -1)
- throw new NfcException("Error while parsing NDEF message");
- }
-
- /**
- * Builds an NDEF message.
- *
- * @param records
- * an array of already created NDEF records
- */
- public NdefMessage(NdefRecord[] records) {
- mRecords = new NdefRecord[records.length];
-
- System.arraycopy(records, 0, mRecords, 0, records.length);
- }
-
- /**
- * Returns the NDEF message as a byte array.
- *
- * @return the message as a byte array
- */
- public byte[] toByteArray() {
- if ((mRecords == null) || (mRecords.length == 0))
- return null;
-
- byte[] msg = {};
-
- for (int i = 0; i < mRecords.length; i++) {
- byte[] record = mRecords[i].toByteArray();
- byte[] tmp = new byte[msg.length + record.length];
-
- /* Make sure the Message Begin flag is set only for the first record */
- if (i == 0)
- record[0] |= FLAG_MB;
- else
- record[0] &= ~FLAG_MB;
-
- /* Make sure the Message End flag is set only for the last record */
- if (i == (mRecords.length - 1))
- record[0] |= FLAG_ME;
- else
- record[0] &= ~FLAG_ME;
-
- System.arraycopy(msg, 0, tmp, 0, msg.length);
- System.arraycopy(record, 0, tmp, msg.length, record.length);
-
- msg = tmp;
- }
-
- return msg;
- }
-
- /**
- * Returns an array of {@link NdefRecord} composing this message.
- *
- * @return mRecords
- *
- * @since AA02.01
- */
- public NdefRecord[] getRecords(){
- return mRecords;
- }
-
- private native int parseNdefMessage(byte[] data);
-
- /**
- * (Parcelable) Describe the parcel
- * {@hide}
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * (Parcelable) Convert current object to a Parcel
- * {@hide}
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mRecords.length);
- dest.writeTypedArray(mRecords, 0);
- }
-
- /**
- * Creator class, needed when implementing from Parcelable
- * {@hide}
- */
- public static final Parcelable.Creator<NdefMessage> CREATOR = new Parcelable.Creator<NdefMessage>() {
- public NdefMessage createFromParcel(Parcel in) {
- int recordsLength = in.readInt();
- NdefRecord[] records = new NdefRecord[recordsLength];
- in.readTypedArray(records, NdefRecord.CREATOR);
- return new NdefMessage(records);
- }
-
- public NdefMessage[] newArray(int size) {
- return new NdefMessage[size];
- }
- };
-
-}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefRecord.java b/core/java/com/trustedlogic/trustednfc/android/NdefRecord.java
deleted file mode 100644
index a0257fe..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/NdefRecord.java
+++ /dev/null
@@ -1,293 +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.
- */
-
-/**
- * File : NdefRecord.java
- * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
- * Created : 05-10-2009
- */
-
-package com.trustedlogic.trustednfc.android;
-
-import android.location.Location;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * An NDEF record as specified by the <a href="http://www.nfc-forum.org/">NFC
- * Forum</a>.
- *
- * @see NdefMessage
- *
- * @since AA01.04
- * @hide
- */
-public class NdefRecord implements Parcelable {
-
- /**
- * Type Name Format - Empty record
- */
- public static final short TNF_EMPTY = 0x0;
-
- /**
- * Type Name Format - NFC Forum-defined type
- */
- public static final short TNF_WELL_KNOWN_TYPE = 0x1;
-
- /**
- * Type Name Format - RFC2045 MIME type
- */
- public static final short TNF_MIME_MEDIA_TYPE = 0x2;
-
- /**
- * Type Name Format - Absolute URI
- */
- public static final short TNF_ABSOLUTE_URI = 0x3;
-
- /**
- * Type Name Format - User-defined type
- */
- public static final short TNF_EXTERNAL_TYPE = 0x4;
-
- /**
- * Type Name Format - Unknown type
- */
- public static final short TNF_UNKNOWN = 0x5;
-
- /**
- * Type Name Format - Unchanged. This TNF is used for chunked records, so
- * that middle records inherits from the first record's type.
- */
- public static final short TNF_UNCHANGED = 0x6;
-
- /**
- * NFC Forum-defined Type - Smart Poster
- */
- public static final byte[] TYPE_SMART_POSTER = { 0x53, 0x70 };
-
- /**
- * NFC Forum-defined Type - Text
- */
- public static final byte[] TYPE_TEXT = { 0x54 };
-
- /**
- * NFC Forum-defined Type - URI
- */
- public static final byte[] TYPE_URI = { 0x55 };
-
- /**
- * NFC Forum-defined Global Type - Connection Handover Request
- */
- public static final byte[] TYPE_HANDOVER_REQUEST = { 0x48, 0x72 };
-
- /**
- * NFC Forum-defined Global Type - Connection Handover Select
- */
- public static final byte[] TYPE_HANDOVER_SELECT = { 0x48, 0x73 };
-
- /**
- * NFC Forum-defined Global Type - Connection Handover Carrier
- */
- public static final byte[] TYPE_HANDOVER_CARRIER = { 0x48, 0x63 };
-
- /**
- * NFC Forum-defined Local Type - Alternative Carrier
- */
- public static final byte[] TYPE_ALTERNATIVE_CARRIER = { 0x61, 0x63 };
-
- /* Flag values */
- private static final int FLAG_MB = 0x80;
- private static final int FLAG_ME = 0x40;
- private static final int FLAG_CF = 0x20;
- private static final int FLAG_SR = 0x10;
- private static final int FLAG_IL = 0x08;
-
- /**
- * Record Flags
- */
- private short mFlags = 0;
-
- /**
- * Record Type Name Format
- */
- private short mTnf = 0;
-
- /**
- * Record Type
- */
- private byte[] mType = null;
-
- /**
- * Record Identifier
- */
- private byte[] mId = null;
-
- /**
- * Record Payload
- */
- private byte[] mPayload = null;
-
- /**
- * Creates an NdefRecord given its Type Name Format, its type, its id and
- * its.
- *
- * @param tnf
- * Type Name Format
- * @param type
- * record type
- * @param id
- * record id (optional, can be null)
- * @param data
- * record payload
- */
- public NdefRecord(short tnf, byte[] type, byte[] id, byte[] data) {
-
- /* generate flag */
- mFlags = FLAG_MB | FLAG_ME;
-
- /* Determine if it is a short record */
- if(data.length < 0xFF)
- {
- mFlags |= FLAG_SR;
- }
-
- /* Determine if an id is present */
- if(id.length != 0)
- {
- mFlags |= FLAG_IL;
- }
-
- mTnf = tnf;
- mType = (byte[]) type.clone();
- mId = (byte[]) id.clone();
- mPayload = (byte[]) data.clone();
- }
-
- /**
- * Appends data to the record's payload.
- *
- * @param data
- * Data to be added to the record.
- */
- public void appendPayload(byte[] data) {
- byte[] newPayload = new byte[mPayload.length + data.length];
-
- System.arraycopy(mPayload, 0, newPayload, 0, mPayload.length);
- System.arraycopy(data, 0, newPayload, mPayload.length, data.length);
-
- mPayload = newPayload;
- }
-
- /**
- * Returns record as a byte array.
- *
- * @return record as a byte array.
- */
- public byte[] toByteArray() {
- return generate(mFlags, mTnf, mType, mId, mPayload);
- }
-
- private native byte[] generate(short flags, short tnf, byte[] type,
- byte[] id, byte[] data);
-
- /**
- * (Parcelable) Describe the parcel
- * {@hide}
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * (Parcelable) Convert current object to a Parcel
- * {@hide}
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mTnf);
- dest.writeInt(mType.length);
- dest.writeByteArray(mType);
- dest.writeInt(mId.length);
- dest.writeByteArray(mId);
- dest.writeInt(mPayload.length);
- dest.writeByteArray(mPayload);
- }
-
- /**
- * Creator class, needed when implementing from Parcelable
- * {@hide}
- */
- public static final Parcelable.Creator<NdefRecord> CREATOR = new Parcelable.Creator<NdefRecord>() {
- public NdefRecord createFromParcel(Parcel in) {
- // TNF
- short tnf = (short)in.readInt();
- // Type
- int typeLength = in.readInt();
- byte[] type = new byte[typeLength];
- in.readByteArray(type);
- // ID
- int idLength = in.readInt();
- byte[] id = new byte[idLength];
- in.readByteArray(id);
- // Payload
- int payloadLength = in.readInt();
- byte[] payload = new byte[payloadLength];
- in.readByteArray(payload);
-
- return new NdefRecord(tnf, type, id, payload);
- }
-
- public NdefRecord[] newArray(int size) {
- return new NdefRecord[size];
- }
- };
-
- /**
- * Returns record TNF
- *
- * @return mTnf
- */
- public int getTnf(){
- return mTnf;
- }
-
- /**
- * Returns record TYPE
- *
- * @return mType
- */
- public byte[] getType(){
- return mType;
- }
-
- /**
- * Returns record ID
- *
- * @return mId
- */
- public byte[] getId(){
- return mId;
- }
-
- /**
- * Returns record Payload
- *
- * @return mPayload
- */
- public byte[] getPayload(){
- return mPayload;
- }
-
-}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefTag.java b/core/java/com/trustedlogic/trustednfc/android/NdefTag.java
deleted file mode 100644
index 1d99241..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/NdefTag.java
+++ /dev/null
@@ -1,126 +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.
- */
-
-/**
- * File : NDEFTag.java
- * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
- * Created : 04-12-2009
- */
-
-package com.trustedlogic.trustednfc.android;
-
-import java.io.IOException;
-
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * NdefTag represents tags complying with the NFC Forum's NFC Data Exchange
- * Format.
- *
- * @since AA01.04
- * @hide
- */
-public class NdefTag extends NfcTag {
-
- private static final String TAG = "NdefTag";
-
-
- public NdefTag(NfcTag tag){
- super(tag.mService,tag.mHandle);
- this.isConnected = tag.isConnected;
- this.isClosed = tag.isClosed;
- tag.isClosed = false;
- }
-
- /**
- * Internal constructor for the NfcNdefTag class.
- *
- * @param service The entry point to the Nfc Service for NfcNdefTag class.
- * @param handle The handle returned by the NFC service and used to identify
- * the tag in subsequent calls.
- * @hide
- */
- NdefTag(INfcTag service, int handle) {
- super(service, handle);
- }
-
- /**
- * Read NDEF data from an NDEF tag.
- *
- * @return the NDEF message read from the tag.
- * @throws NfcException if the tag is not NDEF-formatted.
- * @throws IOException if the target has been lost or the connection has
- * been closed.
- * @see NdefMessage
- */
- public NdefMessage read() throws NfcException, IOException {
- // Check state
- checkState();
-
- //Check if the tag is Ndef compliant
- if(isNdef != true){
- isNdef = isNdef();
- if(isNdef != true) {
- throw new NfcException("Tag is not NDEF compliant");
- }
- }
-
- // Perform transceive
- try {
- NdefMessage msg = mService.read(mHandle);
- if (msg == null) {
- throw new IOException("NDEF read failed");
- }
- return msg;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in read(): ", e);
- return null;
- }
- }
-
- /**
- * Write NDEF data to an NDEF-compliant tag.
- *
- * @param msg NDEF message to be written to the tag.
- * @throws NfcException if the tag is not NDEF formatted.
- * @throws IOException if the target has been lost or the connection has
- * been closed.
- * @see NdefMessage
- */
- public void write(NdefMessage msg) throws NfcException, IOException {
- // Check state
- checkState();
-
- //Check if the tag is Ndef compliant
- if(isNdef != true){
- isNdef = isNdef();
- if(isNdef != true) {
- throw new NfcException("Tag is not NDEF compliant");
- }
- }
-
- // Perform transceive
- try {
- boolean isSuccess = mService.write(mHandle, msg);
- if (!isSuccess) {
- throw new IOException("NDEF write failed");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in write(): ", e);
- }
- }
-}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NfcManager.java b/core/java/com/trustedlogic/trustednfc/android/NfcManager.java
deleted file mode 100644
index 98ab5bf..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/NfcManager.java
+++ /dev/null
@@ -1,656 +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.
- */
-
-/**
- * File : NfcManager.java
- * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
- * Created : 26-08-2009
- */
-
-package com.trustedlogic.trustednfc.android;
-
-import java.io.IOException;
-
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.media.MiniThumbFile;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.util.Log;
-
-//import android.util.Log;
-
-/**
- * This class provides the primary API for managing all aspects of NFC. Get an
- * instance of this class by calling
- * Context.getSystemService(Context.NFC_SERVICE).
- * @hide
- */
-public final class NfcManager {
- /**
- * Tag Reader Discovery mode
- */
- private static final int DISCOVERY_MODE_TAG_READER = 0;
-
- /**
- * NFC-IP1 Peer-to-Peer mode Enables the manager to act as a peer in an
- * NFC-IP1 communication. Implementations should not assume that the
- * controller will end up behaving as an NFC-IP1 target or initiator and
- * should handle both cases, depending on the type of the remote peer type.
- */
- private static final int DISCOVERY_MODE_NFCIP1 = 1;
-
- /**
- * Card Emulation mode Enables the manager to act as an NFC tag. Provided
- * that a Secure Element (an UICC for instance) is connected to the NFC
- * controller through its SWP interface, it can be exposed to the outside
- * NFC world and be addressed by external readers the same way they would
- * with a tag.
- * <p>
- * Which Secure Element is exposed is implementation-dependent.
- *
- * @since AA01.04
- */
- private static final int DISCOVERY_MODE_CARD_EMULATION = 2;
-
- /**
- * Used as Parcelable extra field in
- * {@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_TAG_DISCOVERED_ACTION}
- * . It contains the NDEF message read from the NDEF tag discovered.
- */
- public static final String NDEF_MESSAGE_EXTRA = "com.trustedlogic.trustednfc.android.extra.NDEF_MESSAGE";
-
- /**
- * Broadcast Action: a NDEF tag has been discovered.
- * <p>
- * Always contains the extra field
- * {@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_MESSAGE_EXTRA}.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_NOTIFY permission.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String NDEF_TAG_DISCOVERED_ACTION = "com.trustedlogic.trustednfc.android.action.NDEF_TAG_DISCOVERED";
-
- /**
- * Used as byte array extra field in
- * {@link com.trustedlogic.trustednfc.android.NfcManager#TRANSACTION_DETECTED_ACTION}
- * . It contains the AID of the applet concerned by the transaction.
- */
- public static final String AID_EXTRA = "com.trustedlogic.trustednfc.android.extra.AID";
-
- /**
- * Broadcast Action: a transaction with a secure element has been detected.
- * <p>
- * Always contains the extra field
- * {@link com.trustedlogic.trustednfc.android.NfcManager#AID_EXTRA}
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_NOTIFY permission
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String TRANSACTION_DETECTED_ACTION = "com.trustedlogic.trustednfc.android.action.TRANSACTION_DETECTED";
-
- /**
- * LLCP link status: The LLCP link is activated.
- *
- * @since AA02.01
- */
- public static final int LLCP_LINK_STATE_ACTIVATED = 0;
-
- /**
- * LLCP link status: The LLCP link is deactivated.
- *
- * @since AA02.01
- */
- public static final int LLCP_LINK_STATE_DEACTIVATED = 1;
-
- /**
- * Used as int extra field in
- * {@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_ACTION}
- * . It contains the new state of the LLCP link.
- */
- public static final String LLCP_LINK_STATE_CHANGED_EXTRA = "com.trustedlogic.trustednfc.android.extra.LLCP_LINK_STATE";
-
- /**
- * Broadcast Action: the LLCP link state changed.
- * <p>
- * Always contains the extra field
- * {@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_EXTRA}.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_LLCP permission.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String LLCP_LINK_STATE_CHANGED_ACTION = "com.trustedlogic.trustednfc.android.action.LLCP_LINK_STATE_CHANGED";
-
- private static final String TAG = "NfcManager";
-
- private Handler mHandler;
-
- private INfcManager mService;
-
- private INfcTag mNfcTagService;
-
- private IP2pTarget mP2pTargetService;
-
- private IP2pInitiator mP2pInitiatorService;
-
- private ILlcpSocket mLlcpSocketService;
-
- private ILlcpConnectionlessSocket mLlcpConnectionlessSocketService;
-
- private ILlcpServiceSocket mLlcpServiceSocketService;
-
- static NfcException convertErrorToNfcException(int errorCode) {
- return convertErrorToNfcException(errorCode, null);
- }
-
- static NfcException convertErrorToNfcException(int errorCode, String message) {
- if (message == null) {
- message = "";
- } else {
- message = " (" + message + ")";
- }
-
- switch (errorCode) {
- case ErrorCodes.ERROR_BUSY:
- return new NfcException("Another operation is already pending" + message);
- case ErrorCodes.ERROR_CANCELLED:
- return new NfcException("Operation cancelled" + message);
- case ErrorCodes.ERROR_TIMEOUT:
- return new NfcException("Operation timed out" + message);
- case ErrorCodes.ERROR_SOCKET_CREATION:
- return new NfcException("Error during the creation of an Llcp socket:" + message);
- case ErrorCodes.ERROR_SAP_USED:
- return new NfcException("Error SAP already used:" + message);
- case ErrorCodes.ERROR_SERVICE_NAME_USED:
- return new NfcException("Error Service Name already used:" + message);
- case ErrorCodes.ERROR_SOCKET_OPTIONS:
- return new NfcException("Error Socket options:" + message);
- case ErrorCodes.ERROR_INVALID_PARAM:
- return new NfcException("Error Set Properties: invalid param" + message);
- case ErrorCodes.ERROR_NFC_ON:
- return new NfcException("Error Set Properties : NFC is ON" + message);
- case ErrorCodes.ERROR_NOT_INITIALIZED:
- return new NfcException("NFC is not running " + message);
- case ErrorCodes.ERROR_SE_ALREADY_SELECTED:
- return new NfcException("Secure Element already connected" + message);
- case ErrorCodes.ERROR_NO_SE_CONNECTED:
- return new NfcException("No Secure Element connected" + message);
- case ErrorCodes.ERROR_SE_CONNECTED:
- return new NfcException("A secure Element is already connected" + message);
- default:
- return new NfcException("Unkown error code " + errorCode + message);
- }
- }
-
- /**
- * @hide
- */
- public NfcManager(INfcManager service, Handler handler) {
- mService = service;
- mHandler = handler;
- try {
- mNfcTagService = mService.getNfcTagInterface();
- mP2pInitiatorService = mService.getP2pInitiatorInterface();
- mP2pTargetService = mService.getP2pTargetInterface();
- mLlcpServiceSocketService = mService.getLlcpServiceInterface();
- mLlcpConnectionlessSocketService = mService.getLlcpConnectionlessInterface();
- mLlcpSocketService = mService.getLlcpInterface();
- } catch (RemoteException e) {
- mLlcpSocketService = null;
- mNfcTagService = null;
- mP2pInitiatorService = null;
- mP2pTargetService = null;
- mLlcpConnectionlessSocketService = null;
- mLlcpServiceSocketService = null;
- }
- }
-
- /**
- * Return the status of the NFC feature
- *
- * @return mIsNfcEnabled
- * @since AA02.01
- */
- public boolean isEnabled() {
- try {
- return mService.isEnabled();
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in isEnabled(): ", e);
- return false;
- }
- }
-
- /**
- * Enable the NFC Feature
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_ADMIN permission
- *
- * @throws NfcException if the enable failed
- * @since AA02.01
- */
- public void enable() throws NfcException {
- try {
- boolean isSuccess = mService.enable();
- if (isSuccess == false) {
- throw new NfcException("NFC Service failed to enable");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in enable(): ", e);
- }
- }
-
- /**
- * Disable the NFC feature
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_ADMIN permission
- *
- * @throws NfcException if the disable failed
- * @since AA02.01
- */
- public void disable() throws NfcException {
- try {
- boolean isSuccess = mService.disable();
- if (isSuccess == false) {
- throw new NfcException("NFC Service failed to disable");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in disable(): ", e);
- }
- }
-
- /**
- * Get the list of the identifiers of the Secure Elements detected
- * by the NFC controller.
- *
- * @return list a list of Secure Element identifiers.
- * @see #getSelectedSecureElement
- * @see #selectSecureElement(int)
- * @see #deselectSecureElement
- * @since AA02.01
- */
- public int[] getSecureElementList() {
- try {
- return mService.getSecureElementList();
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getSecureElementList(): ", e);
- return null;
- }
- }
-
- /**
- * Get the identifier of the currently selected secure element.
- *
- * @return id identifier of the currently selected Secure Element. 0 if none.
- * @see #getSecureElementList
- * @see #selectSecureElement(int)
- * @see #deselectSecureElement
- * @since AA02.01
- */
- public int getSelectedSecureElement() {
- try {
- return mService.getSelectedSecureElement();
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getSelectedSecureElement(): ", e);
- return -1;
- }
- }
-
- /**
- * Select a specific Secure Element by its identifier.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_ADMIN permission
- *
- * @throws NfcException if a or this secure element is already selected
- * @see #getSecureElementList
- * @see #getSelectedSecureElement
- * @see #deselectSecureElement
- * @since AA02.01
- */
- public void selectSecureElement(int seId) throws NfcException {
- try {
- int status = mService.selectSecureElement(seId);
- if(status != ErrorCodes.SUCCESS){
- throw convertErrorToNfcException(status);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in selectSecureElement(): ", e);
- }
- }
-
- /**
- * Deselect the currently selected Secure Element
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_ADMIN permission
- *
- * @throws NfcException if no secure Element is selected
- * @see #getSecureElementList
- * @see #getSelectedSecureElement
- * @see #selectSecureElement(int)
- * @since AA02.01
- */
- public void deselectSecureElement() throws NfcException {
- try {
- int status = mService.deselectSecureElement();
- if(status != ErrorCodes.SUCCESS){
- throw convertErrorToNfcException(status);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in deselectSecureElement(): ", e);
- }
- }
-
- /**
- * Open a connection with a remote NFC peer
- *
- * This method does not return while no remote NFC peer enters the field.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_RAW permission
- *
- * @return P2pDevice object to be used to communicate with the detected
- * peer.
- * @throws IOException if the target has been lost or the connection has
- * been closed.
- * @throws NfcException if an open is already started
- * @see P2pDevice
- * @see #getOpenTimeout
- * @see #setOpenTimeout(int)
- * @see #cancel
- * @since AA02.01
- */
- public P2pDevice openP2pConnection() throws IOException, NfcException {
- try {
- int handle = mService.openP2pConnection();
- // Handle potential errors
- if (ErrorCodes.isError(handle)) {
- if (handle == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToNfcException(handle);
- }
- }
- // Build the public NfcTag object, depending on its type
- if (mP2pTargetService.getMode(handle) == P2pDevice.MODE_P2P_TARGET) {
- return new P2pTarget(mP2pTargetService, handle);
- } else {
- return new P2pInitiator(mP2pInitiatorService, handle);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in openTagConnection(): ", e);
- return null;
- }
- }
-
- /**
- * Open a connection with a tag
- *
- * This method does not return while no tag enters the field.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_RAW permission
- *
- * @return tag object to be use to communicate with the detected NfcTag.
- * @throws IOException if the target has been lost or the connection has
- * been closed.
- * @throws NfcException if an open is already started
- * @see NfcTag
- * @see #getOpenTimeout
- * @see #setOpenTimeout(int)
- * @see #cancel
- * @since AA02.01
- */
- public NfcTag openTagConnection() throws IOException, NfcException {
- try {
- int handle = mService.openTagConnection();
- // Handle potential errors
- if (ErrorCodes.isError(handle)) {
- if (handle == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToNfcException(handle);
- }
- }
- // Build the public NfcTag object
- return new NfcTag(mNfcTagService, handle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in openTagConnection(): ", e);
- return null;
- }
- }
-
- /**
- * Set the timeout for open requests
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_RAW permission
- *
- * @param timeout value of the timeout for open request
- * @see #openP2pConnection
- * @see #openTagConnection
- * @see #getOpenTimeout
- * @since AA02.01
- */
- public void setOpenTimeout(int timeout) {
- try {
- mService.setOpenTimeout(timeout);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in setOpenTimeout(): ", e);
- }
- }
-
- /**
- * Get the timeout value of open requests
- *
- * @return mTimeout
- * @see #setOpenTimeout(int)
- * @since AA02.01
- */
- public int getOpenTimeout() {
- try {
- return mService.getOpenTimeout();
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getOpenTimeout(): ", e);
- return 0;
- }
- }
-
- /**
- * Cancel an openTagConnection or an openP2pConnection started
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_RAW permission
- *
- * @see #openP2pConnection
- * @see #openTagConnection
- * @since AA02.01
- */
- public void cancel() {
- try {
- mService.cancel();
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in cancel(): ", e);
- }
- }
-
- /**
- * Creates a connectionless socket for a LLCP link and set its Service
- * Access Point number (SAP)
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_LLCP permission
- *
- * @param sap Service Access Point number related to the created
- * Connectionless socket.
- * @return LlcpConnectionlessSocket object to be used in a LLCP
- * Connectionless communication.
- * @throws IOException if the socket creation failed
- * @throws NfcException if socket ressources are insufficicent
- * @see LlcpConnectionlessSocket
- * @since AA02.01
- */
- public LlcpConnectionlessSocket createLlcpConnectionlessSocket(int sap) throws IOException,
- NfcException {
-
- try {
- int handle = mService.createLlcpConnectionlessSocket(sap);
- // Handle potential errors
- if (ErrorCodes.isError(handle)) {
- if (handle == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToNfcException(handle);
- }
- }
-
- // Build the public LlcpConnectionLess object
- return new LlcpConnectionlessSocket(mLlcpConnectionlessSocketService, handle);
-
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in createLlcpConnectionlessSocket(): ", e);
- return null;
- }
- }
-
- /**
- * Creates a LlcpServiceSocket for a LLCP link, set its Service Access Point
- * number (SAP).
- * <p>
- * During a LLCP communication, the LlcpServiceSocket will create LlcpSocket
- * to communicate with incoming LLCP clients. For that, a server socket need
- * to have some informations as a working buffer length in order to handle
- * incoming data and some options to define the LLCP communication.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_LLCP permission
- *
- * @param sap
- * @param sn Service Name of the LlcpServiceSocket
- * @param miu Maximum Information Unit (MIU) for a LlcpSocket created by the
- * LlcpServiceSocket
- * @param rw Receive Window (RW) for a LlcpSocket created by the
- * LlcpServiceSocket
- * @param linearBufferLength size of the memory space needed to handle
- * incoming data for every LlcpSocket created.
- * @return LlcpServiceSocket object to be used as a LLCP Service in a
- * connection oriented communication.
- * @throws IOException if the socket creation failed
- * @throws NfcException if socket ressources are insufficicent
- * @see LlcpServiceSocket
- * @since AA02.01
- */
- public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw,
- int linearBufferLength) throws IOException, NfcException {
- try {
- int handle = mService.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
- // Handle potential errors
- if (ErrorCodes.isError(handle)) {
- if (handle == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToNfcException(handle);
- }
- }
-
- // Build the public LlcpServiceSocket object
- return new LlcpServiceSocket(mLlcpServiceSocketService, mLlcpSocketService, handle);
-
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in createLlcpServiceSocket(): ", e);
- return null;
- }
- }
-
- /**
- * Creates a LlcpSocket for a LLCP link with a specific Service Access Point
- * number (SAP)
- * <p>
- * A LlcpSocket need to have a linear buffer in order to handle incoming
- * data. This linear buffer will be used to store incoming data as a stream.
- * Data will be readable later.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_LLCP permission
- *
- * @param sap Service Access Point number for the created socket
- * @param miu Maximum Information Unit (MIU) of the communication socket
- * @param rw Receive Window (RW) of the communication socket
- * @param linearBufferLength size of the memory space needed to handle
- * incoming data with this socket
- * @throws IOException if the socket creation failed
- * @throws NfcException if socket ressources are insufficicent
- * @see LlcpSocket
- * @since AA02.01
- */
- public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
- throws IOException, NfcException {
- try {
- int handle = mService.createLlcpSocket(sap, miu, rw, linearBufferLength);
- // Handle potential errors
- if (ErrorCodes.isError(handle)) {
- if (handle == ErrorCodes.ERROR_IO) {
- throw new IOException();
- } else {
- throw convertErrorToNfcException(handle);
- }
- }
- // Build the public LlcpSocket object
- return new LlcpSocket(mLlcpSocketService, handle);
-
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in createLlcpSocket(): ", e);
- return null;
- }
- }
-
- /**
- * Set different parameters like the NCIP General bytes, the LLCP link
- * parameters and all tag discovery parameters.
- * <p class="note">
- * <strong>Note:</strong> Requires the NFC_ADMIN permission
- *
- * @param param parameter to be updated with a new value
- * @param value new value of the parameter
- * @throws NfcException if incorrect parameters of NFC is ON
- * @since AA02.01
- */
- public void setProperties(String param, String value) throws NfcException {
- try {
- int result = mService.setProperties(param, value);
- // Handle potential errors
- if (ErrorCodes.isError(result)) {
- throw convertErrorToNfcException(result);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in setProperties(): ", e);
- }
- }
-
- /**
- * Get the value of different parameters like the NCFIP General bytes, the
- * LLCP link parameters and all tag discovery parameters.
- *
- * @param param parameter to be updated
- * @return String value of the requested parameter
- * @throws RemoteException
- * @since AA02.01
- */
- public String getProperties(String param) {
- String value;
- try {
- value = mService.getProperties(param);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getProperties(): ", e);
- return null;
- }
- return value;
- }
-
-}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NfcTag.java b/core/java/com/trustedlogic/trustednfc/android/NfcTag.java
deleted file mode 100644
index 798c7e4..0000000
--- a/core/java/com/trustedlogic/trustednfc/android/NfcTag.java
+++ /dev/null
@@ -1,250 +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.
- */
-
-/**
- * File : NFCTag.java
- * Original-Author : Trusted Logic S.A. (Daniel Tomas)
- * Created : 26-02-2010
- */
-
-package com.trustedlogic.trustednfc.android;
-
-import java.io.IOException;
-
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
-
-/**
- * This class represents tags with no known formatting. One can use the method
- * {@link #isNdef()} to determine if the tag can store NDEF-formatted messages.
- * <p>
- *
- * <pre class="prettyprint">
- * if (tag.isNdef()) {
- * NdefTag ndefTag = (NdefTag) tag;
- * NdefMessage msg = ndefTag.read();
- * }
- * </pre>
- *
- * @since AA01.04
- * @see NdefMessage
- * @hide
- */
-public class NfcTag {
-
- private static final String TAG = "NfcTag";
-
- /**
- * The handle returned by the NFC service and used to identify the tag in
- * every call of this class.
- *
- * @hide
- */
- protected int mHandle;
-
- /**
- * The entry point for tag operations.
- *
- * @hide
- */
- protected INfcTag mService;
-
- /**
- * Flag set when the object is closed and thus not usable any more.
- *
- * @hide
- */
- protected boolean isClosed = false;
-
- /**
- * Flag set when the tag is connected.
- *
- * @hide
- */
- protected boolean isConnected = false;
-
- /**
- * Flag set when a check NDEF is performed.
- *
- * @hide
- */
- protected boolean isNdef = false;
-
- /**
- * Check if tag is still opened.
- *
- * @return data sent by the P2pInitiator.
- * @throws NfcException if accessing a closed target.
- *
- * @hide
- */
- public void checkState() throws NfcException {
- if (isClosed) {
- throw new NfcException("Tag has been closed.");
- }
- if (!isConnected) {
- throw new NfcException("Tag is not connected.");
- }
- }
-
- /**
- * Internal constructor for the NfcTag class.
- *
- * @param service The entry point to the Nfc Service for NfcTag class.
- * @param handle The handle returned by the NFC service and used to identify
- * the tag in subsequent calls.
- * @hide
- */
- NfcTag(INfcTag service, int handle) {
- this.mService = service;
- this.mHandle = handle;
- }
-
- /**
- * Connects to the tag. This shall be called prior to any other operation on
- * the tag.
- *
- * @throws IOException if the tag has been lost or the connection has been
- * closed.
- * @throws nfcException if the tag is already in connected state.
- */
- public void connect() throws NfcException, IOException {
- // Check state
- if (isClosed) {
- throw new NfcException("Tag has been closed.");
- }
- if (isConnected) {
- throw new NfcException("Already connected");
- }
-
- // Perform connect
- try {
- int result = mService.connect(mHandle);
- if (ErrorCodes.isError(result)) {
- if (result == ErrorCodes.ERROR_IO) {
- throw new IOException("Failed to connect");
- }
- else {
- throw NfcManager.convertErrorToNfcException(result);
- }
- }
- isConnected = true;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in connect(): ", e);
- }
- }
-
- /**
- * Disconnects from the tag. This must be called so that other targets can
- * be discovered. It restarts the NFC discovery loop.
- *
- * @throws NfcException if the tag is already in disconnected state or not connected
- */
- public void close() throws NfcException {
- // Check state
- checkState();
-
- try {
- mService.close(mHandle);
- isClosed = true;
- isConnected = false;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in close(): ", e);
- }
- }
-
- /**
- * Exchanges raw data with the tag, whatever the tag type.
- *
- * To exchange APDUs with a ISO14443-4-compliant tag, the data parameter
- * must be filled with the C-APDU (CLA, INS, P1, P2 [, ...]). The returned
- * data consists of the R-APDU ([...,] SW1, SW2).
- *
- * @param data data to be sent to the tag
- * @return data sent in response by the tag
- * @throws IOException if the tag has been lost or the connection has been
- * closed.
- * @throws NfcException in case of failure within the stack
- */
- public byte[] transceive(byte[] data) throws IOException, NfcException {
- // Check state
- checkState();
-
- // Perform transceive
- try {
- byte[] response = mService.transceive(mHandle, data);
- if (response == null) {
- throw new IOException("Transceive failed");
- }
- return response;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in transceive(): ", e);
- return null;
- }
- }
-
- /**
- * Checks whether tag is NDEF-compliant or not.
- *
- * @return true if the tag is NDEF-compliant, false otherwise
- * @throws NfcException in case an error occurred when trying to determine
- * whether the tag is NDEF-compliant
- */
- public boolean isNdef() throws NfcException {
- // Check state
- checkState();
-
- // Perform Check Ndef
- try {
- isNdef = mService.isNdef(mHandle);
- return isNdef;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in isNdef(): ", e);
- return false;
- }
- }
-
- /**
- * Returns target type. constants.
- *
- * @return tag type.
- */
- public String getType() {
- try {
- return mService.getType(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
- /**
- * Returns target UID.
- *
- * @return tag UID.
- */
- public byte[] getUid() {
- try {
- return mService.getUid(mHandle);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getType(): ", e);
- return null;
- }
- }
-
-}
diff --git a/core/java/com/trustedlogic/trustednfc/android/P2pInitiator.java b/core/java/com/trustedlogic/trustednfc/android/P2pInitiator.java
index 0f28ae0..6b93bce 100644
--- a/core/java/com/trustedlogic/trustednfc/android/P2pInitiator.java
+++ b/core/java/com/trustedlogic/trustednfc/android/P2pInitiator.java
@@ -23,15 +23,14 @@
import java.io.IOException;
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
-
+import android.nfc.IP2pInitiator;
import android.os.RemoteException;
import android.util.Log;
/**
* P2pInitiator represents the initiator in an NFC-IP1 peer-to-peer
* communication.
- *
+ *
* @see P2pTarget
* @since AA02.01
* @hide
@@ -44,24 +43,24 @@
* The entry point for P2P tag operations.
* @hide
*/
- private IP2pInitiator mService;
-
+ private final IP2pInitiator mService;
+
/**
* Internal constructor for the P2pInitiator class.
- *
+ *
* @param handle The handle returned by the NFC service and used to identify
* the tag in subsequent calls.
- *
+ *
* @hide
*/
P2pInitiator(IP2pInitiator service, int handle) {
this.mService = service;
this.mHandle = handle;
- }
+ }
/**
* Receives data from a P2pInitiator.
- *
+ *
* @return data sent by the P2pInitiator.
* @throws IOException if the target has been lost or if the connection has
* been closed.
@@ -81,7 +80,7 @@
/**
* Sends data to a P2pInitiator.
- *
+ *
* @param data data to be sent to the P2pInitiator.
* @throws IOException if the target has been lost or if the connection has
* been closed.
diff --git a/core/java/com/trustedlogic/trustednfc/android/P2pTarget.java b/core/java/com/trustedlogic/trustednfc/android/P2pTarget.java
index b5e00db..aa9e94f 100644
--- a/core/java/com/trustedlogic/trustednfc/android/P2pTarget.java
+++ b/core/java/com/trustedlogic/trustednfc/android/P2pTarget.java
@@ -23,14 +23,14 @@
import java.io.IOException;
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
-
+import android.nfc.ErrorCodes;
+import android.nfc.IP2pTarget;
import android.os.RemoteException;
import android.util.Log;
/**
* P2pTarget represents the target in an NFC-IP1 peer-to-peer communication.
- *
+ *
* @see P2pInitiator
* @since AA02.01
* @hide
@@ -43,27 +43,27 @@
* The entry point for P2P tag operations.
* @hide
*/
- private IP2pTarget mService;
-
+ private final IP2pTarget mService;
+
/**
* Flag set when the object is closed and thus not usable any more.
* @hide
*/
- private boolean isClosed = false;
-
+ private final boolean isClosed = false;
+
/**
* Flag set when the tag is connected.
* @hide
*/
private boolean isConnected = false;
-
+
/**
* Check if tag is still opened.
- *
+ *
* @return data sent by the P2pInitiator.
* @throws NfcException if accessing a closed target.
- *
- * @hide
+ *
+ * @hide
*/
public void checkState() throws NfcException {
if(isClosed) {
@@ -73,21 +73,21 @@
/**
* Internal constructor for the P2pTarget class.
- *
+ *
* @param handle The handle returned by the NFC service and used to identify
* the tag in subsequent calls.
- *
+ *
* @hide
*/
P2pTarget(IP2pTarget service, int handle) {
this.mService = service;
this.mHandle = handle;
- }
+ }
/**
* Connects to the P2pTarget. This shall be called prior to any other
* operation on the P2pTarget.
- *
+ *
* @throws NfcException
*/
public void connect() throws NfcException {
@@ -96,7 +96,7 @@
if (isConnected) {
throw new NfcException("Already connected");
}
-
+
// Perform connect
try {
int result = mService.connect(mHandle);
@@ -105,7 +105,8 @@
throw new NfcException("Failed to connect");
}
else {
- throw NfcManager.convertErrorToNfcException(result);
+ // TODO(nxp)
+ // throw NfcAdapter.convertErrorToNfcException(result);
}
}
isConnected = true;
@@ -117,7 +118,7 @@
/**
* Disconnects from the P2p Target. This must be called so that other
* targets can be discovered. It restarts the NFC discovery loop.
- *
+ *
* @throws NFCException
*/
public void disconnect() throws NfcException {
@@ -132,7 +133,7 @@
/**
* Exchanges raw data with the P2pTarget.
- *
+ *
* @param data data to be sent to the P2pTarget
* @return data sent in response by the P2pTarget
* @throws IOException if the target has been lost or the connection has
@@ -158,10 +159,11 @@
/**
* Get the General bytes of the connected P2P Target
- *
+ *
* @return general bytes of the connected P2P Target
* @throws IOException if the target in not in connected state
*/
+ @Override
public byte[] getGeneralBytes() throws IOException {
try {
if(isConnected){
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket.java
index ccfbeb4..eff01b6 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket.java
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket.java
@@ -22,47 +22,47 @@
package com.trustedlogic.trustednfc.android.internal;
-import com.trustedlogic.trustednfc.android.LlcpPacket;
+import android.nfc.LlcpPacket;
/**
* LlcpConnectionlessSocket represents a LLCP Connectionless object to be used
* in a connectionless communication
- *
+ *
* @since AA02.01
- * {@hide}
+ * @hide
*/
public class NativeLlcpConnectionlessSocket {
-
- private int mHandle;
-
- private int mSap;
-
- private int mLinkMiu;
-
- public NativeLlcpConnectionlessSocket(){;
- }
-
- public NativeLlcpConnectionlessSocket(int sap){
- mSap = sap;
- }
-
+
+ private int mHandle;
+
+ private int mSap;
+
+ private int mLinkMiu;
+
+ public NativeLlcpConnectionlessSocket(){;
+ }
+
+ public NativeLlcpConnectionlessSocket(int sap){
+ mSap = sap;
+ }
+
public native boolean doSendTo(int sap, byte[] data);
public native LlcpPacket doReceiveFrom(int linkMiu);
public native boolean doClose();
-
+
public int getLinkMiu(){
- return mLinkMiu;
+ return mLinkMiu;
}
-
+
public int getSap(){
- return mSap;
+ return mSap;
}
-
+
public int getHandle(){
- return mHandle;
+ return mHandle;
}
}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket.java
index a01f135..079d69b 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket.java
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket.java
@@ -30,53 +30,53 @@
public class NativeLlcpServiceSocket {
- private int mHandle;
-
- private int mLocalMiu;
-
- private int mLocalRw;
-
- private int mLocalLinearBufferLength;
-
- private int mSap;
-
- private int mTimeout;
-
- private String mServiceName;
-
- public NativeLlcpServiceSocket(){
-
- }
-
- public NativeLlcpServiceSocket(String serviceName){
- mServiceName = serviceName;
- }
-
+ private int mHandle;
+
+ private int mLocalMiu;
+
+ private int mLocalRw;
+
+ private int mLocalLinearBufferLength;
+
+ private int mSap;
+
+ private int mTimeout;
+
+ private String mServiceName;
+
+ public NativeLlcpServiceSocket(){
+
+ }
+
+ public NativeLlcpServiceSocket(String serviceName){
+ mServiceName = serviceName;
+ }
+
public native NativeLlcpSocket doAccept(int timeout, int miu, int rw, int linearBufferLength);
public native boolean doClose();
-
+
public int getHandle(){
- return mHandle;
+ return mHandle;
}
-
+
public void setAcceptTimeout(int timeout){
- mTimeout = timeout;
+ mTimeout = timeout;
}
-
+
public int getAcceptTimeout(){
- return mTimeout;
+ return mTimeout;
}
-
+
public int getRw(){
- return mLocalRw;
+ return mLocalRw;
}
-
+
public int getMiu(){
- return mLocalMiu;
+ return mLocalMiu;
}
-
+
public int getLinearBufferLength(){
- return mLocalLinearBufferLength;
+ return mLocalLinearBufferLength;
}
}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket.java
index 077c5e0..818cfaa 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket.java
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket.java
@@ -25,29 +25,29 @@
/**
* LlcpClientSocket represents a LLCP Connection-Oriented client to be used in a
* connection-oriented communication
- * {@hide}
+ * @hide
*/
public class NativeLlcpSocket {
-
- private int mHandle;
-
- private int mSap;
-
- private int mLocalMiu;
-
- private int mLocalRw;
-
+
+ private int mHandle;
+
+ private int mSap;
+
+ private int mLocalMiu;
+
+ private int mLocalRw;
+
private int mTimeout;
-
+
public NativeLlcpSocket(){
-
+
}
-
+
public NativeLlcpSocket(int sap, int miu, int rw){
- mSap = sap;
- mLocalMiu = miu;
- mLocalRw = rw;
+ mSap = sap;
+ mLocalMiu = miu;
+ mLocalRw = rw;
}
public native boolean doConnect(int nSap, int timeout);
@@ -59,35 +59,35 @@
public native boolean doSend(byte[] data);
public native int doReceive(byte[] recvBuff);
-
+
public native int doGetRemoteSocketMiu();
-
+
public native int doGetRemoteSocketRw();
-
-
-
+
+
+
public void setConnectTimeout(int timeout){
- mTimeout = timeout;
+ mTimeout = timeout;
}
-
+
public int getConnectTimeout(){
- return mTimeout;
+ return mTimeout;
}
-
+
public int getSap(){
- return mSap;
+ return mSap;
}
-
+
public int getMiu(){
- return mLocalMiu;
+ return mLocalMiu;
}
-
+
public int getRw(){
- return mLocalRw;
+ return mLocalRw;
}
-
+
public int getHandle(){
- return mHandle;
+ return mHandle;
}
}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNdefTag.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNdefTag.java
index d1e64a6..819b0395 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNdefTag.java
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNdefTag.java
@@ -25,7 +25,7 @@
/**
* Native interface to the NDEF tag functions
*
- * {@hide}
+ * @hide
*/
public class NativeNdefTag {
private int mHandle;
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcManager.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcManager.java
index 2f5a0f0..5ff348a 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcManager.java
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcManager.java
@@ -24,36 +24,40 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
-import com.trustedlogic.trustednfc.android.NfcManager;
-import com.trustedlogic.trustednfc.android.NdefMessage;
-import com.trustedlogic.trustednfc.android.NfcTag;
+import android.nfc.FormatException;
+import android.nfc.NdefTag;
+import android.nfc.NfcAdapter;
+import android.nfc.NdefMessage;
+import android.nfc.Tag;
/**
- * Native interface to the NFC Manager functions {@hide}
+ * Native interface to the NFC Manager functions
+ * @hide
*/
public class NativeNfcManager {
-
+
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA = "com.trustedlogic.trustednfc.android.extra.INTERNAL_LLCP_LINK_STATE";
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION = "com.trustedlogic.trustednfc.android.action.INTERNAL_LLCP_LINK_STATE_CHANGED";
-
+
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String INTERNAL_TARGET_DESELECTED_ACTION = "com.trustedlogic.trustednfc.android.action.INTERNAL_TARGET_DESELECTED";
/* Native structure */
private int mNative;
- private Context mContext;
+ private final Context mContext;
- private Handler mNfcHandler;
+ private final Handler mNfcHandler;
private static final String TAG = "NativeNfcManager";
@@ -92,10 +96,14 @@
*/
public native void enableDiscovery(int mode);
+ public native void disableDiscovery();
+
+ public native void readerDiscovery();
+
/**
* Disables an NFCManager mode of operation. Allows to disable tag reader,
* peer to peer initiator or target modes.
- *
+ *
* @param mode discovery mode to enable. Must be one of the provided
* NFCManager.DISCOVERY_MODE_* constants.
*/
@@ -130,45 +138,81 @@
public native boolean doActivateLlcp();
private class NfcHandler extends Handler {
+
+ private int convertType(String typeName) {
+ if (typeName.equals("Iso14443")) {
+ return Tag.NFC_TAG_ISO14443_4B;
+ } else if (typeName.equals("MifareUL")) {
+ return Tag.NFC_TAG_MIFARE;
+ } else if (typeName.equals("Mifare1K")) {
+ return Tag.NFC_TAG_MIFARE;
+ } else if (typeName.equals("Mifare4K")) {
+ return Tag.NFC_TAG_MIFARE;
+ } else if (typeName.equals("MifareDESFIRE")) {
+ return Tag.NFC_TAG_MIFARE;
+ } else if (typeName.equals("Unknown Mifare")) {
+ return Tag.NFC_TAG_MIFARE;
+ } else if (typeName.equals("Felica")) {
+ return Tag.NFC_TAG_FELICA;
+ } else if (typeName.equals("Jewel")) {
+ return Tag.NFC_TAG_JEWEL;
+ } else {
+ return Tag.NFC_TAG_OTHER;
+ }
+ }
+
@Override
public void handleMessage(Message msg) {
try {
switch (msg.what) {
case MSG_NDEF_TAG:
- Log.d(TAG, "Checking for NDEF tag message");
- NativeNfcTag tag = (NativeNfcTag) msg.obj;
- if (tag.doConnect()) {
- if (tag.checkNDEF()) {
- byte[] buff = tag.doRead();
+ Log.d(TAG, "Tag detected, notifying applications");
+ NativeNfcTag nativeTag = (NativeNfcTag) msg.obj;
+ if (nativeTag.doConnect()) {
+ if (nativeTag.checkNDEF()) {
+ byte[] buff = nativeTag.doRead();
if (buff != null) {
- NdefMessage msgNdef = new NdefMessage(buff);
- if (msgNdef != null) {
- /* Send broadcast ordered */
- Intent NdefMessageIntent = new Intent();
- NdefMessageIntent
- .setAction(NfcManager.NDEF_TAG_DISCOVERED_ACTION);
- NdefMessageIntent.putExtra(NfcManager.NDEF_MESSAGE_EXTRA,
- msgNdef);
- Log.d(TAG, "NDEF message found, broadcasting to applications");
- mContext.sendOrderedBroadcast(NdefMessageIntent,
- android.Manifest.permission.NFC_NOTIFY);
- /* Disconnect tag */
- tag.doAsyncDisconnect();
+ NdefMessage[] msgNdef = new NdefMessage[1];
+ try {
+ msgNdef[0] = new NdefMessage(buff);
+ NdefTag tag = new NdefTag(convertType(nativeTag.getType()), nativeTag.getUid(), nativeTag.getHandle(), msgNdef);
+ Intent intent = new Intent();
+ intent.setAction(NfcAdapter.ACTION_NDEF_TAG_DISCOVERED);
+ intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Log.d(TAG, "NDEF tag found, starting corresponding activity");
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "No activity found, disconnecting");
+ nativeTag.doAsyncDisconnect();
+ }
+ } catch (FormatException e) {
+ Log.w(TAG, "Unable to create NDEF message object (tag empty or not well formated)");
+ nativeTag.doAsyncDisconnect();
}
} else {
- Log.w(TAG, "Unable to read NDEF message (tag empty or not well formated)");
- /* Disconnect tag */
- tag.doAsyncDisconnect();
+ Log.w(TAG, "Unable to read NDEF message (tag empty or not well formated)");
+ nativeTag.doAsyncDisconnect();
}
} else {
- Log.d(TAG, "Tag is *not* NDEF compliant");
- /* Disconnect tag */
- tag.doAsyncDisconnect();
+ Intent intent = new Intent();
+ Tag tag = new Tag(convertType(nativeTag.getType()), false, nativeTag.getUid(), nativeTag.getHandle());
+ intent.setAction(NfcAdapter.ACTION_TAG_DISCOVERED);
+ intent.putExtra(NfcAdapter.EXTRA_TAG, tag);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ Log.d(TAG, "Non-NDEF tag found, starting corresponding activity");
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, "No activity found, disconnecting");
+ nativeTag.doAsyncDisconnect();
+ }
}
} else {
- /* Disconnect tag */
- tag.doAsyncDisconnect();
+ Log.w(TAG, "Failed to connect to tag");
+ nativeTag.doAsyncDisconnect();
}
break;
case MSG_CARD_EMULATION:
@@ -176,8 +220,8 @@
byte[] aid = (byte[]) msg.obj;
/* Send broadcast ordered */
Intent TransactionIntent = new Intent();
- TransactionIntent.setAction(NfcManager.TRANSACTION_DETECTED_ACTION);
- TransactionIntent.putExtra(NfcManager.AID_EXTRA, aid);
+ TransactionIntent.setAction(NfcAdapter.ACTION_TRANSACTION_DETECTED);
+ TransactionIntent.putExtra(NfcAdapter.EXTRA_AID, aid);
Log.d(TAG, "Broadcasting Card Emulation event");
mContext.sendOrderedBroadcast(TransactionIntent,
android.Manifest.permission.NFC_NOTIFY);
@@ -201,7 +245,7 @@
.setAction(INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
LlcpLinkIntent.putExtra(
INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
- NfcManager.LLCP_LINK_STATE_ACTIVATED);
+ NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
Log.d(TAG, "Broadcasting internal LLCP activation");
mContext.sendBroadcast(LlcpLinkIntent);
}
@@ -223,7 +267,7 @@
LlcpLinkIntent
.setAction(INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
LlcpLinkIntent.putExtra(INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
- NfcManager.LLCP_LINK_STATE_ACTIVATED);
+ NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
Log.d(TAG, "Broadcasting internal LLCP activation");
mContext.sendBroadcast(LlcpLinkIntent);
}
@@ -235,9 +279,9 @@
/* Broadcast Intent Link LLCP activated */
Log.d(TAG, "LLCP Link Deactivated message");
Intent LlcpLinkIntent = new Intent();
- LlcpLinkIntent.setAction(NfcManager.LLCP_LINK_STATE_CHANGED_ACTION);
- LlcpLinkIntent.putExtra(NfcManager.LLCP_LINK_STATE_CHANGED_EXTRA,
- NfcManager.LLCP_LINK_STATE_DEACTIVATED);
+ LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
+ LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
+ NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
Log.d(TAG, "Broadcasting LLCP deactivation");
mContext.sendOrderedBroadcast(LlcpLinkIntent,
android.Manifest.permission.NFC_LLCP);
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcTag.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcTag.java
index b92783d..47cf45b 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcTag.java
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcTag.java
@@ -24,39 +24,48 @@
/**
* Native interface to the NFC tag functions
- *
- * {@hide}
+ *
+ * @hide
*/
public class NativeNfcTag {
- private int mHandle;
+ private int mHandle;
- private String mType;
-
- private byte[] mUid;
+ private String mType;
- public native boolean doConnect();
+ private byte[] mUid;
- public native boolean doDisconnect();
-
- public native void doAsyncDisconnect();
+ public native boolean doConnect();
- public native byte[] doTransceive(byte[] data);
+ public native boolean doDisconnect();
- public native boolean checkNDEF();
-
+ public native void doAsyncDisconnect();
+
+ public native byte[] doTransceive(byte[] data);
+
+ public native boolean checkNDEF();
+
public native byte[] doRead();
public native boolean doWrite(byte[] buf);
- public int getHandle() {
- return mHandle;
- }
-
- public String getType() {
- return mType;
- }
-
- public byte[] getUid() {
- return mUid;
- }
+ private NativeNfcTag() {
+ }
+
+ public NativeNfcTag(int handle, String type, byte[] uid) {
+ mHandle = handle;
+ mType = type;
+ mUid = uid.clone();
+ }
+
+ public int getHandle() {
+ return mHandle;
+ }
+
+ public String getType() {
+ return mType;
+ }
+
+ public byte[] getUid() {
+ return mUid;
+ }
}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeP2pDevice.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeP2pDevice.java
index 75d25ba..c674309 100644
--- a/core/java/com/trustedlogic/trustednfc/android/internal/NativeP2pDevice.java
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeP2pDevice.java
@@ -24,52 +24,52 @@
/**
* Native interface to the P2P Initiator functions
- *
- * {@hide}
+ *
+ * @hide
*/
public class NativeP2pDevice {
-
- /**
- * Peer-to-Peer Target.
- */
- public static final short MODE_P2P_TARGET = 0x00;
- /**
- * Peer-to-Peer Initiator.
- */
- public static final short MODE_P2P_INITIATOR = 0x01;
+ /**
+ * Peer-to-Peer Target.
+ */
+ public static final short MODE_P2P_TARGET = 0x00;
- /**
- * Invalid target type.
- */
- public static final short MODE_INVALID = 0xff;
+ /**
+ * Peer-to-Peer Initiator.
+ */
+ public static final short MODE_P2P_INITIATOR = 0x01;
- private int mHandle;
+ /**
+ * Invalid target type.
+ */
+ public static final short MODE_INVALID = 0xff;
- private int mMode;
+ private int mHandle;
- private byte[] mGeneralBytes;
+ private int mMode;
- public native byte[] doReceive();
+ private byte[] mGeneralBytes;
- public native boolean doSend(byte[] data);
+ public native byte[] doReceive();
- public native boolean doConnect();
+ public native boolean doSend(byte[] data);
- public native boolean doDisconnect();
+ public native boolean doConnect();
- public native byte[] doTransceive(byte[] data);
-
- public int getHandle() {
- return mHandle;
- }
+ public native boolean doDisconnect();
- public int getMode() {
- return mMode;
- }
+ public native byte[] doTransceive(byte[] data);
- public byte[] getGeneralBytes() {
- return mGeneralBytes;
- }
+ public int getHandle() {
+ return mHandle;
+ }
+
+ public int getMode() {
+ return mMode;
+ }
+
+ public byte[] getGeneralBytes() {
+ return mGeneralBytes;
+ }
}
diff --git a/core/jni/android_content_res_ObbScanner.cpp b/core/jni/android_content_res_ObbScanner.cpp
index 2a9eacf..3fd7985 100644
--- a/core/jni/android_content_res_ObbScanner.cpp
+++ b/core/jni/android_content_res_ObbScanner.cpp
@@ -32,6 +32,7 @@
jfieldID packageName;
jfieldID version;
jfieldID flags;
+ jfieldID salt;
} gObbInfoClassInfo;
static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
@@ -69,6 +70,14 @@
env->SetObjectField(obbInfo, gObbInfoClassInfo.packageName, packageName);
env->SetIntField(obbInfo, gObbInfoClassInfo.version, obb->getVersion());
env->SetIntField(obbInfo, gObbInfoClassInfo.flags, obb->getFlags());
+
+ size_t saltLen;
+ const unsigned char* salt = obb->getSalt(&saltLen);
+ if (saltLen > 0) {
+ jbyteArray saltArray = env->NewByteArray(saltLen);
+ env->SetByteArrayRegion(saltArray, 0, saltLen, (jbyte*)salt);
+ env->SetObjectField(obbInfo, gObbInfoClassInfo.salt, saltArray);
+ }
}
/*
@@ -99,6 +108,8 @@
"version", "I");
GET_FIELD_ID(gObbInfoClassInfo.flags, gObbInfoClassInfo.clazz,
"flags", "I");
+ GET_FIELD_ID(gObbInfoClassInfo.salt, gObbInfoClassInfo.clazz,
+ "salt", "[B");
return AndroidRuntime::registerNativeMethods(env, "android/content/res/ObbScanner", gMethods,
NELEM(gMethods));
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 43eeda8..ff079e4 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -86,9 +86,10 @@
<protected-broadcast android:name="android.hardware.action.USB_DISCONNECTED" />
<protected-broadcast android:name="android.hardware.action.USB_STATE" />
- <protected-broadcast android:name="com.trustedlogic.trustednfc.android.action.NDEF_TAG_DISCOVERED" />
- <protected-broadcast android:name="com.trustedlogic.trustednfc.android.action.TRANSACTION_DETECTED" />
- <protected-broadcast android:name="com.trustedlogic.trustednfc.android.action.LLCP_LINK_STATE_CHANGED" />
+ <protected-broadcast android:name="android.nfc.action.NDEF_TAG_DISCOVERED" />
+ <protected-broadcast android:name="android.nfc.action.TAG_DISCOVERED" />
+ <protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
+ <protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
<!-- ====================================== -->
<!-- Permissions for things that cost money -->
diff --git a/core/res/res/drawable-hdpi/ic_media_ff.png b/core/res/res/drawable-hdpi/ic_media_ff.png
index b0dc05b..0d9ecd0 100644
--- a/core/res/res/drawable-hdpi/ic_media_ff.png
+++ b/core/res/res/drawable-hdpi/ic_media_ff.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_next.png b/core/res/res/drawable-hdpi/ic_media_next.png
index 2552f4e..5ee97b6 100644
--- a/core/res/res/drawable-hdpi/ic_media_next.png
+++ b/core/res/res/drawable-hdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_pause.png b/core/res/res/drawable-hdpi/ic_media_pause.png
index d4670c2..a223f9a 100644
--- a/core/res/res/drawable-hdpi/ic_media_pause.png
+++ b/core/res/res/drawable-hdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_play.png b/core/res/res/drawable-hdpi/ic_media_play.png
index e67ec80..746d3d2 100644
--- a/core/res/res/drawable-hdpi/ic_media_play.png
+++ b/core/res/res/drawable-hdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_previous.png b/core/res/res/drawable-hdpi/ic_media_previous.png
index 05eba71..b581a11 100644
--- a/core/res/res/drawable-hdpi/ic_media_previous.png
+++ b/core/res/res/drawable-hdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_media_rew.png b/core/res/res/drawable-hdpi/ic_media_rew.png
index 88eed2e..4dd8739 100644
--- a/core/res/res/drawable-hdpi/ic_media_rew.png
+++ b/core/res/res/drawable-hdpi/ic_media_rew.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
index 4f95d50..b9fd0a4 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
index 10a37b7..94e947d 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/menu_background.9.png b/core/res/res/drawable-hdpi/menu_background.9.png
index 1b43435..f4c9e08 100644
--- a/core/res/res/drawable-hdpi/menu_background.9.png
+++ b/core/res/res/drawable-hdpi/menu_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/menu_background_fill_parent_width.9.png b/core/res/res/drawable-hdpi/menu_background_fill_parent_width.9.png
index ec974d6..a3cec11 100644
--- a/core/res/res/drawable-hdpi/menu_background_fill_parent_width.9.png
+++ b/core/res/res/drawable-hdpi/menu_background_fill_parent_width.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_bottom_dark.9.png b/core/res/res/drawable-hdpi/popup_bottom_dark.9.png
index 8b5d3d5..442105c 100755
--- a/core/res/res/drawable-hdpi/popup_bottom_dark.9.png
+++ b/core/res/res/drawable-hdpi/popup_bottom_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_center_medium.9.png b/core/res/res/drawable-hdpi/popup_center_medium.9.png
index 1ce2a6d..5129dbd 100755
--- a/core/res/res/drawable-hdpi/popup_center_medium.9.png
+++ b/core/res/res/drawable-hdpi/popup_center_medium.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_full_dark.9.png b/core/res/res/drawable-hdpi/popup_full_dark.9.png
index 8f2fdf0..c28465b 100755
--- a/core/res/res/drawable-hdpi/popup_full_dark.9.png
+++ b/core/res/res/drawable-hdpi/popup_full_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/popup_top_dark.9.png b/core/res/res/drawable-hdpi/popup_top_dark.9.png
index 1108909..31f5f3b 100755
--- a/core/res/res/drawable-hdpi/popup_top_dark.9.png
+++ b/core/res/res/drawable-hdpi/popup_top_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_gps_on.png b/core/res/res/drawable-hdpi/stat_sys_gps_on.png
index 1e1ab32..150c9fc 100644
--- a/core/res/res/drawable-hdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-hdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_select_handle.png b/core/res/res/drawable-hdpi/text_select_handle.png
deleted file mode 100644
index 80d48ab..0000000
--- a/core/res/res/drawable-hdpi/text_select_handle.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_ff.png b/core/res/res/drawable-mdpi/ic_media_ff.png
old mode 100755
new mode 100644
index ce7e195..d99779d
--- a/core/res/res/drawable-mdpi/ic_media_ff.png
+++ b/core/res/res/drawable-mdpi/ic_media_ff.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_next.png b/core/res/res/drawable-mdpi/ic_media_next.png
old mode 100755
new mode 100644
index 84f38e8..cee4930
--- a/core/res/res/drawable-mdpi/ic_media_next.png
+++ b/core/res/res/drawable-mdpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_pause.png b/core/res/res/drawable-mdpi/ic_media_pause.png
old mode 100755
new mode 100644
index 688118e..c3dfcbd
--- a/core/res/res/drawable-mdpi/ic_media_pause.png
+++ b/core/res/res/drawable-mdpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_play.png b/core/res/res/drawable-mdpi/ic_media_play.png
old mode 100755
new mode 100644
index 7aa7af8..688e01d
--- a/core/res/res/drawable-mdpi/ic_media_play.png
+++ b/core/res/res/drawable-mdpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_previous.png b/core/res/res/drawable-mdpi/ic_media_previous.png
old mode 100755
new mode 100644
index 1bba544..1be95b4
--- a/core/res/res/drawable-mdpi/ic_media_previous.png
+++ b/core/res/res/drawable-mdpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_media_rew.png b/core/res/res/drawable-mdpi/ic_media_rew.png
old mode 100755
new mode 100644
index 132df7f..8311508
--- a/core/res/res/drawable-mdpi/ic_media_rew.png
+++ b/core/res/res/drawable-mdpi/ic_media_rew.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_bottom_dark.9.png b/core/res/res/drawable-mdpi/popup_bottom_dark.9.png
index 76a2a7f..c21f982 100644
--- a/core/res/res/drawable-mdpi/popup_bottom_dark.9.png
+++ b/core/res/res/drawable-mdpi/popup_bottom_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_bottom_medium.9.png b/core/res/res/drawable-mdpi/popup_bottom_medium.9.png
index dee6d6b..0992135 100755
--- a/core/res/res/drawable-mdpi/popup_bottom_medium.9.png
+++ b/core/res/res/drawable-mdpi/popup_bottom_medium.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_full_dark.9.png b/core/res/res/drawable-mdpi/popup_full_dark.9.png
index 2305be4..84ba5ca0 100644
--- a/core/res/res/drawable-mdpi/popup_full_dark.9.png
+++ b/core/res/res/drawable-mdpi/popup_full_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/popup_top_dark.9.png b/core/res/res/drawable-mdpi/popup_top_dark.9.png
index af511f2..2f847ad 100644
--- a/core/res/res/drawable-mdpi/popup_top_dark.9.png
+++ b/core/res/res/drawable-mdpi/popup_top_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_gps_on.png b/core/res/res/drawable-mdpi/stat_sys_gps_on.png
old mode 100755
new mode 100644
index a2c677d..70354b4
--- a/core/res/res/drawable-mdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-mdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle.png b/core/res/res/drawable-mdpi/text_select_handle.png
deleted file mode 100644
index 93a5a15..0000000
--- a/core/res/res/drawable-mdpi/text_select_handle.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_left.png b/core/res/res/drawable-mdpi/text_select_handle_left.png
new file mode 100644
index 0000000..40e6ac0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_select_handle_left.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_middle.png b/core/res/res/drawable-mdpi/text_select_handle_middle.png
index 201e7f9..9421759d 100644
--- a/core/res/res/drawable-mdpi/text_select_handle_middle.png
+++ b/core/res/res/drawable-mdpi/text_select_handle_middle.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_select_handle_right.png b/core/res/res/drawable-mdpi/text_select_handle_right.png
new file mode 100644
index 0000000..9d2d08a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_select_handle_right.png
Binary files differ
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index a33851c..e799527 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -63,6 +63,9 @@
<item>@drawable/scrollbar_handle_horizontal</item>
<item>@drawable/scrollbar_handle_vertical</item>
<item>@drawable/spinner_dropdown_background</item>
+ <item>@drawable/text_select_handle_left</item>
+ <item>@drawable/text_select_handle_middle</item>
+ <item>@drawable/text_select_handle_right</item>
<item>@drawable/title_bar</item>
<item>@drawable/title_bar_shadow</item>
<!-- Visual lock screen -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 849c564..99fc5c2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -149,9 +149,15 @@
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">false</bool>
+ <!-- Don't name config resources like this. It should look like config_annoyDianne -->
+ <bool name="config_annoy_dianne">true</bool>
+
<!-- If this is true, the screen will come on when you unplug usb/power/whatever. -->
<bool name="config_unplugTurnsOnScreen">false</bool>
+ <!-- If this is true, the screen will fade off. -->
+ <bool name="config_animateScreenLights">true</bool>
+
<!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
<!-- The number of degrees to rotate the display when the keyboard is open. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5c60fd5..037a362 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -382,7 +382,7 @@
<!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgrouplab_storage">Storage</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
- <string name="permgroupdesc_storage" product="nosdcard">Access the shared storage.</string>
+ <string name="permgroupdesc_storage" product="nosdcard">Access the USB storage.</string>
<!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permgroupdesc_storage" product="default">Access the SD card.</string>
@@ -890,29 +890,29 @@
<string name="permdesc_mount_format_filesystems">Allows the application to format removable storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_asec_access">get information on secure storage</string>
+ <string name="permlab_asec_access">get information on internal storage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_asec_access">Allows the application to get information on secure storage.</string>
+ <string name="permdesc_asec_access">Allows the application to get information on internal storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_asec_create">create secure storage</string>
+ <string name="permlab_asec_create">create internal storage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_asec_create">Allows the application to create secure storage.</string>
+ <string name="permdesc_asec_create">Allows the application to create internal storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_asec_destroy">destroy secure storage</string>
+ <string name="permlab_asec_destroy">destroy internal storage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_asec_destroy">Allows the application to destroy secure storage.</string>
+ <string name="permdesc_asec_destroy">Allows the application to destroy internal storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_asec_mount_unmount">mount / unmount secure storage</string>
+ <string name="permlab_asec_mount_unmount">mount / unmount internal storage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_asec_mount_unmount">Allows the application to mount / unmount secure storage.</string>
+ <string name="permdesc_asec_mount_unmount">Allows the application to mount / unmount internal storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_asec_rename">rename secure storage</string>
+ <string name="permlab_asec_rename">rename internal storage</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_asec_rename">Allows the application to rename secure storage.</string>
+ <string name="permdesc_asec_rename">Allows the application to rename internal storage.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_vibrate">control vibrator</string>
@@ -1227,11 +1227,11 @@
user dictionary.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
- <string name="permlab_sdcardWrite" product="nosdcard">modify/delete shared storage contents</string>
+ <string name="permlab_sdcardWrite" product="nosdcard">modify/delete USB storage contents</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_sdcardWrite" product="default">modify/delete SD card contents</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=30] -->
- <string name="permdesc_sdcardWrite" product="nosdcard">Allows an application to write to the shared storage.</string>
+ <string name="permdesc_sdcardWrite" product="nosdcard">Allows an application to write to the USB storage.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_sdcardWrite" product="default">Allows an application to write to the SD card.</string>
@@ -2091,15 +2091,15 @@
<!-- See USB_STORAGE. USB_STORAGE_DIALOG: After the user selects the notification, a dialog is shown asking if he wants to mount. This is the title. -->
<string name="usb_storage_title">USB connected</string>
<!-- See USB_STORAGE. This is the message. [CHAR LIMIT=NONE] -->
- <string name="usb_storage_message" product="nosdcard">You have connected your phone to your computer via USB. Select the button below if you want to copy files between your computer and your Android\u2018s shared storage.</string>
+ <string name="usb_storage_message" product="nosdcard">You have connected your phone to your computer via USB. Select the button below if you want to copy files between your computer and your Android\u2018s USB storage.</string>
<!-- See USB_STORAGE. This is the message. -->
<string name="usb_storage_message" product="default">You have connected your phone to your computer via USB. Select the button below if you want to copy files between your computer and your Android\u2018s SD card.</string>
<!-- See USB_STORAGE. This is the button text to mount the phone on the computer. -->
<string name="usb_storage_button_mount">Turn on USB storage</string>
<!-- See USB_STORAGE_DIALOG. If there was an error mounting, this is the text. [CHAR LIMIT=NONE] -->
- <string name="usb_storage_error_message" product="nosdcard">There is a problem using your shared storage for USB storage.</string>
+ <string name="usb_storage_error_message" product="nosdcard">There is a problem using your USB storage for USB mass storage.</string>
<!-- See USB_STORAGE_DIALOG. If there was an error mounting, this is the text. -->
- <string name="usb_storage_error_message" product="default">There is a problem using your SD card for USB storage.</string>
+ <string name="usb_storage_error_message" product="default">There is a problem using your SD card for USB mass storage.</string>
<!-- USB_STORAGE: When the user connects the phone to a computer via USB, we show a notification asking if he wants to share files across. This is the title -->
<string name="usb_storage_notification_title">USB connected</string>
<!-- See USB_STORAGE. This is the message. -->
@@ -2115,7 +2115,7 @@
<!-- See USB_STORAGE_STOP. USB_STORAGE_STOP_DIALOG: After the user selects the notification, a dialog is shown asking if he wants to stop usb storage. This is the title. -->
<string name="usb_storage_stop_title">USB storage in use</string>
<!-- See USB_STORAGE_STOP. This is the message. [CHAR LIMIT=NONE] -->
- <string name="usb_storage_stop_message" product="nosdcard">Before turning off USB storage, make sure you have unmounted (\u201cejected\u201d) your Android\u2018s shared storage from your computer.</string>
+ <string name="usb_storage_stop_message" product="nosdcard">Before turning off USB storage, make sure you have unmounted (\u201cejected\u201d) your Android\u2018s USB storage from your computer.</string>
<!-- See USB_STORAGE_STOP. This is the message. -->
<string name="usb_storage_stop_message" product="default">Before turning off USB storage, make sure you have unmounted (\u201cejected\u201d) your Android\u2018s SD card from your computer.</string>
<!-- See USB_STORAGE_STOP. This is the button text to stop usb storage. -->
@@ -2135,11 +2135,11 @@
<!-- External media format dialog strings -->
<!-- This is the label for the activity, and should never be visible to the user. -->
<!-- See EXTMEDIA_FORMAT. EXTMEDIA_FORMAT_DIALOG: After the user selects the notification, a dialog is shown asking if he wants to format the SD card. This is the title. [CHAR LIMIT=20] -->
- <string name="extmedia_format_title" product="nosdcard">Format shared storage</string>
+ <string name="extmedia_format_title" product="nosdcard">Format USB storage</string>
<!-- See EXTMEDIA_FORMAT. EXTMEDIA_FORMAT_DIALOG: After the user selects the notification, a dialog is shown asking if he wants to format the SD card. This is the title. -->
<string name="extmedia_format_title" product="default">Format SD card</string>
<!-- See EXTMEDIA_FORMAT. This is the message. [CHAR LIMIT=NONE] -->
- <string name="extmedia_format_message" product="nosdcard">Format shared storage, erasing all files stored there? Action cannot be reversed!</string>
+ <string name="extmedia_format_message" product="nosdcard">Format USB storage, erasing all files stored there? Action cannot be reversed!</string>
<!-- See EXTMEDIA_FORMAT. This is the message. -->
<string name="extmedia_format_message" product="default">Are you sure you want to format the SD card? All data on your card will be lost.</string>
<!-- See EXTMEDIA_FORMAT. This is the button text to format the sd card. -->
@@ -2167,49 +2167,49 @@
<!-- External media notification strings -->
<!-- Shown when external media is being checked [CHAR LIMIT=30] -->
- <string name="ext_media_checking_notification_title" product="nosdcard">Preparing shared storage</string>
+ <string name="ext_media_checking_notification_title" product="nosdcard">Preparing USB storage</string>
<!-- Shown when external media is being checked -->
<string name="ext_media_checking_notification_title" product="default">Preparing SD card</string>
<string name="ext_media_checking_notification_message">Checking for errors.</string>
<!-- Shown when external media is blank (or unsupported filesystem) [CHAR LIMIT=30] -->
- <string name="ext_media_nofs_notification_title" product="nosdcard">Blank shared storage</string>
+ <string name="ext_media_nofs_notification_title" product="nosdcard">Blank USB storage</string>
<!-- Shown when external media is blank (or unsupported filesystem) -->
<string name="ext_media_nofs_notification_title" product="default">Blank SD card</string>
- <!-- Shown when shared storage cannot be read. [CHAR LIMIT=NONE] -->
- <string name="ext_media_nofs_notification_message" product="nosdcard">Shared storage blank or has unsupported filesystem.</string>
+ <!-- Shown when USB storage cannot be read. [CHAR LIMIT=NONE] -->
+ <string name="ext_media_nofs_notification_message" product="nosdcard">USB storage blank or has unsupported filesystem.</string>
<string name="ext_media_nofs_notification_message" product="default">SD card blank or has unsupported filesystem.</string>
<!-- Shown when external media is unmountable (corrupt)) [CHAR LIMIT=30] -->
- <string name="ext_media_unmountable_notification_title" product="nosdcard">Damaged shared storage</string>
+ <string name="ext_media_unmountable_notification_title" product="nosdcard">Damaged USB storage</string>
<!-- Shown when external media is unmountable (corrupt)) -->
<string name="ext_media_unmountable_notification_title" product="default">Damaged SD card</string>
- <!-- Shown when shared storage cannot be read. [CHAR LIMIT=NONE] -->
- <string name="ext_media_unmountable_notification_message" product="nosdcard">Shared storage damaged. You may have to reformat it.</string>
+ <!-- Shown when USB storage cannot be read. [CHAR LIMIT=NONE] -->
+ <string name="ext_media_unmountable_notification_message" product="nosdcard">USB storage damaged. You may have to reformat it.</string>
<string name="ext_media_unmountable_notification_message" product="default">SD card damaged. You may have to reformat it.</string>
<!-- Shown when external media is unsafely removed [CHAR LIMIT=30] -->
- <string name="ext_media_badremoval_notification_title" product="nosdcard">Shared storage unexpectedly removed</string>
+ <string name="ext_media_badremoval_notification_title" product="nosdcard">USB storage unexpectedly removed</string>
<!-- Shown when external media is unsafely removed -->
<string name="ext_media_badremoval_notification_title" product="default">SD card unexpectedly removed</string>
<!-- Shown when external media is unsafely removed. [CHAR LIMIT=NONE] -->
- <string name="ext_media_badremoval_notification_message" product="nosdcard">Unmount shared storage before removing to avoid data loss.</string>
+ <string name="ext_media_badremoval_notification_message" product="nosdcard">Unmount USB storage before removing to avoid data loss.</string>
<string name="ext_media_badremoval_notification_message" product="default">Unmount SD card before removing to avoid data loss.</string>
<!-- Shown when external media has been safely removed [CHAR LIMIT=30] -->
- <string name="ext_media_safe_unmount_notification_title" product="nosdcard">Shared storage safe to remove</string>
+ <string name="ext_media_safe_unmount_notification_title" product="nosdcard">USB storage safe to remove</string>
<!-- Shown when external media has been safely removed -->
<string name="ext_media_safe_unmount_notification_title" product="default">SD card safe to remove</string>
<!-- Shown when external media has been safely removed. [CHAR LIMIT=NONE] -->
- <string name="ext_media_safe_unmount_notification_message" product="nosdcard">You can safely remove shared storage.</string>
+ <string name="ext_media_safe_unmount_notification_message" product="nosdcard">You can safely remove USB storage.</string>
<string name="ext_media_safe_unmount_notification_message" product="default">You can safely remove SD card.</string>
<!-- Shown when external media is missing [CHAR LIMIT=30] -->
- <string name="ext_media_nomedia_notification_title" product="nosdcard">Removed shared storage</string>
+ <string name="ext_media_nomedia_notification_title" product="nosdcard">Removed USB storage</string>
<!-- Shown when external media is missing -->
<string name="ext_media_nomedia_notification_title" product="default">Removed SD card</string>
<!-- Shown when external media is missing. [CHAR LIMIT=NONE] -->
- <string name="ext_media_nomedia_notification_message" product="nosdcard">Shared storage removed. Insert new media.</string>
+ <string name="ext_media_nomedia_notification_message" product="nosdcard">USB storage removed. Insert new media.</string>
<string name="ext_media_nomedia_notification_message" product="default">SD card removed. Insert a new one.</string>
<!-- Shown in LauncherActivity when the requested target Intent didn't return any matching Activities, leaving the list empty. -->
diff --git a/core/tests/coretests/res/raw/test1.obb b/core/tests/coretests/res/raw/test1.obb
index 170e36f..8466588 100644
--- a/core/tests/coretests/res/raw/test1.obb
+++ b/core/tests/coretests/res/raw/test1.obb
Binary files differ
diff --git a/core/tests/coretests/res/raw/test1_wrongpackage.obb b/core/tests/coretests/res/raw/test1_wrongpackage.obb
index 2e02eaa..d0aafe1 100644
--- a/core/tests/coretests/res/raw/test1_wrongpackage.obb
+++ b/core/tests/coretests/res/raw/test1_wrongpackage.obb
Binary files differ
diff --git a/docs/html/guide/appendix/install-location.jd b/docs/html/guide/appendix/install-location.jd
index be89caf..914aa66 100644
--- a/docs/html/guide/appendix/install-location.jd
+++ b/docs/html/guide/appendix/install-location.jd
@@ -111,7 +111,7 @@
<p class="caution"><strong>Caution:</strong> Although XML markup such as this will be ignored by
older platforms, you must be careful not to use programming APIs introduced in API Level 8
while your {@code minSdkVersion} is less than "8", unless you perform the work necessary to
-provide backward compatiblity in your code. For information about building
+provide backward compatibility in your code. For information about building
backward compatibility in your application code, see the <a
href="{@docRoot}resources/articles/backward-compatibility.html">Backward Compatibility</a>
article.</p>
@@ -167,6 +167,10 @@
<dd>Your {@link android.app.admin.DeviceAdminReceiver} and all its admin capabilities will
be disabled, which can have unforeseeable consequences for the device functionality, which may
persist after external storage is remounted.</dd>
+ <dt>Broadcast Receivers listening for "boot completed"</dt>
+ <dd>The system delivers the {@link android.content.Intent#ACTION_BOOT_COMPLETED} broadcast
+before the external storage is mounted to the device. If your application is installed on the
+external storage, it can never receive this broadcast.</dd>
</dl>
<p>If your application uses any of the features listed above, you <strong>should not</strong> allow
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 291b18a..5ab1640 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -76,6 +76,9 @@
/* Stream over a socket, limited to a single stream */
OUTPUT_FORMAT_RTP_AVP = 7,
+ /* H.264/AAC data encapsulated in MPEG2/TS */
+ OUTPUT_FORMAT_MPEG2TS = 8,
+
OUTPUT_FORMAT_LIST_END // must be last - used to validate format type
};
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index 9d2cff6..a3da3ed 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -36,6 +36,7 @@
enum Flags {
kWantsPrefetching = 1,
kStreamedFromLocalHost = 2,
+ kIsCachingDataSource = 4,
};
static sp<DataSource> CreateFromURI(
diff --git a/include/media/stagefright/MPEG2TSWriter.h b/include/media/stagefright/MPEG2TSWriter.h
index 551ca01..f2c6505 100644
--- a/include/media/stagefright/MPEG2TSWriter.h
+++ b/include/media/stagefright/MPEG2TSWriter.h
@@ -25,7 +25,10 @@
namespace android {
+struct ABuffer;
+
struct MPEG2TSWriter : public MediaWriter {
+ MPEG2TSWriter(int fd);
MPEG2TSWriter(const char *filename);
virtual status_t addSource(const sp<MediaSource> &source);
@@ -59,6 +62,8 @@
int64_t mNumTSPacketsWritten;
int64_t mNumTSPacketsBeforeMeta;
+ void init();
+
void writeTS();
void writeProgramAssociationTable();
void writeProgramMap();
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index 6533600..de447be 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -118,6 +118,9 @@
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth, uint32_t reqHeight) = 0;
+ virtual status_t turnElectronBeamOff(int32_t mode) = 0;
+ virtual status_t turnElectronBeamOn(int32_t mode) = 0;
+
/* Signal surfaceflinger that there might be some work to do
* This is an ASYNCHRONOUS call.
*/
@@ -142,7 +145,9 @@
FREEZE_DISPLAY,
UNFREEZE_DISPLAY,
SIGNAL,
- CAPTURE_SCREEN
+ CAPTURE_SCREEN,
+ TURN_ELECTRON_BEAM_OFF,
+ TURN_ELECTRON_BEAM_ON
};
virtual status_t onTransact( uint32_t code,
diff --git a/include/utils/ObbFile.h b/include/utils/ObbFile.h
index 5243f50..47559cd 100644
--- a/include/utils/ObbFile.h
+++ b/include/utils/ObbFile.h
@@ -27,6 +27,7 @@
// OBB flags (bit 0)
#define OBB_OVERLAY (1 << 0)
+#define OBB_SALTED (1 << 1)
class ObbFile : public RefBase {
protected:
@@ -70,6 +71,26 @@
mFlags = flags;
}
+ const unsigned char* getSalt(size_t* length) const {
+ if ((mFlags & OBB_SALTED) == 0) {
+ *length = 0;
+ return NULL;
+ }
+
+ *length = sizeof(mSalt);
+ return mSalt;
+ }
+
+ bool setSalt(const unsigned char* salt, size_t length) {
+ if (length != sizeof(mSalt)) {
+ return false;
+ }
+
+ memcpy(mSalt, salt, sizeof(mSalt));
+ mFlags |= OBB_SALTED;
+ return true;
+ }
+
bool isOverlay() {
return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;
}
@@ -103,6 +124,12 @@
/* Flags for this OBB type. */
int32_t mFlags;
+ /* Whether the file is salted. */
+ bool mSalted;
+
+ /* The encryption salt. */
+ unsigned char mSalt[8];
+
const char* mFileName;
size_t mFileSize;
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index d676f5e..969ee79 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -142,6 +142,24 @@
return reply.readInt32();
}
+ virtual status_t turnElectronBeamOff(int32_t mode)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ data.writeInt32(mode);
+ remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_OFF, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual status_t turnElectronBeamOn(int32_t mode)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ data.writeInt32(mode);
+ remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_ON, data, &reply);
+ return reply.readInt32();
+ }
+
virtual void signal() const
{
Parcel data, reply;
@@ -224,6 +242,18 @@
reply->writeInt32(f);
reply->writeInt32(res);
} break;
+ case TURN_ELECTRON_BEAM_OFF: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ int32_t mode = data.readInt32();
+ status_t res = turnElectronBeamOff(mode);
+ reply->writeInt32(res);
+ }
+ case TURN_ELECTRON_BEAM_ON: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ int32_t mode = data.readInt32();
+ status_t res = turnElectronBeamOn(mode);
+ reply->writeInt32(res);
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index c0be3a0..944731d 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -439,11 +439,10 @@
// Since mFDs[0] is used for inotify, we process regular events starting at index 1.
mInputDeviceIndex += 1;
if (mInputDeviceIndex >= mFDCount) {
- mInputDeviceIndex = 0;
break;
}
- const struct pollfd &pfd = mFDs[mInputDeviceIndex];
+ const struct pollfd& pfd = mFDs[mInputDeviceIndex];
if (pfd.revents & POLLIN) {
int32_t readSize = read(pfd.fd, mInputBufferData,
sizeof(struct input_event) * INPUT_BUFFER_SIZE);
@@ -460,11 +459,17 @@
}
}
+#if HAVE_INOTIFY
// readNotify() will modify mFDs and mFDCount, so this must be done after
// processing all other events.
if(mFDs[0].revents & POLLIN) {
readNotify(mFDs[0].fd);
+ mFDs[0].revents = 0;
+ continue; // report added or removed devices immediately
}
+#endif
+
+ mInputDeviceIndex = 0;
// Poll for events. Mind the wake lock dance!
// We hold a wake lock at all times except during poll(). This works due to some
@@ -482,7 +487,7 @@
if (pollResult <= 0) {
if (errno != EINTR) {
- LOGW("select failed (errno=%d)\n", errno);
+ LOGW("poll failed (errno=%d)\n", errno);
usleep(100000);
}
}
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
index e170ab8..2c3724c 100644
--- a/libs/utils/ObbFile.cpp
+++ b/libs/utils/ObbFile.cpp
@@ -29,10 +29,11 @@
#define kFooterTagSize 8 /* last two 32-bit integers */
-#define kFooterMinSize 25 /* 32-bit signature version (4 bytes)
+#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)
* 32-bit package version (4 bytes)
* 32-bit flags (4 bytes)
- * 32-bit package name size (4-bytes)
+ * 64-bit salt (8 bytes)
+ * 32-bit package name size (4 bytes)
* >=1-character package name (1 byte)
* 32-bit footer size (4 bytes)
* 32-bit footer marker (4 bytes)
@@ -47,8 +48,9 @@
/* offsets in version 1 of the header */
#define kPackageVersionOffset 4
#define kFlagsOffset 8
-#define kPackageNameLenOffset 12
-#define kPackageNameOffset 16
+#define kSaltOffset 12
+#define kPackageNameLenOffset 20
+#define kPackageNameOffset 24
/*
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
@@ -79,11 +81,12 @@
namespace android {
-ObbFile::ObbFile() :
- mPackageName(""),
- mVersion(-1),
- mFlags(0)
+ObbFile::ObbFile()
+ : mPackageName("")
+ , mVersion(-1)
+ , mFlags(0)
{
+ memset(mSalt, 0, sizeof(mSalt));
}
ObbFile::~ObbFile() {
@@ -192,7 +195,7 @@
#ifdef DEBUG
for (int i = 0; i < footerSize; ++i) {
- LOGI("char: 0x%02x", scanBuf[i]);
+ LOGI("char: 0x%02x\n", scanBuf[i]);
}
#endif
@@ -206,6 +209,8 @@
mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
+ memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
+
uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
if (packageNameLen <= 0
|| packageNameLen > (footerSize - kPackageNameOffset)) {
@@ -255,7 +260,7 @@
my_lseek64(fd, 0, SEEK_END);
if (mPackageName.size() == 0 || mVersion == -1) {
- LOGW("tried to write uninitialized ObbFile data");
+ LOGW("tried to write uninitialized ObbFile data\n");
return false;
}
@@ -264,43 +269,48 @@
put4LE(intBuf, kSigVersion);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- LOGW("couldn't write signature version: %s", strerror(errno));
+ LOGW("couldn't write signature version: %s\n", strerror(errno));
return false;
}
put4LE(intBuf, mVersion);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- LOGW("couldn't write package version");
+ LOGW("couldn't write package version\n");
return false;
}
put4LE(intBuf, mFlags);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- LOGW("couldn't write package version");
+ LOGW("couldn't write package version\n");
+ return false;
+ }
+
+ if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
+ LOGW("couldn't write salt: %s\n", strerror(errno));
return false;
}
size_t packageNameLen = mPackageName.size();
put4LE(intBuf, packageNameLen);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- LOGW("couldn't write package name length: %s", strerror(errno));
+ LOGW("couldn't write package name length: %s\n", strerror(errno));
return false;
}
if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
- LOGW("couldn't write package name: %s", strerror(errno));
+ LOGW("couldn't write package name: %s\n", strerror(errno));
return false;
}
put4LE(intBuf, kPackageNameOffset + packageNameLen);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- LOGW("couldn't write footer size: %s", strerror(errno));
+ LOGW("couldn't write footer size: %s\n", strerror(errno));
return false;
}
put4LE(intBuf, kSignature);
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
- LOGW("couldn't write footer magic signature: %s", strerror(errno));
+ LOGW("couldn't write footer magic signature: %s\n", strerror(errno));
return false;
}
diff --git a/libs/utils/tests/ObbFile_test.cpp b/libs/utils/tests/ObbFile_test.cpp
index 29bb70a..46b30c2 100644
--- a/libs/utils/tests/ObbFile_test.cpp
+++ b/libs/utils/tests/ObbFile_test.cpp
@@ -23,6 +23,7 @@
#include <gtest/gtest.h>
#include <fcntl.h>
+#include <string.h>
namespace android {
@@ -63,6 +64,10 @@
mObbFile->setPackageName(String8(packageName));
mObbFile->setVersion(versionNum);
+#define SALT_SIZE 8
+ unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};
+ EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))
+ << "Salt should be successfully set";
EXPECT_TRUE(mObbFile->writeTo(mFileName))
<< "couldn't write to fake .obb file";
@@ -77,6 +82,19 @@
const char* currentPackageName = mObbFile->getPackageName().string();
EXPECT_STREQ(packageName, currentPackageName)
<< "package name didn't come out the same as it went in";
+
+ size_t saltLen;
+ const unsigned char* newSalt = mObbFile->getSalt(&saltLen);
+
+ EXPECT_EQ(sizeof(salt), saltLen)
+ << "salt sizes were not the same";
+
+ for (int i = 0; i < sizeof(salt); i++) {
+ EXPECT_EQ(salt[i], newSalt[i])
+ << "salt character " << i << " should be equal";
+ }
+ EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)
+ << "salts should be the same";
}
}
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 34a86ec..b38124e 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -191,6 +191,9 @@
/** @hide Stream over a socket, limited to a single stream */
public static final int OUTPUT_FORMAT_RTP_AVP = 7;
+
+ /** @hide H.264/AAC data encapsulated in MPEG2/TS */
+ public static final int OUTPUT_FORMAT_MPEG2TS = 8;
};
/**
diff --git a/media/libmedia/Metadata.cpp b/media/libmedia/Metadata.cpp
index 35ec6b3..aec96f1 100644
--- a/media/libmedia/Metadata.cpp
+++ b/media/libmedia/Metadata.cpp
@@ -32,7 +32,7 @@
// All these constants below must be kept in sync with Metadata.java.
enum MetadataId {
FIRST_SYSTEM_ID = 1,
- LAST_SYSTEM_ID = 31,
+ LAST_SYSTEM_ID = 32,
FIRST_CUSTOM_ID = 8192
};
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 9d53c25..e20e3ba 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -181,7 +181,7 @@
LOGE("setOutputFormat called in an invalid state: %d", mCurrentState);
return INVALID_OPERATION;
}
- if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP) { //first non-video output format
+ if (mIsVideoSourceSet && of >= OUTPUT_FORMAT_AUDIO_ONLY_START && of != OUTPUT_FORMAT_RTP_AVP && of != OUTPUT_FORMAT_MPEG2TS) { //first non-video output format
LOGE("output format (%d) is meant for audio recording only and incompatible with video recording", of);
return INVALID_OPERATION;
}
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index cf01ff6..d37d83d 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -24,6 +24,7 @@
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/AMRWriter.h>
#include <media/stagefright/CameraSource.h>
+#include <media/stagefright/MPEG2TSWriter.h>
#include <media/stagefright/MPEG4Writer.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
@@ -632,6 +633,9 @@
case OUTPUT_FORMAT_RTP_AVP:
return startRTPRecording();
+ case OUTPUT_FORMAT_MPEG2TS:
+ return startMPEG2TSRecording();
+
default:
LOGE("Unsupported output file format: %d", mOutputFormat);
return UNKNOWN_ERROR;
@@ -799,6 +803,52 @@
return mWriter->start();
}
+status_t StagefrightRecorder::startMPEG2TSRecording() {
+ CHECK_EQ(mOutputFormat, OUTPUT_FORMAT_MPEG2TS);
+
+ sp<MediaWriter> writer = new MPEG2TSWriter(dup(mOutputFd));
+
+ if (mAudioSource != AUDIO_SOURCE_LIST_END) {
+ if (mAudioEncoder != AUDIO_ENCODER_AAC) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ status_t err = setupAudioEncoder(writer);
+
+ if (err != OK) {
+ return err;
+ }
+ }
+
+ if (mVideoSource == VIDEO_SOURCE_DEFAULT
+ || mVideoSource == VIDEO_SOURCE_CAMERA) {
+ if (mVideoEncoder != VIDEO_ENCODER_H264) {
+ return ERROR_UNSUPPORTED;
+ }
+
+ sp<MediaSource> encoder;
+ status_t err = setupVideoEncoder(&encoder);
+
+ if (err != OK) {
+ return err;
+ }
+
+ writer->addSource(encoder);
+ }
+
+ if (mMaxFileDurationUs != 0) {
+ writer->setMaxFileDuration(mMaxFileDurationUs);
+ }
+
+ if (mMaxFileSizeBytes != 0) {
+ writer->setMaxFileSize(mMaxFileSizeBytes);
+ }
+
+ mWriter = writer;
+
+ return mWriter->start();
+}
+
void StagefrightRecorder::clipVideoFrameRate() {
LOGV("clipVideoFrameRate: encoder %d", mVideoEncoder);
int minFrameRate = mEncoderProfiles->getVideoEncoderParamByName(
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 216f6bc..ad0dfa0 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -102,6 +102,7 @@
status_t startAMRRecording();
status_t startAACRecording();
status_t startRTPRecording();
+ status_t startMPEG2TSRecording();
sp<MediaSource> createAudioSource();
status_t setupCameraSource();
status_t setupAudioEncoder(const sp<MediaWriter>& writer);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index ff28f3b..57bea8c 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -26,6 +26,7 @@
#include "include/SoftwareRenderer.h"
#include "include/NuCachedSource2.h"
#include "include/ThrottledSource.h"
+#include "include/MPEG2TSExtractor.h"
#include "ARTPSession.h"
#include "APacketSource.h"
@@ -302,6 +303,28 @@
}
status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
+ // Attempt to approximate overall stream bitrate by summing all
+ // tracks' individual bitrates, if not all of them advertise bitrate,
+ // we have to fail.
+
+ int64_t totalBitRate = 0;
+
+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
+ sp<MetaData> meta = extractor->getTrackMetaData(i);
+
+ int32_t bitrate;
+ if (!meta->findInt32(kKeyBitRate, &bitrate)) {
+ totalBitRate = -1;
+ break;
+ }
+
+ totalBitRate += bitrate;
+ }
+
+ mBitrate = totalBitRate;
+
+ LOGV("mBitrate = %lld bits/sec", mBitrate);
+
bool haveAudio = false;
bool haveVideo = false;
for (size_t i = 0; i < extractor->countTracks(); ++i) {
@@ -440,6 +463,8 @@
delete mSuspensionState;
mSuspensionState = NULL;
+
+ mBitrate = -1;
}
void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
@@ -452,17 +477,32 @@
}
}
+bool AwesomePlayer::getBitrate(int64_t *bitrate) {
+ off_t size;
+ if (mDurationUs >= 0 && mCachedSource != NULL
+ && mCachedSource->getSize(&size) == OK) {
+ *bitrate = size * 8000000ll / mDurationUs; // in bits/sec
+ return true;
+ }
+
+ if (mBitrate >= 0) {
+ *bitrate = mBitrate;
+ return true;
+ }
+
+ *bitrate = 0;
+
+ return false;
+}
+
// Returns true iff cached duration is available/applicable.
bool AwesomePlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
- off_t totalSize;
+ int64_t bitrate;
if (mRTSPController != NULL) {
*durationUs = mRTSPController->getQueueDurationUs(eos);
return true;
- } else if (mCachedSource != NULL && mDurationUs >= 0
- && mCachedSource->getSize(&totalSize) == OK) {
- int64_t bitrate = totalSize * 8000000ll / mDurationUs; // in bits/sec
-
+ } else if (mCachedSource != NULL && getBitrate(&bitrate)) {
size_t cachedDataRemaining = mCachedSource->approxDataRemaining(eos);
*durationUs = cachedDataRemaining * 8000000ll / bitrate;
return true;
@@ -489,10 +529,8 @@
finishAsyncPrepare_l();
}
} else {
- off_t size;
- if (mDurationUs >= 0 && mCachedSource->getSize(&size) == OK) {
- int64_t bitrate = size * 8000000ll / mDurationUs; // in bits/sec
-
+ int64_t bitrate;
+ if (getBitrate(&bitrate)) {
size_t cachedSize = mCachedSource->cachedSize();
int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
@@ -506,8 +544,8 @@
// We don't know the bitrate of the stream, use absolute size
// limits to maintain the cache.
- const size_t kLowWaterMarkBytes = 400000;
- const size_t kHighWaterMarkBytes = 1000000;
+ const size_t kLowWaterMarkBytes = 40000;
+ const size_t kHighWaterMarkBytes = 200000;
if ((mFlags & PLAYING) && !eos
&& (cachedDataRemaining < kLowWaterMarkBytes)) {
@@ -1343,14 +1381,17 @@
String8 uri("http://");
uri.append(mUri.string() + 11);
- dataSource = new LiveSource(uri.string());
+ sp<LiveSource> liveSource = new LiveSource(uri.string());
- mCachedSource = new NuCachedSource2(dataSource);
+ mCachedSource = new NuCachedSource2(liveSource);
dataSource = mCachedSource;
sp<MediaExtractor> extractor =
MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
+ static_cast<MPEG2TSExtractor *>(extractor.get())
+ ->setLiveSource(liveSource);
+
return setDataSource_l(extractor);
} else if (!strncmp("rtsp://gtalk/", mUri.string(), 13)) {
if (mLooper == NULL) {
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index ee74b88..b3daf67 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -63,6 +63,8 @@
sp<ALooper> mLooper;
sp<AMessage> mNotify;
+ sp<ABuffer> mAACCodecSpecificData;
+
sp<ABuffer> mAACBuffer;
unsigned mStreamType;
@@ -125,6 +127,8 @@
void MPEG2TSWriter::SourceInfo::stop() {
mLooper->unregisterHandler(id());
mLooper->stop();
+
+ mSource->stop();
}
void MPEG2TSWriter::SourceInfo::extractCodecSpecificData() {
@@ -133,18 +137,48 @@
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
+ uint32_t type;
+ const void *data;
+ size_t size;
+ if (!meta->findData(kKeyESDS, &type, &data, &size)) {
+ // Codec specific data better be in the first data buffer.
+ return;
+ }
+
+ ESDS esds((const char *)data, size);
+ CHECK_EQ(esds.InitCheck(), (status_t)OK);
+
+ const uint8_t *codec_specific_data;
+ size_t codec_specific_data_size;
+ esds.getCodecSpecificInfo(
+ (const void **)&codec_specific_data, &codec_specific_data_size);
+
+ CHECK_GE(codec_specific_data_size, 2u);
+
+ mAACCodecSpecificData = new ABuffer(codec_specific_data_size);
+
+ memcpy(mAACCodecSpecificData->data(), codec_specific_data,
+ codec_specific_data_size);
+
+ return;
+ }
+
if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
return;
}
+ uint32_t type;
+ const void *data;
+ size_t size;
+ if (!meta->findData(kKeyAVCC, &type, &data, &size)) {
+ // Codec specific data better be part of the data stream then.
+ return;
+ }
+
sp<ABuffer> out = new ABuffer(1024);
out->setRange(0, 0);
- uint32_t type;
- const void *data;
- size_t size;
- CHECK(meta->findData(kKeyAVCC, &type, &data, &size));
-
const uint8_t *ptr = (const uint8_t *)data;
size_t numSeqParameterSets = ptr[5] & 31;
@@ -250,21 +284,7 @@
mAACBuffer->setRange(0, 0);
}
- sp<MetaData> meta = mSource->getFormat();
- uint32_t type;
- const void *data;
- size_t size;
- CHECK(meta->findData(kKeyESDS, &type, &data, &size));
-
- ESDS esds((const char *)data, size);
- CHECK_EQ(esds.InitCheck(), (status_t)OK);
-
- const uint8_t *codec_specific_data;
- size_t codec_specific_data_size;
- esds.getCodecSpecificInfo(
- (const void **)&codec_specific_data, &codec_specific_data_size);
-
- CHECK_GE(codec_specific_data_size, 2u);
+ const uint8_t *codec_specific_data = mAACCodecSpecificData->data();
unsigned profile = (codec_specific_data[0] >> 3) - 1;
@@ -355,7 +375,18 @@
}
if (err == OK) {
- if (buffer->range_length() > 0) {
+ if (mStreamType == 0x0f && mAACCodecSpecificData == NULL) {
+ // The first buffer contains codec specific data.
+
+ CHECK_GE(buffer->range_length(), 2u);
+
+ mAACCodecSpecificData = new ABuffer(buffer->range_length());
+
+ memcpy(mAACCodecSpecificData->data(),
+ (const uint8_t *)buffer->data()
+ + buffer->range_offset(),
+ buffer->range_length());
+ } else if (buffer->range_length() > 0) {
if (mStreamType == 0x0f) {
appendAACFrames(buffer);
} else {
@@ -378,12 +409,25 @@
////////////////////////////////////////////////////////////////////////////////
+MPEG2TSWriter::MPEG2TSWriter(int fd)
+ : mFile(fdopen(fd, "wb")),
+ mStarted(false),
+ mNumSourcesDone(0),
+ mNumTSPacketsWritten(0),
+ mNumTSPacketsBeforeMeta(0) {
+ init();
+}
+
MPEG2TSWriter::MPEG2TSWriter(const char *filename)
: mFile(fopen(filename, "wb")),
mStarted(false),
mNumSourcesDone(0),
mNumTSPacketsWritten(0),
mNumTSPacketsBeforeMeta(0) {
+ init();
+}
+
+void MPEG2TSWriter::init() {
CHECK(mFile != NULL);
mLooper = new ALooper;
@@ -396,6 +440,10 @@
}
MPEG2TSWriter::~MPEG2TSWriter() {
+ if (mStarted) {
+ stop();
+ }
+
mLooper->unregisterHandler(mReflector->id());
mLooper->stop();
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 3a0fc41..b67002d 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -179,7 +179,8 @@
mFinalStatus(OK),
mLastAccessPos(0),
mFetching(true),
- mLastFetchTimeUs(-1) {
+ mLastFetchTimeUs(-1),
+ mSuspended(false) {
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
mLooper->start();
@@ -205,7 +206,7 @@
}
uint32_t NuCachedSource2::flags() {
- return mSource->flags();
+ return (mSource->flags() & ~kWantsPrefetching) | kIsCachingDataSource;
}
void NuCachedSource2::onMessageReceived(const sp<AMessage> &msg) {
@@ -222,6 +223,12 @@
break;
}
+ case kWhatSuspend:
+ {
+ onSuspend();
+ break;
+ }
+
default:
TRESPASS();
}
@@ -263,6 +270,7 @@
bool keepAlive =
!mFetching
+ && !mSuspended
&& mFinalStatus == OK
&& ALooper::GetNowUs() >= mLastFetchTimeUs + kKeepAliveIntervalUs;
@@ -279,7 +287,7 @@
LOGI("Cache full, done prefetching for now");
mFetching = false;
}
- } else {
+ } else if (!mSuspended) {
Mutex::Autolock autoLock(mLock);
restartPrefetcherIfNecessary_l();
}
@@ -468,5 +476,39 @@
return OK;
}
+void NuCachedSource2::clearCacheAndResume() {
+ LOGV("clearCacheAndResume");
+
+ Mutex::Autolock autoLock(mLock);
+
+ CHECK(mSuspended);
+
+ mCacheOffset = 0;
+ mFinalStatus = OK;
+ mLastAccessPos = 0;
+ mLastFetchTimeUs = -1;
+
+ size_t totalSize = mCache->totalSize();
+ CHECK_EQ(mCache->releaseFromStart(totalSize), totalSize);
+
+ mFetching = true;
+ mSuspended = false;
+}
+
+void NuCachedSource2::suspend() {
+ (new AMessage(kWhatSuspend, mReflector->id()))->post();
+
+ while (!mSuspended) {
+ usleep(10000);
+ }
+}
+
+void NuCachedSource2::onSuspend() {
+ Mutex::Autolock autoLock(mLock);
+
+ mFetching = false;
+ mSuspended = true;
+}
+
} // namespace android
diff --git a/media/libstagefright/httplive/LiveSource.cpp b/media/libstagefright/httplive/LiveSource.cpp
index 943a0fc..4124571 100644
--- a/media/libstagefright/httplive/LiveSource.cpp
+++ b/media/libstagefright/httplive/LiveSource.cpp
@@ -31,6 +31,7 @@
LiveSource::LiveSource(const char *url)
: mMasterURL(url),
mInitCheck(NO_INIT),
+ mDurationUs(-1),
mPlaylistIndex(0),
mLastFetchTimeUs(-1),
mSource(new NuHTTPDataSource),
@@ -40,6 +41,8 @@
mPrevBandwidthIndex(-1) {
if (switchToNext()) {
mInitCheck = OK;
+
+ determineSeekability();
}
}
@@ -139,7 +142,7 @@
}
#else
// Stay on the lowest bandwidth available.
- size_t index = 0; // Lowest bandwidth stream
+ size_t index = mBandwidthItems.size() - 1; // Highest bandwidth stream
#endif
mURL = mBandwidthItems.editItemAt(index).mURI;
@@ -336,4 +339,69 @@
return OK;
}
+bool LiveSource::seekTo(int64_t seekTimeUs) {
+ LOGV("seek to %lld us", seekTimeUs);
+
+ if (!mPlaylist->isComplete()) {
+ return false;
+ }
+
+ int32_t targetDuration;
+ if (!mPlaylist->meta()->findInt32("target-duration", &targetDuration)) {
+ return false;
+ }
+
+ int64_t seekTimeSecs = (seekTimeUs + 500000ll) / 1000000ll;
+
+ int64_t index = seekTimeSecs / targetDuration;
+
+ if (index < 0 || index >= mPlaylist->size()) {
+ return false;
+ }
+
+ size_t newPlaylistIndex = mFirstItemSequenceNumber + index;
+
+ if (newPlaylistIndex == mPlaylistIndex) {
+ return false;
+ }
+
+ mPlaylistIndex = newPlaylistIndex;
+
+ switchToNext();
+ mOffsetBias = 0;
+
+ LOGV("seeking to index %lld", index);
+
+ return true;
+}
+
+bool LiveSource::getDuration(int64_t *durationUs) const {
+ if (mDurationUs >= 0) {
+ *durationUs = mDurationUs;
+ return true;
+ }
+
+ *durationUs = 0;
+ return false;
+}
+
+bool LiveSource::isSeekable() const {
+ return mDurationUs >= 0;
+}
+
+void LiveSource::determineSeekability() {
+ mDurationUs = -1;
+
+ if (!mPlaylist->isComplete()) {
+ return;
+ }
+
+ int32_t targetDuration;
+ if (!mPlaylist->meta()->findInt32("target-duration", &targetDuration)) {
+ return;
+ }
+
+ mDurationUs = targetDuration * 1000000ll * mPlaylist->size();
+}
+
} // namespace android
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 0d7daa9..a68c641 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -27,7 +27,8 @@
: mInitCheck(NO_INIT),
mBaseURI(baseURI),
mIsExtM3U(false),
- mIsVariantPlaylist(false) {
+ mIsVariantPlaylist(false),
+ mIsComplete(false) {
mInitCheck = parse(data, size);
}
@@ -46,6 +47,10 @@
return mIsVariantPlaylist;
}
+bool M3UParser::isComplete() const {
+ return mIsComplete;
+}
+
sp<AMessage> M3UParser::meta() {
return mMeta;
}
@@ -153,6 +158,8 @@
return ERROR_MALFORMED;
}
err = parseMetaData(line, &mMeta, "media-sequence");
+ } else if (line.startsWith("#EXT-X-ENDLIST")) {
+ mIsComplete = true;
} else if (line.startsWith("#EXTINF")) {
if (mIsVariantPlaylist) {
return ERROR_MALFORMED;
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 079adca..46a0c65 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -152,6 +152,8 @@
bool mSeekNotificationSent;
int64_t mSeekTimeUs;
+ int64_t mBitrate; // total bitrate of the file (in bps) or -1 if unknown.
+
bool mWatchForAudioSeekComplete;
bool mWatchForAudioEOS;
@@ -254,6 +256,8 @@
static void OnRTSPSeekDoneWrapper(void *cookie);
void onRTSPSeekDone();
+ bool getBitrate(int64_t *bitrate);
+
AwesomePlayer(const AwesomePlayer &);
AwesomePlayer &operator=(const AwesomePlayer &);
};
diff --git a/media/libstagefright/include/LiveSource.h b/media/libstagefright/include/LiveSource.h
index 5e89581..55dd45e 100644
--- a/media/libstagefright/include/LiveSource.h
+++ b/media/libstagefright/include/LiveSource.h
@@ -40,6 +40,11 @@
return kWantsPrefetching;
}
+ bool getDuration(int64_t *durationUs) const;
+
+ bool isSeekable() const;
+ bool seekTo(int64_t seekTimeUs);
+
protected:
virtual ~LiveSource();
@@ -53,6 +58,7 @@
AString mMasterURL;
AString mURL;
status_t mInitCheck;
+ int64_t mDurationUs;
sp<M3UParser> mPlaylist;
int32_t mFirstItemSequenceNumber;
@@ -72,6 +78,7 @@
bool switchToNext();
bool loadPlaylist(bool fetchMaster);
+ void determineSeekability();
DISALLOW_EVIL_CONSTRUCTORS(LiveSource);
};
diff --git a/media/libstagefright/include/M3UParser.h b/media/libstagefright/include/M3UParser.h
index 69199ab..bd9eebe 100644
--- a/media/libstagefright/include/M3UParser.h
+++ b/media/libstagefright/include/M3UParser.h
@@ -32,6 +32,7 @@
bool isExtM3U() const;
bool isVariantPlaylist() const;
+ bool isComplete() const;
sp<AMessage> meta();
@@ -52,6 +53,7 @@
AString mBaseURI;
bool mIsExtM3U;
bool mIsVariantPlaylist;
+ bool mIsComplete;
sp<AMessage> mMeta;
Vector<Item> mItems;
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index 1bf4cd1..d83b538 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -15,6 +15,7 @@
struct DataSource;
struct MPEG2TSSource;
struct String8;
+struct LiveSource;
struct MPEG2TSExtractor : public MediaExtractor {
MPEG2TSExtractor(const sp<DataSource> &source);
@@ -25,16 +26,19 @@
virtual sp<MetaData> getMetaData();
- virtual uint32_t flags() const {
- return CAN_PAUSE;
- }
+ virtual uint32_t flags() const;
+
+ void setLiveSource(const sp<LiveSource> &liveSource);
+ void seekTo(int64_t seekTimeUs);
private:
friend struct MPEG2TSSource;
- Mutex mLock;
+ mutable Mutex mLock;
sp<DataSource> mDataSource;
+ sp<LiveSource> mLiveSource;
+
sp<ATSParser> mParser;
Vector<sp<AnotherPacketSource> > mSourceImpls;
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 3a20c16..1fb2088 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -42,6 +42,9 @@
size_t cachedSize();
size_t approxDataRemaining(bool *eos);
+ void suspend();
+ void clearCacheAndResume();
+
protected:
virtual ~NuCachedSource2();
@@ -61,6 +64,7 @@
enum {
kWhatFetchMore = 'fetc',
kWhatRead = 'read',
+ kWhatSuspend = 'susp',
};
sp<DataSource> mSource;
@@ -78,10 +82,12 @@
sp<AMessage> mAsyncResult;
bool mFetching;
int64_t mLastFetchTimeUs;
+ bool mSuspended;
void onMessageReceived(const sp<AMessage> &msg);
void onFetch();
void onRead(const sp<AMessage> &msg);
+ void onSuspend();
void fetchInternal();
ssize_t readInternal(off_t offset, void *data, size_t size);
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 7c9b83a..c88c6c1 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -49,13 +49,17 @@
unsigned pid, unsigned payload_unit_start_indicator,
ABitReader *br);
- void signalDiscontinuity();
+ void signalDiscontinuity(bool isASeek);
sp<MediaSource> getSource(SourceType type);
+ int64_t convertPTSToTimestamp(uint64_t PTS);
+
private:
unsigned mProgramMapPID;
KeyedVector<unsigned, sp<Stream> > mStreams;
+ bool mFirstPTSValid;
+ uint64_t mFirstPTS;
void parseProgramMap(ABitReader *br);
@@ -63,13 +67,13 @@
};
struct ATSParser::Stream : public RefBase {
- Stream(unsigned elementaryPID, unsigned streamType);
+ Stream(Program *program, unsigned elementaryPID, unsigned streamType);
void parse(
unsigned payload_unit_start_indicator,
ABitReader *br);
- void signalDiscontinuity();
+ void signalDiscontinuity(bool isASeek);
sp<MediaSource> getSource(SourceType type);
@@ -77,6 +81,7 @@
virtual ~Stream();
private:
+ Program *mProgram;
unsigned mElementaryPID;
unsigned mStreamType;
@@ -101,7 +106,9 @@
////////////////////////////////////////////////////////////////////////////////
ATSParser::Program::Program(unsigned programMapPID)
- : mProgramMapPID(programMapPID) {
+ : mProgramMapPID(programMapPID),
+ mFirstPTSValid(false),
+ mFirstPTS(0) {
}
bool ATSParser::Program::parsePID(
@@ -128,9 +135,9 @@
return true;
}
-void ATSParser::Program::signalDiscontinuity() {
+void ATSParser::Program::signalDiscontinuity(bool isASeek) {
for (size_t i = 0; i < mStreams.size(); ++i) {
- mStreams.editValueAt(i)->signalDiscontinuity();
+ mStreams.editValueAt(i)->signalDiscontinuity(isASeek);
}
}
@@ -213,10 +220,12 @@
ssize_t index = mStreams.indexOfKey(elementaryPID);
#if 0 // XXX revisit
CHECK_LT(index, 0);
- mStreams.add(elementaryPID, new Stream(elementaryPID, streamType));
+ mStreams.add(elementaryPID,
+ new Stream(this, elementaryPID, streamType));
#else
if (index < 0) {
- mStreams.add(elementaryPID, new Stream(elementaryPID, streamType));
+ mStreams.add(elementaryPID,
+ new Stream(this, elementaryPID, streamType));
}
#endif
@@ -239,10 +248,26 @@
return NULL;
}
+int64_t ATSParser::Program::convertPTSToTimestamp(uint64_t PTS) {
+ if (!mFirstPTSValid) {
+ mFirstPTSValid = true;
+ mFirstPTS = PTS;
+ PTS = 0;
+ } else if (PTS < mFirstPTS) {
+ PTS = 0;
+ } else {
+ PTS -= mFirstPTS;
+ }
+
+ return (PTS * 100) / 9;
+}
+
////////////////////////////////////////////////////////////////////////////////
-ATSParser::Stream::Stream(unsigned elementaryPID, unsigned streamType)
- : mElementaryPID(elementaryPID),
+ATSParser::Stream::Stream(
+ Program *program, unsigned elementaryPID, unsigned streamType)
+ : mProgram(program),
+ mElementaryPID(elementaryPID),
mStreamType(streamType),
mBuffer(new ABuffer(128 * 1024)),
mPayloadStarted(false),
@@ -281,13 +306,21 @@
mBuffer->setRange(0, mBuffer->size() + payloadSizeBits / 8);
}
-void ATSParser::Stream::signalDiscontinuity() {
+void ATSParser::Stream::signalDiscontinuity(bool isASeek) {
LOGV("Stream discontinuity");
mPayloadStarted = false;
mBuffer->setRange(0, 0);
mQueue.clear();
+ if (isASeek) {
+ // This is only a "minor" discontinuity, we stay within the same
+ // bitstream.
+
+ mSource->clear();
+ return;
+ }
+
if (mStreamType == 0x1b && mSource != NULL) {
// Don't signal discontinuities on audio streams.
mSource->queueDiscontinuity();
@@ -467,7 +500,7 @@
LOGV("onPayloadData mStreamType=0x%02x", mStreamType);
CHECK(PTS_DTS_flags == 2 || PTS_DTS_flags == 3);
- int64_t timeUs = (PTS * 100) / 9;
+ int64_t timeUs = mProgram->convertPTSToTimestamp(PTS);
status_t err = mQueue.appendData(data, size, timeUs);
CHECK_EQ(err, (status_t)OK);
@@ -515,9 +548,9 @@
parseTS(&br);
}
-void ATSParser::signalDiscontinuity() {
+void ATSParser::signalDiscontinuity(bool isASeek) {
for (size_t i = 0; i < mPrograms.size(); ++i) {
- mPrograms.editItemAt(i)->signalDiscontinuity();
+ mPrograms.editItemAt(i)->signalDiscontinuity(isASeek);
}
}
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 9ec6d7b..11b1de4 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -33,7 +33,7 @@
ATSParser();
void feedTSPacket(const void *data, size_t size);
- void signalDiscontinuity();
+ void signalDiscontinuity(bool isASeek = false);
enum SourceType {
AVC_VIDEO,
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 3f76820..ea747c8 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -91,6 +91,10 @@
return;
}
+ int64_t timeUs;
+ CHECK(buffer->meta()->findInt64("time", &timeUs));
+ LOGV("queueAccessUnit timeUs=%lld us (%.2f secs)", timeUs, timeUs / 1E6);
+
Mutex::Autolock autoLock(mLock);
mBuffers.push_back(buffer);
mCondition.signal();
@@ -101,10 +105,17 @@
buffer->meta()->setInt32("discontinuity", true);
Mutex::Autolock autoLock(mLock);
+
mBuffers.push_back(buffer);
mCondition.signal();
}
+void AnotherPacketSource::clear() {
+ Mutex::Autolock autoLock(mLock);
+ mBuffers.clear();
+ mEOSResult = OK;
+}
+
void AnotherPacketSource::signalEOS(status_t result) {
CHECK(result != OK);
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index 6b43c4e..6999175 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -43,6 +43,8 @@
void queueDiscontinuity();
void signalEOS(status_t result);
+ void clear();
+
protected:
virtual ~AnotherPacketSource();
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index a13287e..b0b9e66 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -42,6 +42,7 @@
void ElementaryStreamQueue::clear() {
mBuffer->setRange(0, 0);
+ mTimestamps.clear();
mFormat.clear();
}
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index 0d96bd1..3176810 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -19,8 +19,11 @@
#include <utils/Log.h>
#include "include/MPEG2TSExtractor.h"
+#include "include/LiveSource.h"
+#include "include/NuCachedSource2.h"
#include <media/stagefright/DataSource.h>
+#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaSource.h>
@@ -37,7 +40,8 @@
struct MPEG2TSSource : public MediaSource {
MPEG2TSSource(
const sp<MPEG2TSExtractor> &extractor,
- const sp<AnotherPacketSource> &impl);
+ const sp<AnotherPacketSource> &impl,
+ bool seekable);
virtual status_t start(MetaData *params = NULL);
virtual status_t stop();
@@ -50,14 +54,20 @@
sp<MPEG2TSExtractor> mExtractor;
sp<AnotherPacketSource> mImpl;
+ // If there are both audio and video streams, only the video stream
+ // will be seekable, otherwise the single stream will be seekable.
+ bool mSeekable;
+
DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSSource);
};
MPEG2TSSource::MPEG2TSSource(
const sp<MPEG2TSExtractor> &extractor,
- const sp<AnotherPacketSource> &impl)
+ const sp<AnotherPacketSource> &impl,
+ bool seekable)
: mExtractor(extractor),
- mImpl(impl) {
+ mImpl(impl),
+ mSeekable(seekable) {
}
status_t MPEG2TSSource::start(MetaData *params) {
@@ -69,13 +79,27 @@
}
sp<MetaData> MPEG2TSSource::getFormat() {
- return mImpl->getFormat();
+ sp<MetaData> meta = mImpl->getFormat();
+
+ int64_t durationUs;
+ if (mExtractor->mLiveSource != NULL
+ && mExtractor->mLiveSource->getDuration(&durationUs)) {
+ meta->setInt64(kKeyDuration, durationUs);
+ }
+
+ return meta;
}
status_t MPEG2TSSource::read(
MediaBuffer **out, const ReadOptions *options) {
*out = NULL;
+ int64_t seekTimeUs;
+ ReadOptions::SeekMode seekMode;
+ if (mSeekable && options && options->getSeekTo(&seekTimeUs, &seekMode)) {
+ mExtractor->seekTo(seekTimeUs);
+ }
+
status_t finalResult;
while (!mImpl->hasBufferAvailable(&finalResult)) {
if (finalResult != OK) {
@@ -109,7 +133,20 @@
return NULL;
}
- return new MPEG2TSSource(this, mSourceImpls.editItemAt(index));
+ bool seekable = true;
+ if (mSourceImpls.size() > 1) {
+ CHECK_EQ(mSourceImpls.size(), 2u);
+
+ sp<MetaData> meta = mSourceImpls.editItemAt(index)->getFormat();
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+ if (!strncasecmp("audio/", mime, 6)) {
+ seekable = false;
+ }
+ }
+
+ return new MPEG2TSSource(this, mSourceImpls.editItemAt(index), seekable);
}
sp<MetaData> MPEG2TSExtractor::getTrackMetaData(
@@ -189,6 +226,46 @@
return OK;
}
+void MPEG2TSExtractor::setLiveSource(const sp<LiveSource> &liveSource) {
+ Mutex::Autolock autoLock(mLock);
+
+ mLiveSource = liveSource;
+}
+
+void MPEG2TSExtractor::seekTo(int64_t seekTimeUs) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mLiveSource == NULL) {
+ return;
+ }
+
+ if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
+ static_cast<NuCachedSource2 *>(mDataSource.get())->suspend();
+ }
+
+ if (mLiveSource->seekTo(seekTimeUs)) {
+ mParser->signalDiscontinuity(true /* isSeek */);
+ mOffset = 0;
+ }
+
+ if (mDataSource->flags() & DataSource::kIsCachingDataSource) {
+ static_cast<NuCachedSource2 *>(mDataSource.get())
+ ->clearCacheAndResume();
+ }
+}
+
+uint32_t MPEG2TSExtractor::flags() const {
+ Mutex::Autolock autoLock(mLock);
+
+ uint32_t flags = CAN_PAUSE;
+
+ if (mLiveSource != NULL && mLiveSource->isSeekable()) {
+ flags |= CAN_SEEK_FORWARD | CAN_SEEK_BACKWARD | CAN_SEEK;
+ }
+
+ return flags;
+}
+
////////////////////////////////////////////////////////////////////////////////
bool SniffMPEG2TS(
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index ded3b24..5a1ea5c 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -59,7 +59,8 @@
sp<AMessage> mNotifyMsg;
KeyedVector<uint32_t, sp<ARTPSource> > mSources;
- int32_t mNumRTCPPacketsReceived;
+ int64_t mNumRTCPPacketsReceived;
+ int64_t mNumRTPPacketsReceived;
struct sockaddr_in mRemoteRTCPAddr;
bool mIsInjected;
@@ -168,6 +169,12 @@
break;
}
+ case kWhatFakeTimestamps:
+ {
+ onFakeTimestamps();
+ break;
+ }
+
default:
{
TRESPASS();
@@ -199,6 +206,7 @@
CHECK(msg->findMessage("notify", &info->mNotifyMsg));
info->mNumRTCPPacketsReceived = 0;
+ info->mNumRTPPacketsReceived = 0;
memset(&info->mRemoteRTCPAddr, 0, sizeof(info->mRemoteRTCPAddr));
if (!injected) {
@@ -373,6 +381,12 @@
}
status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
+ if (s->mNumRTPPacketsReceived++ == 0) {
+ sp<AMessage> notify = s->mNotifyMsg->dup();
+ notify->setInt32("first-rtp", true);
+ notify->post();
+ }
+
size_t size = buffer->size();
if (size < 12) {
@@ -638,5 +652,27 @@
}
}
+void ARTPConnection::fakeTimestamps() {
+ (new AMessage(kWhatFakeTimestamps, id()))->post();
+}
+
+void ARTPConnection::onFakeTimestamps() {
+ List<StreamInfo>::iterator it = mStreams.begin();
+ while (it != mStreams.end()) {
+ StreamInfo &info = *it++;
+
+ for (size_t j = 0; j < info.mSources.size(); ++j) {
+ sp<ARTPSource> source = info.mSources.valueAt(j);
+
+ if (!source->timeEstablished()) {
+ source->timeUpdate(0, 0);
+ source->timeUpdate(0 + 90000, 0x100000000ll);
+
+ mFlags |= kFakeTimestamps;
+ }
+ }
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/rtsp/ARTPConnection.h b/media/libstagefright/rtsp/ARTPConnection.h
index 77f81fa..a17b382 100644
--- a/media/libstagefright/rtsp/ARTPConnection.h
+++ b/media/libstagefright/rtsp/ARTPConnection.h
@@ -51,6 +51,8 @@
static void MakePortPair(
int *rtpSocket, int *rtcpSocket, unsigned *rtpPort);
+ void fakeTimestamps();
+
protected:
virtual ~ARTPConnection();
virtual void onMessageReceived(const sp<AMessage> &msg);
@@ -61,6 +63,7 @@
kWhatRemoveStream,
kWhatPollStreams,
kWhatInjectPacket,
+ kWhatFakeTimestamps,
};
static const int64_t kSelectTimeoutUs;
@@ -78,6 +81,7 @@
void onPollStreams();
void onInjectPacket(const sp<AMessage> &msg);
void onSendReceiverReports();
+ void onFakeTimestamps();
status_t receive(StreamInfo *info, bool receiveRTP);
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index 0f4c1f3..1bc9925 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -105,7 +105,9 @@
mCheckPending(false),
mCheckGeneration(0),
mTryTCPInterleaving(false),
+ mTryFakeRTCP(false),
mReceivedFirstRTCPPacket(false),
+ mReceivedFirstRTPPacket(false),
mSeekable(false) {
mNetLooper->setName("rtsp net");
mNetLooper->start(false /* runOnCallingThread */,
@@ -534,6 +536,7 @@
mFirstAccessUnitNTP = 0;
mNumAccessUnitsReceived = 0;
mReceivedFirstRTCPPacket = false;
+ mReceivedFirstRTPPacket = false;
mSeekable = false;
sp<AMessage> reply = new AMessage('tear', id());
@@ -611,12 +614,17 @@
case 'accu':
{
- int32_t firstRTCP;
- if (msg->findInt32("first-rtcp", &firstRTCP)) {
+ int32_t first;
+ if (msg->findInt32("first-rtcp", &first)) {
mReceivedFirstRTCPPacket = true;
break;
}
+ if (msg->findInt32("first-rtp", &first)) {
+ mReceivedFirstRTPPacket = true;
+ break;
+ }
+
++mNumAccessUnitsReceived;
postAccessUnitTimeoutCheck();
@@ -839,9 +847,17 @@
case 'tiou':
{
if (!mReceivedFirstRTCPPacket) {
- if (mTryTCPInterleaving) {
+ if (mTryFakeRTCP) {
LOGW("Never received any data, disconnecting.");
(new AMessage('abor', id()))->post();
+ } else if (mTryTCPInterleaving && mReceivedFirstRTPPacket) {
+ LOGW("We received RTP packets but no RTCP packets, "
+ "using fake timestamps.");
+
+ mTryFakeRTCP = true;
+
+ mReceivedFirstRTCPPacket = true;
+ mRTPConn->fakeTimestamps();
} else {
LOGW("Never received any data, switching transports.");
@@ -987,7 +1003,9 @@
bool mCheckPending;
int32_t mCheckGeneration;
bool mTryTCPInterleaving;
+ bool mTryFakeRTCP;
bool mReceivedFirstRTCPPacket;
+ bool mReceivedFirstRTPPacket;
bool mSeekable;
struct TrackInfo {
diff --git a/native/include/android/storage_manager.h b/native/include/android/storage_manager.h
index c202693..bad24913 100644
--- a/native/include/android/storage_manager.h
+++ b/native/include/android/storage_manager.h
@@ -74,10 +74,10 @@
AOBB_STATE_ERROR_ALREADY_MOUNTED = 24,
/*
- * The current application does not have permission to use this OBB
- * because the OBB indicates it's owned by a different package or the
- * key used to open it is incorrect. Can be returned as the status for
- * callbacks made during asynchronous OBB actions.
+ * The current application does not have permission to use this OBB.
+ * This could be because the OBB indicates it's owned by a different
+ * package. Can be returned as the status for callbacks made during
+ * asynchronous OBB actions.
*/
AOBB_STATE_ERROR_PERMISSION_DENIED = 25,
};
diff --git a/preloaded-classes b/preloaded-classes
index 1d5fbc08..8de175a 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1,115 +1,167 @@
# Classes which are preloaded by com.android.internal.os.ZygoteInit.
# Automatically generated by frameworks/base/tools/preload/WritePreloadedClassFile.java.
# MIN_LOAD_TIME_MICROS=1250
+# MIN_PROCESSES=10
android.R$styleable
+android.accounts.Account
+android.accounts.Account$1
android.accounts.AccountManager
-android.accounts.AccountManager$4
-android.accounts.AccountManager$6
-android.accounts.AccountManager$AmsTask
-android.accounts.AccountManager$BaseFutureTask
-android.accounts.AccountManager$Future2Task
-android.accounts.AuthenticatorDescription
-android.accounts.IAccountAuthenticatorResponse$Stub
+android.accounts.AccountManager$12
+android.accounts.IAccountManager
android.accounts.IAccountManager$Stub
-android.accounts.IAccountManagerResponse$Stub
+android.accounts.IAccountManager$Stub$Proxy
android.app.Activity
-android.app.ActivityGroup
-android.app.ActivityManager$RunningAppProcessInfo
-android.app.ActivityManager$RunningServiceInfo
android.app.ActivityManagerNative
android.app.ActivityManagerProxy
android.app.ActivityThread
+android.app.ActivityThread$1
+android.app.ActivityThread$2
+android.app.ActivityThread$ActivityClientRecord
+android.app.ActivityThread$AppBindData
android.app.ActivityThread$ApplicationThread
+android.app.ActivityThread$ContextCleanupInfo
+android.app.ActivityThread$CreateServiceData
+android.app.ActivityThread$GcIdler
android.app.ActivityThread$H
+android.app.ActivityThread$Idler
+android.app.ActivityThread$ProviderClientRecord
+android.app.ActivityThread$ProviderRefCount
+android.app.ActivityThread$ReceiverData
+android.app.ActivityThread$ResourcesKey
+android.app.ActivityThread$ServiceArgsData
+android.app.ActivityThread$StopInfo
android.app.AlertDialog
+android.app.AppGlobals
+android.app.Application
+android.app.ApplicationErrorReport$CrashInfo
+android.app.ApplicationLoaders
android.app.ApplicationThreadNative
android.app.ContextImpl
+android.app.ContextImpl$ApplicationContentResolver
android.app.ContextImpl$ApplicationPackageManager
-android.app.DatePickerDialog
+android.app.ContextImpl$ApplicationPackageManager$ResourceName
+android.app.ContextImpl$SharedPreferencesImpl
+android.app.ContextImpl$SharedPreferencesImpl$1
+android.app.ContextImpl$SharedPreferencesImpl$EditorImpl
+android.app.ContextImpl$SharedPreferencesImpl$EditorImpl$1
+android.app.ContextImpl$SharedPreferencesImpl$EditorImpl$2
+android.app.ContextImpl$SharedPreferencesImpl$MemoryCommitResult
android.app.Dialog
-android.app.ExpandableListActivity
+android.app.Dialog$1
+android.app.Dialog$ListenersHandler
android.app.IActivityManager
android.app.IActivityManager$ContentProviderHolder
-android.app.IAlarmManager$Stub
+android.app.IActivityManager$ContentProviderHolder$1
+android.app.IApplicationThread
+android.app.IInstrumentationWatcher
+android.app.IInstrumentationWatcher$Stub
+android.app.INotificationManager
+android.app.INotificationManager$Stub
+android.app.INotificationManager$Stub$Proxy
+android.app.ITransientNotification
android.app.ITransientNotification$Stub
android.app.Instrumentation
-android.app.IntentService
+android.app.IntentReceiverLeaked
android.app.ListActivity
-android.app.LocalActivityManager
-android.app.Notification
+android.app.LoadedApk
+android.app.LoadedApk$ReceiverDispatcher
+android.app.LoadedApk$ReceiverDispatcher$Args
+android.app.LoadedApk$ReceiverDispatcher$InnerReceiver
+android.app.LoadedApk$ServiceDispatcher$ConnectionInfo
+android.app.LoadedApk$ServiceDispatcher$DeathMonitor
+android.app.LoadedApk$ServiceDispatcher$RunConnection
+android.app.LoadedApk$WarningContextClassLoader
+android.app.NativeActivity
+android.app.NotificationManager
android.app.PendingIntent
-android.app.ProgressDialog
+android.app.PendingIntent$1
+android.app.QueuedWork
+android.app.ReceiverRestrictedContext
android.app.ResultInfo
+android.app.ResultInfo$1
android.app.SearchDialog
-android.app.SearchDialog$SearchAutoComplete
-android.app.SearchDialog$SearchBar
-android.app.SearchableInfo
android.app.Service
-android.app.SuggestionsAdapter
-android.app.SuperNotCalledException
-android.app.TabActivity
-android.app.TimePickerDialog
-android.app.admin.IDevicePolicyManager$Stub
-android.appwidget.AppWidgetHost
-android.appwidget.AppWidgetHostView
-android.appwidget.AppWidgetHostView$ParcelableSparseArray
-android.appwidget.AppWidgetManager
-android.appwidget.AppWidgetProvider
-android.appwidget.AppWidgetProviderInfo
android.app.backup.BackupDataInput
android.app.backup.BackupDataInput$EntityHeader
android.app.backup.BackupDataOutput
-android.app.backup.BackupAgentHelper
android.app.backup.BackupHelperDispatcher
android.app.backup.BackupHelperDispatcher$Header
android.app.backup.FileBackupHelperBase
-android.app.backup.IBackupManager$Stub
-android.app.backup.RestoreSet
-android.bluetooth.BluetoothAdapter
android.bluetooth.BluetoothAudioGateway
android.bluetooth.BluetoothSocket
-android.bluetooth.BluetoothUuid
android.bluetooth.HeadsetBase
android.bluetooth.IBluetooth
android.bluetooth.IBluetooth$Stub
android.bluetooth.IBluetoothA2dp
android.bluetooth.IBluetoothA2dp$Stub
-android.bluetooth.IBluetoothHeadset$Stub
android.bluetooth.ScoSocket
+android.content.BroadcastReceiver
+android.content.ComponentCallbacks
android.content.ComponentName
+android.content.ComponentName$1
+android.content.ContentProvider
android.content.ContentProvider$Transport
-android.content.ContentProviderOperation
-android.content.ContentProviderResult
+android.content.ContentProviderNative
+android.content.ContentProviderProxy
android.content.ContentResolver
+android.content.ContentResolver$CursorWrapperInner
+android.content.ContentUris
android.content.ContentValues
+android.content.ContentValues$1
android.content.Context
android.content.ContextWrapper
+android.content.DialogInterface
+android.content.DialogInterface$OnCancelListener
+android.content.DialogInterface$OnClickListener
+android.content.DialogInterface$OnDismissListener
+android.content.IContentProvider
+android.content.IContentService
android.content.IContentService$Stub
-android.content.ISyncContext$Stub
+android.content.IContentService$Stub$Proxy
+android.content.IIntentReceiver
+android.content.IIntentReceiver$Stub
+android.content.IIntentSender
+android.content.IIntentSender$Stub
+android.content.IIntentSender$Stub$Proxy
android.content.Intent
+android.content.Intent$1
android.content.IntentFilter
-android.content.IntentSender
-android.content.SearchRecentSuggestionsProvider
-android.content.SyncResult
-android.content.SyncStats
+android.content.IntentFilter$1
+android.content.ServiceConnection
+android.content.SharedPreferences
+android.content.SharedPreferences$Editor
+android.content.SharedPreferences$OnSharedPreferenceChangeListener
android.content.UriMatcher
android.content.pm.ActivityInfo
+android.content.pm.ActivityInfo$1
android.content.pm.ApplicationInfo
+android.content.pm.ApplicationInfo$1
+android.content.pm.ComponentInfo
android.content.pm.ConfigurationInfo
-android.content.pm.IPackageDataObserver$Stub
+android.content.pm.ConfigurationInfo$1
+android.content.pm.FeatureInfo
+android.content.pm.FeatureInfo$1
+android.content.pm.IPackageManager
android.content.pm.IPackageManager$Stub
android.content.pm.IPackageManager$Stub$Proxy
-android.content.pm.IPackageStatsObserver$Stub
android.content.pm.InstrumentationInfo
+android.content.pm.InstrumentationInfo$1
android.content.pm.PackageInfo
+android.content.pm.PackageInfo$1
+android.content.pm.PackageItemInfo
android.content.pm.PackageManager
-android.content.pm.PackageManager$NameNotFoundException
-android.content.pm.PackageStats
+android.content.pm.PathPermission
+android.content.pm.PathPermission$1
android.content.pm.PermissionInfo
+android.content.pm.PermissionInfo$1
android.content.pm.ProviderInfo
+android.content.pm.ProviderInfo$1
android.content.pm.ResolveInfo
-android.content.pm.ResolveInfo$DisplayNameComparator
+android.content.pm.ResolveInfo$1
+android.content.pm.ServiceInfo
+android.content.pm.ServiceInfo$1
android.content.pm.Signature
+android.content.pm.Signature$1
android.content.res.AssetFileDescriptor
android.content.res.AssetFileDescriptor$1
android.content.res.AssetManager
@@ -120,34 +172,59 @@
android.content.res.CompatibilityInfo$1
android.content.res.Configuration
android.content.res.Configuration$1
+android.content.res.ObbInfo
+android.content.res.ObbInfo$1
+android.content.res.ObbScanner
android.content.res.Resources
android.content.res.Resources$1
+android.content.res.Resources$Theme
android.content.res.StringBlock
+android.content.res.StringBlock$StyleIDs
android.content.res.TypedArray
android.content.res.XmlBlock
android.content.res.XmlBlock$Parser
android.content.res.XmlResourceParser
android.database.AbstractCursor
+android.database.AbstractCursor$SelfContentObserver
android.database.AbstractWindowedCursor
+android.database.BulkCursorNative
+android.database.BulkCursorProxy
android.database.BulkCursorToCursorAdaptor
android.database.CharArrayBuffer
-android.database.CursorToBulkCursorAdaptor
+android.database.ContentObservable
+android.database.ContentObserver
+android.database.ContentObserver$NotificationRunnable
+android.database.ContentObserver$Transport
+android.database.CrossProcessCursor
+android.database.Cursor
android.database.CursorWindow
android.database.CursorWindow$1
android.database.CursorWrapper
-android.database.MatrixCursor
+android.database.DataSetObservable
+android.database.DataSetObserver
+android.database.DatabaseUtils
+android.database.DatabaseUtils$InsertHelper
+android.database.IBulkCursor
+android.database.IContentObserver
+android.database.IContentObserver$Stub
+android.database.Observable
+android.database.sqlite.DatabaseObjectNotClosedException
android.database.sqlite.SQLiteClosable
android.database.sqlite.SQLiteCompiledSql
-android.database.sqlite.SQLiteContentHelper
android.database.sqlite.SQLiteCursor
+android.database.sqlite.SQLiteCursorDriver
android.database.sqlite.SQLiteDatabase
+android.database.sqlite.SQLiteDatabase$ActiveDatabases
android.database.sqlite.SQLiteDebug
+android.database.sqlite.SQLiteDebug$DbStats
android.database.sqlite.SQLiteDebug$PagerStats
+android.database.sqlite.SQLiteDirectCursorDriver
+android.database.sqlite.SQLiteOpenHelper
android.database.sqlite.SQLiteProgram
android.database.sqlite.SQLiteQuery
android.database.sqlite.SQLiteQueryBuilder
android.database.sqlite.SQLiteStatement
-android.database.sqlite.SqliteWrapper
+android.ddm.DdmHandleAppName
android.ddm.DdmHandleExit
android.ddm.DdmHandleHeap
android.ddm.DdmHandleHello
@@ -160,7 +237,6 @@
android.graphics.AvoidXfermode
android.graphics.Bitmap
android.graphics.Bitmap$1
-android.graphics.Bitmap$CompressFormat
android.graphics.Bitmap$Config
android.graphics.BitmapFactory
android.graphics.BitmapFactory$Options
@@ -168,7 +244,7 @@
android.graphics.BlurMaskFilter
android.graphics.Camera
android.graphics.Canvas
-android.graphics.Canvas$VertexMode
+android.graphics.Canvas$EdgeType
android.graphics.Color
android.graphics.ColorFilter
android.graphics.ColorMatrixColorFilter
@@ -180,11 +256,13 @@
android.graphics.DrawFilter
android.graphics.EmbossMaskFilter
android.graphics.Interpolator
+android.graphics.Interpolator$Result
android.graphics.LayerRasterizer
android.graphics.LightingColorFilter
android.graphics.LinearGradient
android.graphics.MaskFilter
android.graphics.Matrix
+android.graphics.Matrix$ScaleToFit
android.graphics.Movie
android.graphics.NinePatch
android.graphics.Paint
@@ -216,13 +294,13 @@
android.graphics.RectF$1
android.graphics.Region
android.graphics.Region$1
-android.graphics.Region$Op
android.graphics.RegionIterator
android.graphics.Shader
android.graphics.Shader$TileMode
android.graphics.SumPathEffect
android.graphics.SweepGradient
android.graphics.TableMaskFilter
+android.graphics.TemporaryBuffer
android.graphics.Typeface
android.graphics.Xfermode
android.graphics.YuvImage
@@ -251,77 +329,88 @@
android.graphics.drawable.NinePatchDrawable
android.graphics.drawable.NinePatchDrawable$NinePatchState
android.graphics.drawable.ShapeDrawable
+android.graphics.drawable.ShapeDrawable$ShapeState
android.graphics.drawable.StateListDrawable
android.graphics.drawable.StateListDrawable$StateListState
android.graphics.drawable.TransitionDrawable
android.graphics.drawable.TransitionDrawable$TransitionState
+android.graphics.drawable.shapes.RectShape
+android.graphics.drawable.shapes.RoundRectShape
+android.graphics.drawable.shapes.Shape
android.graphics.utils.BoundaryPatch
android.hardware.Camera
-android.hardware.Camera$Parameters
-android.hardware.GeomagneticField
+android.hardware.Camera$CameraInfo
android.hardware.SensorManager
-android.location.Address
-android.location.Criteria
-android.location.GeocoderParams
-android.location.IGpsStatusListener$Stub
+android.inputmethodservice.ExtractEditText
+android.inputmethodservice.InputMethodService
+android.location.GpsSatellite
+android.location.GpsStatus
+android.location.GpsStatus$1
+android.location.ILocationManager
android.location.ILocationManager$Stub
android.location.ILocationManager$Stub$Proxy
-android.location.Location
android.location.LocationManager
+android.media.AmrInputStream
android.media.AudioFormat
android.media.AudioManager
+android.media.AudioManager$1
+android.media.AudioManager$FocusEventHandlerDelegate
+android.media.AudioManager$FocusEventHandlerDelegate$1
android.media.AudioRecord
android.media.AudioSystem
android.media.AudioTrack
+android.media.CamcorderProfile
+android.media.DecoderCapabilities
android.media.ExifInterface
+android.media.IAudioFocusDispatcher
+android.media.IAudioFocusDispatcher$Stub
+android.media.IAudioService
android.media.IAudioService$Stub
+android.media.IAudioService$Stub$Proxy
android.media.JetPlayer
-android.media.MediaFile
-android.media.MediaMetadataRetriever
android.media.MediaPlayer
+android.media.MediaPlayer$OnCompletionListener
+android.media.MediaPlayer$OnErrorListener
+android.media.MediaPlayer$OnPreparedListener
android.media.MediaScanner
-android.media.Metadata
-android.media.MiniThumbFile
-android.media.ThumbnailUtils
+android.media.SoundPool
android.media.ToneGenerator
android.net.ConnectivityManager
android.net.Credentials
android.net.DhcpInfo
android.net.DhcpInfo$1
-android.net.Downloads
-android.net.Downloads$ByUri
+android.net.IConnectivityManager
android.net.IConnectivityManager$Stub
+android.net.IConnectivityManager$Stub$Proxy
android.net.LocalServerSocket
android.net.LocalSocket
android.net.LocalSocketImpl
android.net.LocalSocketImpl$SocketInputStream
android.net.LocalSocketImpl$SocketOutputStream
android.net.NetworkInfo
+android.net.NetworkInfo$1
android.net.NetworkInfo$DetailedState
+android.net.NetworkInfo$State
android.net.NetworkUtils
-android.net.SSLCertificateSocketFactory
android.net.TrafficStats
android.net.Uri
+android.net.Uri$1
+android.net.Uri$AbstractHierarchicalUri
+android.net.Uri$AbstractPart
+android.net.Uri$Builder
android.net.Uri$HierarchicalUri
android.net.Uri$OpaqueUri
android.net.Uri$Part
+android.net.Uri$Part$EmptyPart
+android.net.Uri$PathPart
+android.net.Uri$PathSegments
+android.net.Uri$PathSegmentsBuilder
+android.net.Uri$StringUri
android.net.WebAddress
android.net.http.AndroidHttpClient
-android.net.http.AndroidHttpClientConnection
+android.net.http.AndroidHttpClient$1
android.net.http.EventHandler
-android.net.http.Headers
android.net.http.HttpsConnection
-com.android.internal.http.HttpDateTime
-android.net.http.Request
-android.net.http.RequestQueue
-android.net.http.SslCertificate
-android.net.http.SslError
-android.net.wifi.IWifiManager$Stub
-android.net.wifi.ScanResult
-android.net.wifi.SupplicantState
-android.net.wifi.WifiConfiguration
-android.net.wifi.WifiInfo
-android.net.wifi.WifiManager
android.net.wifi.WifiNative
android.opengl.ETC1
android.opengl.GLES10
@@ -329,313 +418,403 @@
android.opengl.GLES11
android.opengl.GLES11Ext
android.opengl.GLES20
-android.opengl.GLSurfaceView
-android.opengl.GLSurfaceView$ComponentSizeChooser
android.opengl.GLUtils
android.opengl.Matrix
android.opengl.Visibility
+android.os.AsyncTask$1
+android.os.AsyncTask$AsyncTaskResult
android.os.Binder
android.os.BinderProxy
android.os.Build
android.os.Build$VERSION
android.os.Bundle
+android.os.Bundle$1
android.os.Debug
android.os.Debug$MemoryInfo
android.os.Debug$MemoryInfo$1
-android.os.DropBoxManager$Entry
android.os.Environment
android.os.FileObserver$ObserverThread
android.os.FileUtils
android.os.FileUtils$FileStatus
android.os.Handler
+android.os.HandlerThread
android.os.IBinder
+android.os.IBinder$DeathRecipient
android.os.IInterface
+android.os.IPowerManager
android.os.IPowerManager$Stub
+android.os.IPowerManager$Stub$Proxy
+android.os.IServiceManager
android.os.Looper
android.os.MemoryFile
android.os.Message
+android.os.Message$1
+android.os.MessageQueue
+android.os.MessageQueue$IdleHandler
android.os.Parcel
android.os.Parcel$1
android.os.ParcelFileDescriptor
android.os.ParcelFileDescriptor$1
-android.os.ParcelUuid
android.os.Parcelable
android.os.Parcelable$Creator
+android.os.PatternMatcher
+android.os.PatternMatcher$1
android.os.Power
+android.os.PowerManager
+android.os.PowerManager$WakeLock
+android.os.PowerManager$WakeLock$1
android.os.Process
-android.os.RecoverySystem
-android.os.ResultReceiver
+android.os.ServiceManager
+android.os.ServiceManagerNative
+android.os.ServiceManagerProxy
android.os.StatFs
+android.os.StrictMode
+android.os.StrictMode$1
+android.os.StrictMode$2
+android.os.StrictMode$AndroidBlockGuardPolicy
+android.os.StrictMode$AndroidBlockGuardPolicy$1
+android.os.StrictMode$LogStackTrace
+android.os.StrictMode$StrictModeDiskReadViolation
+android.os.StrictMode$StrictModeDiskWriteViolation
+android.os.StrictMode$ViolationInfo
android.os.SystemClock
android.os.SystemProperties
android.os.UEventObserver
-android.os.storage.IMountService$Stub
-android.os.storage.IMountService$Stub$Proxy
android.pim.EventRecurrence
-android.pim.RecurrenceSet
-android.preference.CheckBoxPreference$SavedState
-android.preference.DialogPreference
-android.preference.ListPreference
-android.preference.Preference
-android.preference.PreferenceActivity
-android.preference.PreferenceGroup
-android.preference.PreferenceGroupAdapter
-android.preference.PreferenceInflater
android.preference.PreferenceManager
-android.preference.PreferenceScreen
-android.preference.RingtonePreference
-android.preference.VolumePreference
-android.preference.VolumePreference$SeekBarVolumizer
-android.provider.Browser
-android.provider.Calendar
-android.provider.Calendar$Attendees
-android.provider.Calendar$CalendarAlerts
-android.provider.Calendar$Calendars
-android.provider.Calendar$EventDays
-android.provider.Calendar$Events
-android.provider.Calendar$Reminders
-android.provider.Contacts
-android.provider.Contacts$ContactMethods
-android.provider.ContactsContract
-android.provider.ContactsContract$CommonDataKinds$Email
-android.provider.ContactsContract$CommonDataKinds$Phone
-android.provider.ContactsContract$CommonDataKinds$StructuredPostal
-android.provider.ContactsContract$Contacts
-android.provider.ContactsContract$Data
-android.provider.ContactsContract$DataColumnsWithJoins
-android.provider.ContactsContract$PhoneLookup
-android.provider.ContactsContract$RawContacts
-android.provider.ContactsContract$RawContacts$EntityIteratorImpl
-android.provider.ContactsContract$RawContactsEntity
-android.provider.Downloads
-android.provider.Downloads$Impl
-android.provider.MediaStore
-android.provider.MediaStore$Audio$Artists
-android.provider.MediaStore$Audio$Media
-android.provider.MediaStore$Images$Media
-android.provider.MediaStore$Images$Thumbnails
-android.provider.MediaStore$Video$Media
-android.provider.SearchRecentSuggestions
+android.provider.BaseColumns
+android.provider.Settings$NameValueCache
+android.provider.Settings$NameValueTable
android.provider.Settings$Secure
android.provider.Settings$System
-android.provider.UserDictionary$Words
-android.security.KeyStore
+android.renderscript.RenderScript
android.security.Md5MessageDigest
android.security.MessageDigest
android.security.Sha1MessageDigest
android.server.BluetoothA2dpService
android.server.BluetoothEventLoop
android.server.BluetoothService
-android.speech.tts.ITts$Stub
-android.speech.tts.ITts$Stub$Proxy
-android.speech.tts.ITtsCallback$Stub
-android.speech.tts.TextToSpeech
android.telephony.PhoneNumberUtils
-android.telephony.ServiceState
-android.telephony.SignalStrength
-android.telephony.SmsMessage
-android.telephony.SmsMessage$MessageClass
android.telephony.TelephonyManager
+android.text.AndroidBidi
android.text.AndroidCharacter
+android.text.AutoText
android.text.BoringLayout
+android.text.BoringLayout$Metrics
android.text.DynamicLayout
+android.text.DynamicLayout$ChangeWatcher
+android.text.Editable
+android.text.Editable$Factory
+android.text.GetChars
+android.text.GraphicsOperations
android.text.Html$HtmlParser
-android.text.HtmlToSpannedConverter
+android.text.InputFilter
+android.text.InputType
android.text.Layout
+android.text.Layout$Alignment
+android.text.Layout$Directions
+android.text.NoCopySpan
+android.text.NoCopySpan$Concrete
+android.text.PackedIntVector
+android.text.PackedObjectVector
+android.text.ParcelableSpan
android.text.Selection
+android.text.Selection$END
+android.text.Selection$START
+android.text.SpanWatcher
+android.text.Spannable
+android.text.Spannable$Factory
+android.text.SpannableString
android.text.SpannableStringBuilder
+android.text.SpannableStringInternal
+android.text.Spanned
android.text.SpannedString
+android.text.StaticLayout
+android.text.Styled
+android.text.TextPaint
android.text.TextUtils
-android.text.format.DateUtils
-android.text.format.Formatter
+android.text.TextUtils$1
+android.text.TextUtils$EllipsizeCallback
+android.text.TextUtils$TruncateAt
+android.text.TextWatcher
android.text.format.Time
android.text.method.ArrowKeyMovementMethod
android.text.method.BaseKeyListener
-android.text.method.DigitsKeyListener
-android.text.method.LinkMovementMethod
+android.text.method.KeyListener
android.text.method.MetaKeyKeyListener
+android.text.method.MovementMethod
android.text.method.QwertyKeyListener
-android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence
+android.text.method.ReplacementTransformationMethod
android.text.method.SingleLineTransformationMethod
android.text.method.TextKeyListener
android.text.method.TextKeyListener$Capitalize
-android.text.style.ImageSpan
-android.text.style.RelativeSizeSpan
-android.text.style.ScaleXSpan
+android.text.method.TransformationMethod
+android.text.style.AlignmentSpan
+android.text.style.CharacterStyle
+android.text.style.ClickableSpan
+android.text.style.LeadingMarginSpan
+android.text.style.LineBackgroundSpan
+android.text.style.LineHeightSpan
+android.text.style.MetricAffectingSpan
+android.text.style.ParagraphStyle
+android.text.style.ReplacementSpan
android.text.style.StyleSpan
-android.text.style.TextAppearanceSpan
-android.text.util.Linkify
+android.text.style.URLSpan
+android.text.style.UpdateAppearance
+android.text.style.UpdateLayout
+android.text.style.WrapTogetherSpan
+android.util.AndroidException
+android.util.AndroidRuntimeException
android.util.AttributeSet
-android.util.Base64$Encoder
android.util.DisplayMetrics
android.util.EventLog
android.util.EventLog$Event
+android.util.FinitePool
android.util.FloatMath
android.util.Log
+android.util.Log$1
+android.util.Log$TerribleFailureHandler
android.util.LongSparseArray
-android.util.MonthDisplayHelper
+android.util.Pair
android.util.Patterns
+android.util.Pool
+android.util.Poolable
+android.util.PoolableManager
+android.util.Pools
android.util.SparseArray
+android.util.SparseIntArray
android.util.StateSet
+android.util.SynchronizedPool
android.util.TypedValue
android.util.Xml
-android.util.Xml$Encoding
android.view.AbsSavedState
+android.view.AbsSavedState$1
+android.view.AbsSavedState$2
+android.view.ContextMenu
+android.view.ContextMenu$ContextMenuInfo
android.view.ContextThemeWrapper
android.view.Display
android.view.FocusFinder
-android.view.GestureDetector
+android.view.FocusFinder$1
+android.view.Gravity
+android.view.IWindow
android.view.IWindow$Stub
+android.view.IWindowManager
android.view.IWindowManager$Stub
android.view.IWindowManager$Stub$Proxy
+android.view.IWindowSession
android.view.IWindowSession$Stub
+android.view.IWindowSession$Stub$Proxy
+android.view.InputChannel
+android.view.InputChannel$1
+android.view.InputEvent
+android.view.InputEvent$1
+android.view.InputHandler
+android.view.InputQueue
+android.view.InputQueue$Callback
+android.view.InputQueue$FinishedCallback
android.view.KeyCharacterMap
android.view.KeyCharacterMap$KeyData
android.view.KeyEvent
+android.view.KeyEvent$1
+android.view.KeyEvent$Callback
+android.view.KeyEvent$DispatcherState
+android.view.LayoutInflater
+android.view.LayoutInflater$Factory
+android.view.LayoutInflater$Filter
+android.view.Menu
+android.view.MenuItem
android.view.MotionEvent
-android.view.ScaleGestureDetector
+android.view.MotionEvent$1
android.view.Surface
android.view.Surface$1
+android.view.Surface$CompatibleCanvas
+android.view.SurfaceHolder
+android.view.SurfaceHolder$Callback
+android.view.SurfaceHolder$Callback2
android.view.SurfaceSession
-android.view.SurfaceView
-android.view.SurfaceView$MyWindow
android.view.VelocityTracker
+android.view.VelocityTracker$1
+android.view.VelocityTracker$Pointer
android.view.View
+android.view.View$AttachInfo
android.view.View$AttachInfo$Callbacks
-android.view.View$AttachInfo$InvalidateInfo
android.view.View$BaseSavedState
+android.view.View$BaseSavedState$1
+android.view.View$CheckForTap
+android.view.View$MeasureSpec
+android.view.View$OnClickListener
+android.view.View$OnCreateContextMenuListener
+android.view.View$OnLongClickListener
+android.view.View$OnTouchListener
+android.view.View$PerformClick
+android.view.View$ScrollabilityCache
+android.view.View$UnsetPressedState
android.view.ViewConfiguration
+android.view.ViewDebug
android.view.ViewGroup
+android.view.ViewGroup$LayoutParams
+android.view.ViewGroup$MarginLayoutParams
+android.view.ViewGroup$OnHierarchyChangeListener
+android.view.ViewManager
android.view.ViewParent
android.view.ViewRoot
+android.view.ViewRoot$1
+android.view.ViewRoot$2
+android.view.ViewRoot$InputMethodCallback
+android.view.ViewRoot$ResizedInfo
+android.view.ViewRoot$RunQueue
+android.view.ViewRoot$TrackballAxis
android.view.ViewRoot$W
-android.view.ViewStub
+android.view.ViewTreeObserver
+android.view.ViewTreeObserver$InternalInsetsInfo
+android.view.ViewTreeObserver$OnGlobalFocusChangeListener
+android.view.ViewTreeObserver$OnGlobalLayoutListener
+android.view.ViewTreeObserver$OnPreDrawListener
+android.view.ViewTreeObserver$OnScrollChangedListener
+android.view.ViewTreeObserver$OnTouchModeChangeListener
android.view.Window
+android.view.Window$Callback
+android.view.Window$LocalWindowManager
+android.view.WindowLeaked
+android.view.WindowManager
android.view.WindowManager$LayoutParams
+android.view.WindowManager$LayoutParams$1
android.view.WindowManagerImpl
android.view.accessibility.AccessibilityEvent
+android.view.accessibility.AccessibilityEventSource
+android.view.accessibility.AccessibilityManager
+android.view.accessibility.AccessibilityManager$1
+android.view.accessibility.AccessibilityManager$MyHandler
+android.view.accessibility.IAccessibilityManager
+android.view.accessibility.IAccessibilityManager$Stub
+android.view.accessibility.IAccessibilityManager$Stub$Proxy
+android.view.accessibility.IAccessibilityManagerClient
+android.view.accessibility.IAccessibilityManagerClient$Stub
+android.view.animation.AccelerateDecelerateInterpolator
+android.view.animation.AlphaAnimation
android.view.animation.Animation
-android.view.animation.AnimationSet
+android.view.animation.AnimationUtils
+android.view.animation.DecelerateInterpolator
+android.view.animation.Interpolator
+android.view.animation.LinearInterpolator
+android.view.animation.Transformation
android.view.inputmethod.BaseInputConnection
-android.view.inputmethod.CompletionInfo
+android.view.inputmethod.ComposingText
android.view.inputmethod.EditorInfo
+android.view.inputmethod.EditorInfo$1
android.view.inputmethod.ExtractedText
+android.view.inputmethod.ExtractedText$1
+android.view.inputmethod.ExtractedTextRequest
+android.view.inputmethod.InputConnection
android.view.inputmethod.InputMethodManager
+android.view.inputmethod.InputMethodManager$1
+android.view.inputmethod.InputMethodManager$ControlledInputConnectionWrapper
+android.view.inputmethod.InputMethodManager$H
android.webkit.BrowserFrame
-android.webkit.CacheManager
-android.webkit.CallbackProxy
-android.webkit.ConsoleMessage$MessageLevel
-android.webkit.CookieManager
-android.webkit.CookieSyncManager
-android.webkit.DownloadListener
-android.webkit.FileLoader
android.webkit.GeolocationPermissions
-android.webkit.GeolocationService
android.webkit.HTML5VideoViewProxy
android.webkit.JWebCoreJavaBridge
android.webkit.LoadListener
+android.webkit.MockGeolocation
android.webkit.PluginManager
-android.webkit.URLUtil
-android.webkit.WebIconDatabase$EventHandler$IconResult
-android.webkit.WebIconDatabase$IconListener
+android.webkit.WebBackForwardList
+android.webkit.WebHistoryItem
+android.webkit.WebIconDatabase
android.webkit.WebSettings
android.webkit.WebSettings$TextSize
android.webkit.WebStorage
-android.webkit.WebTextView
android.webkit.WebView
-android.webkit.WebView$DragTrackerHandler
-android.webkit.WebView$ScaleDetectorListener
android.webkit.WebViewCore
-android.webkit.WebViewCore$4
-android.webkit.WebViewCore$TextSelectionData
-android.webkit.WebViewCore$TouchEventData
-android.webkit.WebViewCore$TouchUpData
-android.webkit.WebViewDatabase
android.widget.AbsListView
-android.widget.AbsListView$3
-android.widget.AbsListView$CheckForKeyLongPress
-android.widget.AbsListView$PerformClick
-android.widget.AbsListView$SavedState
-android.widget.AbsSeekBar
+android.widget.AbsListView$2
+android.widget.AbsListView$LayoutParams
+android.widget.AbsListView$RecycleBin
android.widget.AbsSpinner
-android.widget.AbsSpinner$SavedState
android.widget.AbsoluteLayout
+android.widget.Adapter
android.widget.AdapterView
-android.widget.ArrayAdapter
+android.widget.AdapterView$AdapterDataSetObserver
+android.widget.AdapterView$OnItemClickListener
android.widget.AutoCompleteTextView
-android.widget.AutoCompleteTextView$DropDownItemClickListener
-android.widget.AutoCompleteTextView$DropDownListView
android.widget.BaseAdapter
-android.widget.BaseExpandableListAdapter
+android.widget.Button
android.widget.CheckBox
+android.widget.Checkable
android.widget.CompoundButton
-android.widget.CompoundButton$SavedState
-android.widget.CursorAdapter
-android.widget.CursorTreeAdapter
-android.widget.DatePicker
+android.widget.EdgeGlow
android.widget.EditText
-android.widget.ExpandableListConnector
-android.widget.ExpandableListView
+android.widget.Filter$FilterListener
+android.widget.Filterable
android.widget.FrameLayout
+android.widget.FrameLayout$LayoutParams
+android.widget.Gallery
android.widget.GridView
-android.widget.HeaderViewListAdapter
+android.widget.HorizontalScrollView
+android.widget.ImageButton
android.widget.ImageView
android.widget.ImageView$ScaleType
android.widget.LinearLayout
+android.widget.LinearLayout$LayoutParams
+android.widget.ListAdapter
android.widget.ListView
-android.widget.ListView$SavedState
-android.widget.MediaController
-android.widget.MediaController$4
-android.widget.MultiAutoCompleteTextView
+android.widget.ListView$ArrowScrollFocusResult
android.widget.NumberPicker
+android.widget.OverScroller
+android.widget.OverScroller$MagneticOverScroller
android.widget.PopupWindow
-android.widget.PopupWindow$PopupViewContainer
+android.widget.PopupWindow$1
android.widget.ProgressBar
-android.widget.ProgressBar$SavedState
-android.widget.QuickContactBadge
-android.widget.RatingBar
android.widget.RelativeLayout
+android.widget.RelativeLayout$DependencyGraph
android.widget.RelativeLayout$DependencyGraph$Node
+android.widget.RelativeLayout$DependencyGraph$Node$1
+android.widget.RelativeLayout$LayoutParams
android.widget.RemoteViews
-android.widget.ResourceCursorAdapter
+android.widget.RemoteViews$1
+android.widget.RemoteViews$Action
+android.widget.RemoteViews$ReflectionAction
android.widget.ScrollBarDrawable
android.widget.ScrollView
-android.widget.SeekBar
-android.widget.SimpleCursorAdapter
-android.widget.SlidingDrawer
-android.widget.Spinner
+android.widget.SpinnerAdapter
android.widget.TabHost
android.widget.TabWidget
android.widget.TableLayout
android.widget.TableRow
android.widget.TextView
-android.widget.TextView$CommitSelectionReceiver
-android.widget.TextView$Marquee
-android.widget.TimePicker
-android.widget.TwoLineListItem
-android.widget.VideoView
+android.widget.TextView$3
+android.widget.TextView$Blink
+android.widget.TextView$BufferType
+android.widget.TextView$ChangeWatcher
+android.widget.TextView$CharWrapper
+android.widget.TextView$CursorController
+android.widget.TextView$Drawables
+android.widget.TextView$HandleView
+android.widget.TextView$InsertionPointCursorController
+android.widget.TextView$InsertionPointCursorController$1
+android.widget.TextView$SelectionModifierCursorController
+android.widget.TextView$SelectionModifierCursorController$1
+android.widget.Toast
+android.widget.Toast$TN
+android.widget.Toast$TN$1
+android.widget.Toast$TN$2
android.widget.ViewAnimator
-android.widget.ViewSwitcher
android.widget.ZoomButton
-android.widget.ZoomButtonsController
android.widget.ZoomControls
com.android.internal.R$styleable
-com.android.internal.app.AlertActivity
com.android.internal.app.AlertController
+com.android.internal.app.AlertController$1
com.android.internal.app.AlertController$AlertParams
-com.android.internal.app.AlertController$RecycleListView
-com.android.internal.app.ChooserActivity
-com.android.internal.app.ResolverActivity
-com.android.internal.app.ResolverActivity$ResolveListAdapter
+com.android.internal.app.AlertController$ButtonHandler
+com.android.internal.appwidget.IAppWidgetService
com.android.internal.appwidget.IAppWidgetService$Stub
-com.android.internal.content.SyncStateContentProviderHelper
com.android.internal.graphics.NativeUtils
-com.android.internal.location.DummyLocationProvider
+com.android.internal.logging.AndroidConfig
com.android.internal.logging.AndroidHandler
+com.android.internal.logging.AndroidHandler$1
com.android.internal.os.AndroidPrintStream
com.android.internal.os.BinderInternal
com.android.internal.os.BinderInternal$GcWatcher
-com.android.internal.os.IResultReceiver$Stub
com.android.internal.os.LoggingPrintStream
com.android.internal.os.LoggingPrintStream$1
com.android.internal.os.RuntimeInit
@@ -645,53 +824,53 @@
com.android.internal.os.ZygoteConnection
com.android.internal.os.ZygoteConnection$Arguments
com.android.internal.os.ZygoteInit
-com.android.internal.net.DomainNameValidator
+com.android.internal.os.ZygoteInit$MethodAndArgsCaller
+com.android.internal.policy.IPolicy
com.android.internal.policy.PolicyManager
com.android.internal.policy.impl.PhoneLayoutInflater
com.android.internal.policy.impl.PhoneWindow
+com.android.internal.policy.impl.PhoneWindow$1
+com.android.internal.policy.impl.PhoneWindow$ContextMenuCallback
com.android.internal.policy.impl.PhoneWindow$DecorView
+com.android.internal.policy.impl.PhoneWindow$PanelFeatureState
com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState
-com.android.internal.policy.impl.PhoneWindowManager
+com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState$1
com.android.internal.policy.impl.Policy
-com.android.internal.statusbar.IStatusBar
-com.android.internal.statusbar.IStatusBar$Stub
-com.android.internal.statusbar.IStatusBarService$Stub
-com.android.internal.statusbar.IStatusBarService$Stub
-com.android.internal.statusbar.StatusBarIcon
-com.android.internal.telephony.GsmAlphabet
-com.android.internal.telephony.ITelephony$Stub
-com.android.internal.telephony.ITelephony$Stub$Proxy
+com.android.internal.telephony.ITelephonyRegistry
com.android.internal.telephony.ITelephonyRegistry$Stub
-com.android.internal.telephony.IccCard$State
+com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
com.android.internal.telephony.Phone$State
-com.android.internal.telephony.SmsAddress
-com.android.internal.telephony.SmsMessageBase
-com.android.internal.telephony.gsm.GsmSmsAddress
-com.android.internal.telephony.gsm.SmsMessage
-com.android.internal.telephony.gsm.SmsMessage$PduParser
com.android.internal.util.ArrayUtils
-com.android.internal.util.FastMath
com.android.internal.util.FastXmlSerializer
-com.android.internal.util.HanziToPinyin
com.android.internal.util.XmlUtils
com.android.internal.view.IInputConnectionWrapper
+com.android.internal.view.IInputConnectionWrapper$MyHandler
+com.android.internal.view.IInputContext
com.android.internal.view.IInputContext$Stub
+com.android.internal.view.IInputMethodCallback
+com.android.internal.view.IInputMethodCallback$Stub
+com.android.internal.view.IInputMethodClient
+com.android.internal.view.IInputMethodClient$Stub
+com.android.internal.view.IInputMethodManager
com.android.internal.view.IInputMethodManager$Stub
+com.android.internal.view.IInputMethodManager$Stub$Proxy
+com.android.internal.view.IInputMethodSession
+com.android.internal.view.IInputMethodSession$Stub
+com.android.internal.view.IInputMethodSession$Stub$Proxy
+com.android.internal.view.InputBindResult
+com.android.internal.view.InputBindResult$1
+com.android.internal.view.RootViewSurfaceTaker
com.android.internal.view.menu.ContextMenuBuilder
com.android.internal.view.menu.IconMenuItemView
com.android.internal.view.menu.IconMenuView
-com.android.internal.view.menu.IconMenuView$SavedState
-com.android.internal.view.menu.ListMenuItemView
com.android.internal.view.menu.MenuBuilder
-com.android.internal.view.menu.MenuItemImpl
-com.android.internal.view.menu.SubMenuBuilder
+com.android.internal.view.menu.MenuBuilder$Callback
com.android.internal.widget.ContactHeaderWidget
com.android.internal.widget.DialogTitle
-com.android.internal.widget.EditableInputConnection
-com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
-com.android.internal.widget.LockPatternUtils
-com.android.internal.widget.LockPatternView
-com.android.internal.widget.LockPatternView$Cell
+com.android.internal.widget.WeightedLinearLayout
+com.android.server.Watchdog
+com.google.android.collect.Lists
+com.google.android.collect.Maps
com.google.android.gles_jni.EGLImpl
com.google.android.gles_jni.GLImpl
com.ibm.icu4jni.charset.CharsetDecoderICU
@@ -699,16 +878,24 @@
com.ibm.icu4jni.charset.CharsetICU
com.ibm.icu4jni.charset.NativeConverter
com.ibm.icu4jni.common.ErrorCode
-com.ibm.icu4jni.text.Collator
com.ibm.icu4jni.text.NativeBreakIterator
com.ibm.icu4jni.text.NativeCollation
com.ibm.icu4jni.text.NativeDecimalFormat
-com.ibm.icu4jni.text.RuleBasedCollator
+com.ibm.icu4jni.text.NativeDecimalFormat$FieldPositionIterator
+com.ibm.icu4jni.util.ICU
+com.ibm.icu4jni.util.LocaleData
+dalvik.system.BlockGuard
+dalvik.system.BlockGuard$1
+dalvik.system.BlockGuard$2
+dalvik.system.BlockGuard$BlockGuardPolicyException
+dalvik.system.BlockGuard$Policy
+dalvik.system.BlockGuard$WrappedFileSystem
+dalvik.system.BlockGuard$WrappedNetworkSystem
dalvik.system.DalvikLogHandler
dalvik.system.DalvikLogging
+dalvik.system.DexFile
dalvik.system.NativeStart
dalvik.system.PathClassLoader
-dalvik.system.SamplingProfiler
dalvik.system.TouchDex
dalvik.system.VMDebug
dalvik.system.VMRuntime
@@ -720,8 +907,11 @@
java.io.BufferedInputStream
java.io.BufferedReader
java.io.ByteArrayInputStream
+java.io.ByteArrayOutputStream
java.io.Closeable
+java.io.Console
java.io.DataInput
+java.io.DataInputStream
java.io.DataOutput
java.io.DataOutputStream
java.io.File
@@ -742,25 +932,25 @@
java.io.ObjectOutput
java.io.ObjectOutputStream
java.io.ObjectStreamClass
-java.io.ObjectStreamClass$OSCThreadLocalCache
java.io.ObjectStreamConstants
-java.io.ObjectStreamException
java.io.ObjectStreamField
java.io.OutputStream
java.io.OutputStreamWriter
java.io.PrintStream
java.io.PrintWriter
-java.io.PushbackReader
+java.io.PushbackInputStream
java.io.RandomAccessFile
java.io.Reader
java.io.Serializable
-java.io.StreamCorruptedException
+java.io.StringWriter
+java.io.Writer
java.lang.AbstractStringBuilder
java.lang.Appendable
java.lang.ArrayIndexOutOfBoundsException
java.lang.Boolean
java.lang.BootClassLoader
java.lang.Byte
+java.lang.CaseMapper
java.lang.CharSequence
java.lang.Character
java.lang.Character$UnicodeBlock
@@ -769,6 +959,7 @@
java.lang.ClassCache$EnumComparator
java.lang.ClassLoader
java.lang.ClassLoader$SystemClassLoader
+java.lang.ClassNotFoundException
java.lang.Cloneable
java.lang.Comparable
java.lang.Double
@@ -777,8 +968,11 @@
java.lang.Exception
java.lang.Float
java.lang.IllegalArgumentException
+java.lang.IllegalStateException
java.lang.IndexOutOfBoundsException
java.lang.Integer
+java.lang.IntegralToString
+java.lang.IntegralToString$1
java.lang.InternalError
java.lang.InterruptedException
java.lang.Iterable
@@ -787,12 +981,15 @@
java.lang.Long
java.lang.Math
java.lang.NoClassDefFoundError
-java.lang.NoSuchMethodError
+java.lang.NoSuchMethodException
+java.lang.NullPointerException
java.lang.Number
java.lang.NumberFormatException
java.lang.Object
java.lang.OutOfMemoryError
java.lang.Readable
+java.lang.RealToString
+java.lang.RealToString$1
java.lang.Runnable
java.lang.Runtime
java.lang.RuntimeException
@@ -817,6 +1014,7 @@
java.lang.ThreadLocal
java.lang.ThreadLocal$Values
java.lang.Throwable
+java.lang.UnsafeByteSequence
java.lang.UnsatisfiedLinkError
java.lang.UnsupportedOperationException
java.lang.VMClassLoader
@@ -838,6 +1036,7 @@
java.lang.reflect.InvocationHandler
java.lang.reflect.Member
java.lang.reflect.Method
+java.lang.reflect.Method$1
java.lang.reflect.Modifier
java.lang.reflect.Proxy
java.lang.reflect.ReflectionAccessImpl
@@ -845,32 +1044,39 @@
java.math.BigDecimal
java.math.BigInt
java.math.BigInteger
-java.math.Multiplication
java.math.NativeBN
+java.math.RoundingMode
java.net.AddressCache
java.net.AddressCache$1
-java.net.ConnectException
+java.net.AddressCache$AddressCacheEntry
java.net.ContentHandler
java.net.DatagramPacket
+java.net.HttpURLConnection
java.net.Inet4Address
java.net.InetAddress
java.net.InetAddress$1
-java.net.InetAddress$2
java.net.InetAddress$WaitReachable
java.net.InetSocketAddress
+java.net.InterfaceAddress
java.net.JarURLConnection
+java.net.MulticastGroupRequest
java.net.NetPermission
java.net.NetworkInterface
-java.net.ServerSocket
+java.net.Proxy
java.net.Socket
-java.net.SocketException
+java.net.Socket$ConnectLock
+java.net.SocketAddress
java.net.SocketImpl
+java.net.SocketImplFactory
java.net.SocketOptions
+java.net.SocketTimeoutException
java.net.URI
+java.net.URIEncoderDecoder
java.net.URL
java.net.URLConnection
java.net.URLConnection$DefaultContentHandler
java.net.URLStreamHandler
+java.net.UnknownHostException
java.nio.BaseByteBuffer
java.nio.Buffer
java.nio.BufferFactory
@@ -879,14 +1085,13 @@
java.nio.CharArrayBuffer
java.nio.CharBuffer
java.nio.CharSequenceAdapter
-java.nio.CharToByteBufferAdapter
java.nio.DirectByteBuffer
-java.nio.FloatToByteBufferAdapter
+java.nio.DirectByteBuffer$SafeAddress
java.nio.HeapByteBuffer
-java.nio.IntToByteBufferAdapter
-java.nio.LongBuffer
-java.nio.LongToByteBufferAdapter
+java.nio.MappedByteBuffer
+java.nio.MappedByteBufferAdapter
java.nio.NIOAccess
+java.nio.ReadOnlyDirectByteBuffer
java.nio.ReadWriteCharArrayBuffer
java.nio.ReadWriteDirectByteBuffer
java.nio.ReadWriteHeapByteBuffer
@@ -894,6 +1099,7 @@
java.nio.channels.ByteChannel
java.nio.channels.Channel
java.nio.channels.FileChannel
+java.nio.channels.FileChannel$MapMode
java.nio.channels.GatheringByteChannel
java.nio.channels.InterruptibleChannel
java.nio.channels.ReadableByteChannel
@@ -901,39 +1107,60 @@
java.nio.channels.WritableByteChannel
java.nio.channels.spi.AbstractInterruptibleChannel
java.nio.channels.spi.AbstractInterruptibleChannel$1
-java.nio.channels.spi.AbstractInterruptibleChannel$2
java.nio.charset.Charset
java.nio.charset.Charset$1
java.nio.charset.CharsetDecoder
java.nio.charset.CharsetEncoder
+java.nio.charset.Charsets
java.nio.charset.CoderResult
java.nio.charset.CodingErrorAction
-java.nio.charset.spi.CharsetProvider
+java.nio.charset.ModifiedUtf8
java.security.AccessControlContext
java.security.AccessController
java.security.BasicPermission
java.security.Guard
java.security.KeyStore
-java.security.MessageDigest
+java.security.KeyStore$1
+java.security.KeyStoreSpi
java.security.Permission
+java.security.Principal
java.security.PrivilegedAction
java.security.PrivilegedExceptionAction
java.security.ProtectionDomain
java.security.Provider
+java.security.Provider$Service
+java.security.Provider$Service$1
+java.security.SecureRandom
+java.security.SecureRandomSpi
java.security.Security
+java.security.Security$1
+java.security.Security$SecurityDoor
+java.security.cert.CertPathParameters
+java.security.cert.CertPathValidator
+java.security.cert.CertPathValidatorSpi
+java.security.cert.Certificate
+java.security.cert.CertificateFactory
+java.security.cert.CertificateFactorySpi
+java.security.cert.PKIXParameters
+java.security.cert.TrustAnchor
java.security.cert.X509Certificate
-java.text.AttributedCharacterIterator$Attribute
-java.text.Collator
+java.security.cert.X509Extension
java.text.DateFormat
-java.text.DateFormat$Field
+java.text.DateFormatSymbols
java.text.DecimalFormat
+java.text.DecimalFormat$1
java.text.DecimalFormatSymbols
java.text.Format
java.text.NumberFormat
+java.text.ParsePosition
java.text.SimpleDateFormat
java.util.AbstractCollection
java.util.AbstractList
+java.util.AbstractList$FullListIterator
+java.util.AbstractList$SimpleListIterator
java.util.AbstractMap
+java.util.AbstractQueue
+java.util.AbstractSequentialList
java.util.AbstractSet
java.util.ArrayList
java.util.ArrayList$ArrayListIterator
@@ -946,87 +1173,141 @@
java.util.Collections$EmptyList
java.util.Collections$EmptyMap
java.util.Collections$EmptySet
-java.util.Collections$SingletonSet
java.util.Collections$UnmodifiableCollection
java.util.Collections$UnmodifiableCollection$1
+java.util.Collections$UnmodifiableList
+java.util.Collections$UnmodifiableMap
java.util.Collections$UnmodifiableRandomAccessList
java.util.Collections$UnmodifiableSet
+java.util.ComparableTimSort
java.util.Comparator
+java.util.Currency
java.util.Date
+java.util.Deque
java.util.Dictionary
java.util.EnumMap
java.util.EnumSet
java.util.Enumeration
java.util.EventListener
java.util.EventObject
+java.util.Formattable
java.util.Formatter
+java.util.Formatter$1
+java.util.Formatter$FormatSpecifierParser
+java.util.Formatter$FormatToken
java.util.GregorianCalendar
java.util.HashMap
+java.util.HashMap$EntryIterator
+java.util.HashMap$EntrySet
java.util.HashMap$HashIterator
java.util.HashMap$HashMapEntry
java.util.HashMap$KeyIterator
java.util.HashMap$KeySet
+java.util.HashMap$ValueIterator
java.util.HashMap$Values
java.util.HashSet
java.util.Hashtable
+java.util.Hashtable$EntryIterator
+java.util.Hashtable$EntrySet
java.util.Hashtable$HashIterator
java.util.Hashtable$HashtableEntry
java.util.Hashtable$KeyEnumeration
java.util.Hashtable$ValueIterator
java.util.Hashtable$Values
-java.util.IdentityHashMap
java.util.Iterator
java.util.LinkedHashMap
+java.util.LinkedHashMap$KeyIterator
java.util.LinkedHashMap$LinkedEntry
java.util.LinkedHashMap$LinkedHashIterator
java.util.LinkedHashMap$ValueIterator
java.util.LinkedList
+java.util.LinkedList$Link
+java.util.LinkedList$LinkIterator
java.util.List
java.util.ListIterator
java.util.Locale
java.util.Map
java.util.Map$Entry
-java.util.MiniEnumSet
+java.util.NavigableMap
+java.util.NavigableSet
java.util.Properties
java.util.PropertyPermission
+java.util.Queue
+java.util.Random
java.util.RandomAccess
-java.util.ResourceBundle
java.util.Set
java.util.SimpleTimeZone
java.util.SortedMap
java.util.SortedSet
-java.util.SpecialAccess
-java.util.Stack
java.util.StringTokenizer
+java.util.TimSort
java.util.TimeZone
java.util.TreeMap
+java.util.TreeMap$1
+java.util.TreeMap$2
+java.util.TreeMap$Bound
+java.util.TreeMap$Bound$1
+java.util.TreeMap$Bound$2
+java.util.TreeMap$Bound$3
+java.util.TreeMap$EntrySet
+java.util.TreeMap$EntrySet$1
+java.util.TreeMap$KeySet
+java.util.TreeMap$KeySet$1
+java.util.TreeMap$MapIterator
+java.util.TreeMap$Node
+java.util.TreeMap$Relation
java.util.TreeSet
-java.util.UUID
java.util.Vector
+java.util.Vector$1
java.util.WeakHashMap
java.util.WeakHashMap$Entry
-java.util.concurrent.ConcurrentHashMap
+java.util.WeakHashMap$Entry$Type
+java.util.WeakHashMap$HashIterator
+java.util.concurrent.AbstractExecutorService
+java.util.concurrent.BlockingQueue
+java.util.concurrent.Callable
java.util.concurrent.ConcurrentLinkedQueue
java.util.concurrent.ConcurrentLinkedQueue$Node
java.util.concurrent.CopyOnWriteArrayList
java.util.concurrent.CopyOnWriteArrayList$COWIterator
+java.util.concurrent.CountDownLatch
+java.util.concurrent.CountDownLatch$Sync
+java.util.concurrent.Executor
+java.util.concurrent.ExecutorService
+java.util.concurrent.Executors
+java.util.concurrent.Executors$DefaultThreadFactory
java.util.concurrent.Executors$DelegatedExecutorService
+java.util.concurrent.Executors$FinalizableDelegatedExecutorService
+java.util.concurrent.Future
java.util.concurrent.FutureTask
+java.util.concurrent.FutureTask$Sync
java.util.concurrent.LinkedBlockingQueue
-java.util.concurrent.Semaphore
+java.util.concurrent.LinkedBlockingQueue$Node
+java.util.concurrent.RejectedExecutionHandler
+java.util.concurrent.RunnableFuture
+java.util.concurrent.ThreadFactory
java.util.concurrent.ThreadPoolExecutor
+java.util.concurrent.ThreadPoolExecutor$AbortPolicy
+java.util.concurrent.ThreadPoolExecutor$Worker
java.util.concurrent.TimeUnit
-java.util.concurrent.atomic.AtomicBoolean
+java.util.concurrent.TimeUnit$1
+java.util.concurrent.TimeUnit$2
+java.util.concurrent.TimeUnit$3
+java.util.concurrent.TimeUnit$4
+java.util.concurrent.TimeUnit$5
+java.util.concurrent.TimeUnit$6
+java.util.concurrent.TimeUnit$7
java.util.concurrent.atomic.AtomicInteger
-java.util.concurrent.atomic.AtomicLong
-java.util.concurrent.atomic.AtomicReference
java.util.concurrent.atomic.UnsafeAccess
java.util.concurrent.locks.AbstractOwnableSynchronizer
java.util.concurrent.locks.AbstractQueuedSynchronizer
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject
java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
+java.util.concurrent.locks.Condition
java.util.concurrent.locks.Lock
+java.util.concurrent.locks.LockSupport
java.util.concurrent.locks.ReentrantLock
+java.util.concurrent.locks.ReentrantLock$FairSync
java.util.concurrent.locks.ReentrantLock$NonfairSync
java.util.concurrent.locks.ReentrantLock$Sync
java.util.concurrent.locks.UnsafeAccess
@@ -1038,6 +1319,9 @@
java.util.jar.JarFile$1JarFileEnumerator
java.util.jar.JarVerifier
java.util.jar.Manifest
+java.util.logging.ConsoleHandler
+java.util.logging.ErrorManager
+java.util.logging.Formatter
java.util.logging.Handler
java.util.logging.Level
java.util.logging.LogManager
@@ -1048,13 +1332,18 @@
java.util.logging.Logger
java.util.logging.Logger$1
java.util.logging.LoggingPermission
+java.util.logging.SimpleFormatter
+java.util.logging.StreamHandler
java.util.regex.MatchResult
java.util.regex.Matcher
java.util.regex.Pattern
+java.util.regex.PatternSyntaxException
+java.util.regex.Splitter
java.util.zip.Adler32
java.util.zip.CRC32
java.util.zip.Checksum
java.util.zip.Deflater
+java.util.zip.GZIPInputStream
java.util.zip.Inflater
java.util.zip.InflaterInputStream
java.util.zip.ZipConstants
@@ -1064,9 +1353,6 @@
java.util.zip.ZipFile$2
java.util.zip.ZipFile$RAFStream
java.util.zip.ZipFile$ZipInflaterInputStream
-javax.crypto.Cipher
-javax.crypto.Mac
-javax.crypto.spec.IvParameterSpec
javax.microedition.khronos.egl.EGL
javax.microedition.khronos.egl.EGL10
javax.microedition.khronos.opengles.GL
@@ -1075,18 +1361,41 @@
javax.microedition.khronos.opengles.GL11
javax.microedition.khronos.opengles.GL11Ext
javax.microedition.khronos.opengles.GL11ExtensionPack
+javax.net.SocketFactory
javax.net.ssl.DefaultHostnameVerifier
+javax.net.ssl.HostnameVerifier
javax.net.ssl.HttpsURLConnection
-javax.net.ssl.SSLServerSocket
-javax.net.ssl.SSLSession
+javax.net.ssl.KeyManager
+javax.net.ssl.KeyManagerFactory
+javax.net.ssl.KeyManagerFactory$1
+javax.net.ssl.KeyManagerFactorySpi
+javax.net.ssl.SSLContextSpi
+javax.net.ssl.SSLSessionContext
javax.net.ssl.SSLSocket
javax.net.ssl.SSLSocketFactory
+javax.net.ssl.SSLSocketFactory$1
+javax.net.ssl.TrustManager
+javax.net.ssl.TrustManagerFactory
+javax.net.ssl.TrustManagerFactory$1
+javax.net.ssl.TrustManagerFactorySpi
+javax.net.ssl.X509ExtendedKeyManager
+javax.net.ssl.X509KeyManager
+javax.net.ssl.X509TrustManager
javax.security.auth.x500.X500Principal
-javax.security.cert.X509Certificate
-junit.framework.Assert
+libcore.base.Objects
+libcore.icu.NativeIDN
+libcore.icu.NativeNormalizer
+libcore.icu.NativePluralRules
+libcore.icu.TimeZones
+libcore.icu.TimeZones$CachedTimeZones
+libcore.io.IoUtils
+org.apache.commons.logging.Log
org.apache.commons.logging.LogFactory
+org.apache.commons.logging.impl.Jdk14Logger
+org.apache.commons.logging.impl.WeakHashtable
org.apache.harmony.archive.util.Util
org.apache.harmony.dalvik.NativeTestTarget
+org.apache.harmony.dalvik.ddmc.Chunk
org.apache.harmony.dalvik.ddmc.ChunkHandler
org.apache.harmony.dalvik.ddmc.DdmServer
org.apache.harmony.kernel.vm.LangAccess
@@ -1095,166 +1404,432 @@
org.apache.harmony.lang.annotation.AnnotationMember
org.apache.harmony.luni.internal.net.www.protocol.file.FileURLConnection
org.apache.harmony.luni.internal.net.www.protocol.file.Handler
-org.apache.harmony.luni.internal.net.www.protocol.http.Handler
org.apache.harmony.luni.internal.net.www.protocol.jar.Handler
org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnectionImpl
org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnectionImpl$JarURLConnectionInputStream
org.apache.harmony.luni.internal.util.TimezoneGetter
+org.apache.harmony.luni.internal.util.ZoneInfo
org.apache.harmony.luni.internal.util.ZoneInfoDB
-org.apache.harmony.luni.net.GenericIPMreq
org.apache.harmony.luni.net.PlainSocketImpl
-org.apache.harmony.luni.platform.Endianness
-org.apache.harmony.luni.platform.ICommonDataTypes
+org.apache.harmony.luni.net.SocketInputStream
+org.apache.harmony.luni.net.SocketOutputStream
org.apache.harmony.luni.platform.IFileSystem
-org.apache.harmony.luni.platform.IMemorySystem
org.apache.harmony.luni.platform.INetworkSystem
+org.apache.harmony.luni.platform.MappedPlatformAddress
org.apache.harmony.luni.platform.OSFileSystem
org.apache.harmony.luni.platform.OSMemory
org.apache.harmony.luni.platform.OSNetworkSystem
org.apache.harmony.luni.platform.Platform
org.apache.harmony.luni.platform.PlatformAddress
org.apache.harmony.luni.platform.PlatformAddressFactory
+org.apache.harmony.luni.platform.RuntimeMemorySpy
+org.apache.harmony.luni.platform.RuntimeMemorySpy$AddressWrapper
org.apache.harmony.luni.util.FloatingPointParser
org.apache.harmony.luni.util.InputStreamHelper
org.apache.harmony.luni.util.InputStreamHelper$1
org.apache.harmony.luni.util.InputStreamHelper$ExposedByteArrayInputStream
-org.apache.harmony.luni.util.LocaleCache
-org.apache.harmony.luni.util.NumberConverter
org.apache.harmony.luni.util.PriviAction
-org.apache.harmony.luni.util.ThreadLocalCache
-org.apache.harmony.luni.util.ThreadLocalCache$1
-org.apache.harmony.luni.util.ThreadLocalCache$2
-org.apache.harmony.luni.util.ThreadLocalCache$3
-org.apache.harmony.luni.util.ThreadLocalCache$4
-org.apache.harmony.luni.util.ThreadLocalCache$5
+org.apache.harmony.luni.util.TwoKeyHashMap
+org.apache.harmony.luni.util.TwoKeyHashMap$Entry
+org.apache.harmony.luni.util.TwoKeyHashMap$EntryIteratorImpl
+org.apache.harmony.luni.util.TwoKeyHashMap$ValueIteratorImpl
+org.apache.harmony.luni.util.TwoKeyHashMap$ValuesCollectionImpl
org.apache.harmony.luni.util.Util
org.apache.harmony.nio.FileChannelFactory
org.apache.harmony.nio.internal.DirectBuffer
org.apache.harmony.nio.internal.FileChannelImpl
org.apache.harmony.nio.internal.FileChannelImpl$RepositioningLock
-org.apache.harmony.nio.internal.FileLockImpl
org.apache.harmony.nio.internal.LockManager
org.apache.harmony.nio.internal.LockManager$1
+org.apache.harmony.nio.internal.ReadOnlyFileChannel
org.apache.harmony.nio.internal.WriteOnlyFileChannel
-org.apache.harmony.security.asn1.ASN1GeneralizedTime
+org.apache.harmony.security.Util
+org.apache.harmony.security.asn1.ASN1Any
+org.apache.harmony.security.asn1.ASN1Choice
+org.apache.harmony.security.asn1.ASN1Constants
+org.apache.harmony.security.asn1.ASN1Constructured
org.apache.harmony.security.asn1.ASN1Oid
+org.apache.harmony.security.asn1.ASN1Oid$1
+org.apache.harmony.security.asn1.ASN1Primitive
+org.apache.harmony.security.asn1.ASN1Sequence
+org.apache.harmony.security.asn1.ASN1SequenceOf
+org.apache.harmony.security.asn1.ASN1SetOf
org.apache.harmony.security.asn1.ASN1StringType
+org.apache.harmony.security.asn1.ASN1StringType$1
+org.apache.harmony.security.asn1.ASN1StringType$2
+org.apache.harmony.security.asn1.ASN1StringType$3
+org.apache.harmony.security.asn1.ASN1StringType$4
+org.apache.harmony.security.asn1.ASN1StringType$5
+org.apache.harmony.security.asn1.ASN1StringType$6
+org.apache.harmony.security.asn1.ASN1StringType$7
+org.apache.harmony.security.asn1.ASN1Type
+org.apache.harmony.security.asn1.ASN1TypeCollection
+org.apache.harmony.security.asn1.ASN1ValueCollection
+org.apache.harmony.security.asn1.BerInputStream
org.apache.harmony.security.asn1.DerInputStream
-org.apache.harmony.security.asn1.DerOutputStream
org.apache.harmony.security.fortress.Engine
+org.apache.harmony.security.fortress.SecurityAccess
org.apache.harmony.security.fortress.SecurityUtils
org.apache.harmony.security.fortress.Services
-org.apache.harmony.security.pkcs7.ContentInfo
+org.apache.harmony.security.fortress.Services$1
+org.apache.harmony.security.provider.cert.Cache
org.apache.harmony.security.provider.cert.DRLCertFactory
+org.apache.harmony.security.provider.cert.DRLCertFactory$1
org.apache.harmony.security.provider.cert.X509CertFactoryImpl
-org.apache.harmony.security.provider.cert.X509CertImpl
-org.apache.harmony.security.provider.cert.X509CertPathImpl
+org.apache.harmony.security.provider.crypto.CryptoProvider
+org.apache.harmony.security.provider.crypto.CryptoProvider$1
org.apache.harmony.security.provider.crypto.RandomBitsSupplier
+org.apache.harmony.security.provider.crypto.RandomBitsSupplier$1
org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl
+org.apache.harmony.security.provider.crypto.SHA1_Data
org.apache.harmony.security.utils.AlgNameMapper
+org.apache.harmony.security.utils.ObjectIdentifier
org.apache.harmony.security.x501.AttributeTypeAndValue
+org.apache.harmony.security.x501.AttributeTypeAndValue$1
+org.apache.harmony.security.x501.AttributeTypeAndValue$2
+org.apache.harmony.security.x501.AttributeTypeAndValueComparator
+org.apache.harmony.security.x501.AttributeValue
org.apache.harmony.security.x501.DirectoryString
+org.apache.harmony.security.x501.DirectoryString$1
org.apache.harmony.security.x501.Name
-org.apache.harmony.security.x509.AlgorithmIdentifier
-org.apache.harmony.security.x509.BasicConstraints
-org.apache.harmony.security.x509.Certificate
-org.apache.harmony.security.x509.EDIPartyName
-org.apache.harmony.security.x509.Extension
-org.apache.harmony.security.x509.Extensions
+org.apache.harmony.security.x501.Name$1
org.apache.harmony.security.x509.GeneralName
-org.apache.harmony.security.x509.GeneralNames
-org.apache.harmony.security.x509.KeyUsage
-org.apache.harmony.security.x509.ORAddress
-org.apache.harmony.security.x509.OtherName
-org.apache.harmony.security.x509.SubjectPublicKeyInfo
-org.apache.harmony.security.x509.TBSCertificate
-org.apache.harmony.security.x509.Time
-org.apache.harmony.security.x509.Validity
+org.apache.harmony.text.BidiRun
+org.apache.harmony.text.NativeBidi
org.apache.harmony.xml.ExpatAttributes
org.apache.harmony.xml.ExpatParser
+org.apache.harmony.xml.ExpatParser$ClonedAttributes
+org.apache.harmony.xml.ExpatParser$CurrentAttributes
+org.apache.harmony.xml.ExpatParser$ExpatLocator
org.apache.harmony.xml.ExpatPullParser
-org.apache.harmony.xml.parsers.SAXParserFactoryImpl
-org.apache.harmony.xnet.provider.jsse.FileClientSessionCache
+org.apache.harmony.xml.ExpatPullParser$ByteDocument
+org.apache.harmony.xml.ExpatPullParser$Document
+org.apache.harmony.xml.ExpatPullParser$Document$SaxHandler
+org.apache.harmony.xml.ExpatPullParser$EndTagEvent
+org.apache.harmony.xml.ExpatPullParser$Event
+org.apache.harmony.xml.ExpatPullParser$NamespaceStack
+org.apache.harmony.xml.ExpatPullParser$NamespaceStack$Builder
+org.apache.harmony.xml.ExpatPullParser$StartDocumentEvent
+org.apache.harmony.xml.ExpatPullParser$StartTagEvent
+org.apache.harmony.xml.ExpatPullParser$TextEvent
+org.apache.harmony.xml.ExpatReader
+org.apache.harmony.xnet.provider.jsse.AbstractSessionContext
+org.apache.harmony.xnet.provider.jsse.AbstractSessionContext$1
+org.apache.harmony.xnet.provider.jsse.ClientSessionContext
+org.apache.harmony.xnet.provider.jsse.DefaultSSLContextImpl
+org.apache.harmony.xnet.provider.jsse.IndexedPKIXParameters
+org.apache.harmony.xnet.provider.jsse.IndexedPKIXParameters$Bytes
+org.apache.harmony.xnet.provider.jsse.JSSEProvider
+org.apache.harmony.xnet.provider.jsse.JSSEProvider$1
+org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl
+org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl$1
+org.apache.harmony.xnet.provider.jsse.KeyManagerImpl
org.apache.harmony.xnet.provider.jsse.NativeCrypto
-org.apache.harmony.xnet.provider.jsse.OpenSSLServerSocketImpl
-org.apache.harmony.xnet.provider.jsse.OpenSSLSessionImpl
+org.apache.harmony.xnet.provider.jsse.NativeCrypto$SSLHandshakeCallbacks
+org.apache.harmony.xnet.provider.jsse.OpenSSLContextImpl
+org.apache.harmony.xnet.provider.jsse.OpenSSLProvider
+org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl
org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl
-org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$LoggerHolder
org.apache.harmony.xnet.provider.jsse.ProtocolVersion
org.apache.harmony.xnet.provider.jsse.SSLContextImpl
-org.apache.harmony.xnet.provider.jsse.SSLParameters
+org.apache.harmony.xnet.provider.jsse.SSLParametersImpl
org.apache.harmony.xnet.provider.jsse.ServerSessionContext
+org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl
+org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl$1
+org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl$2
+org.apache.harmony.xnet.provider.jsse.TrustManagerImpl
+org.apache.http.ConnectionReuseStrategy
+org.apache.http.FormattedHeader
+org.apache.http.Header
+org.apache.http.HeaderElement
+org.apache.http.HeaderElementIterator
+org.apache.http.HeaderIterator
+org.apache.http.HttpClientConnection
+org.apache.http.HttpConnection
+org.apache.http.HttpConnectionMetrics
+org.apache.http.HttpEntity
+org.apache.http.HttpEntityEnclosingRequest
+org.apache.http.HttpHost
+org.apache.http.HttpInetConnection
+org.apache.http.HttpMessage
+org.apache.http.HttpRequest
+org.apache.http.HttpRequestInterceptor
+org.apache.http.HttpResponse
+org.apache.http.HttpResponseFactory
+org.apache.http.HttpResponseInterceptor
org.apache.http.HttpVersion
+org.apache.http.NameValuePair
+org.apache.http.ProtocolVersion
+org.apache.http.ReasonPhraseCatalog
+org.apache.http.RequestLine
+org.apache.http.StatusLine
+org.apache.http.auth.AuthSchemeFactory
+org.apache.http.auth.AuthSchemeRegistry
+org.apache.http.auth.AuthState
+org.apache.http.client.AuthenticationHandler
+org.apache.http.client.CredentialsProvider
+org.apache.http.client.HttpClient
+org.apache.http.client.HttpRequestRetryHandler
+org.apache.http.client.RedirectHandler
+org.apache.http.client.RequestDirector
+org.apache.http.client.ResponseHandler
+org.apache.http.client.UserTokenHandler
+org.apache.http.client.methods.AbortableHttpRequest
org.apache.http.client.methods.HttpEntityEnclosingRequestBase
-org.apache.http.client.methods.HttpGet
org.apache.http.client.methods.HttpPost
org.apache.http.client.methods.HttpRequestBase
+org.apache.http.client.methods.HttpUriRequest
+org.apache.http.client.params.HttpClientParams
+org.apache.http.client.protocol.RequestAddCookies
+org.apache.http.client.protocol.RequestDefaultHeaders
+org.apache.http.client.protocol.RequestProxyAuthentication
+org.apache.http.client.protocol.RequestTargetAuthentication
+org.apache.http.client.protocol.ResponseProcessCookies
+org.apache.http.client.utils.URIUtils
org.apache.http.conn.BasicManagedEntity
+org.apache.http.conn.ClientConnectionManager
+org.apache.http.conn.ClientConnectionOperator
+org.apache.http.conn.ClientConnectionRequest
+org.apache.http.conn.ConnectionKeepAliveStrategy
+org.apache.http.conn.ConnectionReleaseTrigger
+org.apache.http.conn.EofSensorInputStream
+org.apache.http.conn.EofSensorWatcher
+org.apache.http.conn.ManagedClientConnection
+org.apache.http.conn.OperatedClientConnection
+org.apache.http.conn.params.ConnManagerPNames
org.apache.http.conn.params.ConnManagerParams
+org.apache.http.conn.params.ConnManagerParams$1
+org.apache.http.conn.params.ConnPerRoute
+org.apache.http.conn.params.ConnRoutePNames
org.apache.http.conn.params.ConnRouteParams
+org.apache.http.conn.routing.BasicRouteDirector
org.apache.http.conn.routing.HttpRoute
+org.apache.http.conn.routing.HttpRouteDirector
+org.apache.http.conn.routing.HttpRoutePlanner
+org.apache.http.conn.routing.RouteInfo
+org.apache.http.conn.routing.RouteInfo$LayerType
+org.apache.http.conn.routing.RouteInfo$TunnelType
+org.apache.http.conn.routing.RouteTracker
+org.apache.http.conn.scheme.LayeredSocketFactory
+org.apache.http.conn.scheme.PlainSocketFactory
+org.apache.http.conn.scheme.Scheme
+org.apache.http.conn.scheme.SchemeRegistry
+org.apache.http.conn.scheme.SocketFactory
org.apache.http.conn.ssl.AbstractVerifier
+org.apache.http.conn.ssl.AllowAllHostnameVerifier
+org.apache.http.conn.ssl.BrowserCompatHostnameVerifier
org.apache.http.conn.ssl.SSLSocketFactory
+org.apache.http.conn.ssl.StrictHostnameVerifier
+org.apache.http.conn.ssl.X509HostnameVerifier
org.apache.http.conn.util.InetAddressUtils
+org.apache.http.cookie.CookieSpecFactory
+org.apache.http.cookie.CookieSpecRegistry
+org.apache.http.entity.AbstractHttpEntity
+org.apache.http.entity.BasicHttpEntity
+org.apache.http.entity.ContentLengthStrategy
+org.apache.http.entity.HttpEntityWrapper
org.apache.http.impl.AbstractHttpClientConnection
+org.apache.http.impl.DefaultConnectionReuseStrategy
+org.apache.http.impl.DefaultHttpResponseFactory
org.apache.http.impl.EnglishReasonPhraseCatalog
+org.apache.http.impl.HttpConnectionMetricsImpl
org.apache.http.impl.SocketHttpClientConnection
+org.apache.http.impl.auth.BasicSchemeFactory
+org.apache.http.impl.auth.DigestSchemeFactory
org.apache.http.impl.client.AbstractAuthenticationHandler
org.apache.http.impl.client.AbstractHttpClient
-org.apache.http.impl.client.BasicCookieStore
+org.apache.http.impl.client.BasicCredentialsProvider
+org.apache.http.impl.client.ClientParamsStack
+org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy
org.apache.http.impl.client.DefaultHttpClient
+org.apache.http.impl.client.DefaultHttpRequestRetryHandler
+org.apache.http.impl.client.DefaultProxyAuthenticationHandler
+org.apache.http.impl.client.DefaultRedirectHandler
+org.apache.http.impl.client.DefaultRequestDirector
+org.apache.http.impl.client.DefaultTargetAuthenticationHandler
+org.apache.http.impl.client.DefaultUserTokenHandler
org.apache.http.impl.client.EntityEnclosingRequestWrapper
+org.apache.http.impl.client.RequestWrapper
+org.apache.http.impl.client.RoutedRequest
org.apache.http.impl.conn.AbstractClientConnAdapter
+org.apache.http.impl.conn.AbstractPoolEntry
org.apache.http.impl.conn.AbstractPooledConnAdapter
org.apache.http.impl.conn.DefaultClientConnection
-org.apache.http.impl.conn.SingleClientConnManager
+org.apache.http.impl.conn.DefaultClientConnectionOperator
+org.apache.http.impl.conn.DefaultHttpRoutePlanner
+org.apache.http.impl.conn.DefaultResponseParser
+org.apache.http.impl.conn.IdleConnectionHandler
+org.apache.http.impl.conn.IdleConnectionHandler$TimeValues
+org.apache.http.impl.conn.tsccm.AbstractConnPool
+org.apache.http.impl.conn.tsccm.BasicPoolEntry
+org.apache.http.impl.conn.tsccm.BasicPoolEntryRef
+org.apache.http.impl.conn.tsccm.BasicPooledConnAdapter
org.apache.http.impl.conn.tsccm.ConnPoolByRoute
+org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1
+org.apache.http.impl.conn.tsccm.PoolEntryRequest
+org.apache.http.impl.conn.tsccm.RefQueueHandler
+org.apache.http.impl.conn.tsccm.RefQueueWorker
+org.apache.http.impl.conn.tsccm.RouteSpecificPool
org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager
-org.apache.http.impl.cookie.BasicClientCookie
-org.apache.http.impl.cookie.BrowserCompatSpec
-org.apache.http.impl.cookie.DateUtils
-org.apache.http.impl.cookie.DateUtils$DateFormatHolder
-org.apache.http.impl.cookie.RFC2109Spec
+org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1
+org.apache.http.impl.conn.tsccm.WaitingThreadAborter
+org.apache.http.impl.cookie.BestMatchSpecFactory
+org.apache.http.impl.cookie.BrowserCompatSpecFactory
+org.apache.http.impl.cookie.NetscapeDraftSpecFactory
+org.apache.http.impl.cookie.RFC2109SpecFactory
+org.apache.http.impl.cookie.RFC2965SpecFactory
+org.apache.http.impl.entity.EntityDeserializer
+org.apache.http.impl.entity.EntitySerializer
+org.apache.http.impl.entity.LaxContentLengthStrategy
+org.apache.http.impl.entity.StrictContentLengthStrategy
+org.apache.http.impl.io.AbstractMessageParser
+org.apache.http.impl.io.AbstractMessageWriter
+org.apache.http.impl.io.AbstractSessionInputBuffer
+org.apache.http.impl.io.AbstractSessionOutputBuffer
+org.apache.http.impl.io.ContentLengthInputStream
+org.apache.http.impl.io.ContentLengthOutputStream
+org.apache.http.impl.io.HttpRequestWriter
+org.apache.http.impl.io.HttpTransportMetricsImpl
org.apache.http.impl.io.SocketInputBuffer
-org.apache.http.message.BasicHttpEntityEnclosingRequest
-org.apache.http.message.BasicHttpRequest
+org.apache.http.impl.io.SocketOutputBuffer
+org.apache.http.io.HttpMessageParser
+org.apache.http.io.HttpMessageWriter
+org.apache.http.io.HttpTransportMetrics
+org.apache.http.io.SessionInputBuffer
+org.apache.http.io.SessionOutputBuffer
+org.apache.http.message.AbstractHttpMessage
+org.apache.http.message.BasicHeader
+org.apache.http.message.BasicHeaderElement
+org.apache.http.message.BasicHeaderElementIterator
+org.apache.http.message.BasicHeaderValueParser
org.apache.http.message.BasicHttpResponse
+org.apache.http.message.BasicLineFormatter
org.apache.http.message.BasicLineParser
+org.apache.http.message.BasicListHeaderIterator
org.apache.http.message.BasicNameValuePair
-org.apache.http.message.BasicTokenIterator
+org.apache.http.message.BasicRequestLine
+org.apache.http.message.BasicStatusLine
+org.apache.http.message.BufferedHeader
+org.apache.http.message.HeaderGroup
+org.apache.http.message.HeaderValueParser
+org.apache.http.message.LineFormatter
+org.apache.http.message.LineParser
+org.apache.http.message.ParserCursor
+org.apache.http.params.AbstractHttpParams
org.apache.http.params.BasicHttpParams
+org.apache.http.params.CoreConnectionPNames
+org.apache.http.params.CoreProtocolPNames
+org.apache.http.params.HttpConnectionParams
+org.apache.http.params.HttpParams
+org.apache.http.params.HttpProtocolParams
+org.apache.http.protocol.BasicHttpContext
org.apache.http.protocol.BasicHttpProcessor
org.apache.http.protocol.HTTP
+org.apache.http.protocol.HttpContext
+org.apache.http.protocol.HttpProcessor
+org.apache.http.protocol.HttpRequestExecutor
+org.apache.http.protocol.HttpRequestInterceptorList
+org.apache.http.protocol.HttpResponseInterceptorList
+org.apache.http.protocol.RequestConnControl
+org.apache.http.protocol.RequestContent
+org.apache.http.protocol.RequestExpectContinue
+org.apache.http.protocol.RequestTargetHost
+org.apache.http.protocol.RequestUserAgent
+org.apache.http.util.ByteArrayBuffer
+org.apache.http.util.CharArrayBuffer
+org.apache.http.util.LangUtils
+org.bouncycastle.asn1.ASN1Choice
+org.bouncycastle.asn1.ASN1Collection
+org.bouncycastle.asn1.ASN1Collection$ASN1CollectionEnumeration
+org.bouncycastle.asn1.ASN1Encodable
+org.bouncycastle.asn1.ASN1EncodableVector
+org.bouncycastle.asn1.ASN1InputStream
+org.bouncycastle.asn1.ASN1Null
+org.bouncycastle.asn1.ASN1Object
+org.bouncycastle.asn1.ASN1OctetString
+org.bouncycastle.asn1.ASN1OctetStringParser
+org.bouncycastle.asn1.ASN1OutputStream
+org.bouncycastle.asn1.ASN1Sequence
+org.bouncycastle.asn1.ASN1SequenceParser
+org.bouncycastle.asn1.ASN1Set
+org.bouncycastle.asn1.ASN1StreamParser
+org.bouncycastle.asn1.ASN1TaggedObject
+org.bouncycastle.asn1.ASN1TaggedObjectParser
+org.bouncycastle.asn1.BERTaggedObjectParser
+org.bouncycastle.asn1.DERBitString
+org.bouncycastle.asn1.DERBoolean
+org.bouncycastle.asn1.DEREncodable
+org.bouncycastle.asn1.DEREncodableVector
+org.bouncycastle.asn1.DERFactory
+org.bouncycastle.asn1.DERIA5String
+org.bouncycastle.asn1.DERInteger
org.bouncycastle.asn1.DERNull
org.bouncycastle.asn1.DERObject
org.bouncycastle.asn1.DERObjectIdentifier
+org.bouncycastle.asn1.DEROctetString
+org.bouncycastle.asn1.DEROctetStringParser
+org.bouncycastle.asn1.DEROutputStream
+org.bouncycastle.asn1.DERPrintableString
+org.bouncycastle.asn1.DERSequence
+org.bouncycastle.asn1.DERSequenceParser
+org.bouncycastle.asn1.DERSet
+org.bouncycastle.asn1.DERString
+org.bouncycastle.asn1.DERT61String
+org.bouncycastle.asn1.DERTaggedObject
+org.bouncycastle.asn1.DERTags
+org.bouncycastle.asn1.DERUTCTime
+org.bouncycastle.asn1.DERUTF8String
+org.bouncycastle.asn1.DERUniversalString
+org.bouncycastle.asn1.DefiniteLengthInputStream
+org.bouncycastle.asn1.IndefiniteLengthInputStream
+org.bouncycastle.asn1.LimitedInputStream
+org.bouncycastle.asn1.OIDTokenizer
+org.bouncycastle.asn1.OrderedTable
+org.bouncycastle.asn1.bc.BCObjectIdentifiers
org.bouncycastle.asn1.iana.IANAObjectIdentifiers
org.bouncycastle.asn1.nist.NISTObjectIdentifiers
org.bouncycastle.asn1.oiw.OIWObjectIdentifiers
org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers
+org.bouncycastle.asn1.x509.AlgorithmIdentifier
+org.bouncycastle.asn1.x509.BasicConstraints
+org.bouncycastle.asn1.x509.SubjectPublicKeyInfo
+org.bouncycastle.asn1.x509.TBSCertificateStructure
+org.bouncycastle.asn1.x509.Time
+org.bouncycastle.asn1.x509.X509CertificateStructure
+org.bouncycastle.asn1.x509.X509Extension
org.bouncycastle.asn1.x509.X509Extensions
org.bouncycastle.asn1.x509.X509Name
-org.bouncycastle.crypto.digests.SHA1Digest
+org.bouncycastle.asn1.x509.X509NameElementList
+org.bouncycastle.asn1.x509.X509ObjectIdentifiers
+org.bouncycastle.crypto.Digest
+org.bouncycastle.crypto.ExtendedDigest
+org.bouncycastle.crypto.Mac
+org.bouncycastle.crypto.digests.OpenSSLDigest
+org.bouncycastle.crypto.digests.OpenSSLDigest$SHA1
org.bouncycastle.crypto.engines.AESFastEngine
org.bouncycastle.crypto.macs.HMac
+org.bouncycastle.jce.ProviderConfigurationPermission
+org.bouncycastle.jce.interfaces.BCKeyStore
+org.bouncycastle.jce.interfaces.ConfigurableProvider
+org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier
org.bouncycastle.jce.provider.BouncyCastleProvider
-org.bouncycastle.jce.provider.CertPathValidatorUtilities
-org.bouncycastle.jce.provider.JCEBlockCipher
+org.bouncycastle.jce.provider.BouncyCastleProvider$1
org.bouncycastle.jce.provider.JDKKeyStore
+org.bouncycastle.jce.provider.JDKKeyStore$StoreEntry
org.bouncycastle.jce.provider.JDKX509CertificateFactory
+org.bouncycastle.jce.provider.PEMUtil
+org.bouncycastle.jce.provider.PKCS12BagAttributeCarrierImpl
org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi
-org.bouncycastle.jce.provider.WrapCipherSpi
+org.bouncycastle.jce.provider.ProviderUtil
org.bouncycastle.jce.provider.X509CertificateObject
-org.ccil.cowan.tagsoup.HTMLScanner
-org.ccil.cowan.tagsoup.HTMLSchema
+org.bouncycastle.jce.provider.symmetric.AESMappings
+org.bouncycastle.util.Strings
+org.bouncycastle.util.io.Streams
org.ccil.cowan.tagsoup.Parser
-org.json.JSONObject
-org.kxml2.io.KXmlParser
-org.kxml2.io.KXmlSerializer
org.xml.sax.Attributes
-org.xml.sax.InputSource
-org.xml.sax.helpers.AttributesImpl
-org.xml.sax.helpers.DefaultHandler
+org.xml.sax.ContentHandler
+org.xml.sax.Locator
+org.xml.sax.XMLReader
org.xmlpull.v1.XmlPullParser
-org.xmlpull.v1.XmlPullParserFactory
+org.xmlpull.v1.XmlSerializer
sun.misc.Unsafe
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 775f5c8..8cf8f6a 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -17,7 +17,6 @@
package com.android.server;
import com.android.internal.app.IMediaContainerService;
-import com.android.internal.util.HexDump;
import com.android.server.am.ActivityManagerService;
import android.content.BroadcastReceiver;
@@ -46,13 +45,15 @@
import android.os.storage.IObbActionListener;
import android.os.storage.OnObbStateChangeListener;
import android.os.storage.StorageResultCode;
-import android.security.MessageDigest;
import android.util.Slog;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -62,6 +63,10 @@
import java.util.Map;
import java.util.Map.Entry;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+
/**
* MountService implements back-end services for platform storage
* management.
@@ -154,6 +159,18 @@
final private HashSet<String> mAsecMountSet = new HashSet<String>();
/**
+ * The size of the crypto algorithm key in bits for OBB files. Currently
+ * Twofish is used which takes 128-bit keys.
+ */
+ private static final int CRYPTO_ALGORITHM_KEY_SIZE = 128;
+
+ /**
+ * The number of times to run SHA1 in the PBKDF2 function for OBB files.
+ * 1024 is reasonably secure and not too slow.
+ */
+ private static final int PBKDF2_HASH_ROUNDS = 1024;
+
+ /**
* Mounted OBB tracking information. Used to track the current state of all
* OBBs.
*/
@@ -1901,16 +1918,23 @@
if (mKey == null) {
hashedKey = "none";
} else {
- final MessageDigest md;
try {
- md = MessageDigest.getInstance("MD5");
+ SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
+
+ KeySpec ks = new PBEKeySpec(mKey.toCharArray(), obbInfo.salt,
+ PBKDF2_HASH_ROUNDS, CRYPTO_ALGORITHM_KEY_SIZE);
+ SecretKey key = factory.generateSecret(ks);
+ BigInteger bi = new BigInteger(key.getEncoded());
+ hashedKey = bi.toString(16);
} catch (NoSuchAlgorithmException e) {
- Slog.e(TAG, "Could not load MD5 algorithm", e);
- sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_PERMISSION_DENIED);
+ Slog.e(TAG, "Could not load PBKDF2 algorithm", e);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
+ return;
+ } catch (InvalidKeySpecException e) {
+ Slog.e(TAG, "Invalid key spec when loading PBKDF2 algorithm", e);
+ sendNewStatusOrIgnore(OnObbStateChangeListener.ERROR_INTERNAL);
return;
}
-
- hashedKey = HexDump.toHexString(md.digest(mKey.getBytes()));
}
int rc = StorageResultCode.OperationSucceeded;
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index bc802a8..9d7c58e 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -5156,9 +5156,6 @@
// we don't consider this to be a failure of the core package deletion
}
}
- if (libraryPath != null) {
- NativeLibraryHelper.removeNativeBinariesLI(libraryPath);
- }
}
private boolean setPermissions() {
@@ -7208,6 +7205,8 @@
pw.print(" pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
pw.print(" installStatus="); pw.print(ps.installStatus);
pw.print(" enabled="); pw.println(ps.enabled);
+ pw.print(" versionCode="); pw.print(ps.versionCode);
+ pw.print(" versionName="); pw.println(ps.pkg.mVersionName);
if (ps.disabledComponents.size() > 0) {
pw.println(" disabledComponents:");
for (String s : ps.disabledComponents) {
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 88a4c90..f53ce2d 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -141,9 +141,7 @@
// used for noChangeLights in setPowerState()
private static final int LIGHTS_MASK = SCREEN_BRIGHT_BIT | BUTTON_BRIGHT_BIT | KEYBOARD_BRIGHT_BIT;
- static final boolean ANIMATE_SCREEN_LIGHTS = true;
- static final boolean ANIMATE_BUTTON_LIGHTS = false;
- static final boolean ANIMATE_KEYBOARD_LIGHTS = false;
+ boolean mAnimateScreenLights = true;
static final int ANIM_STEPS = 60/4;
// Slower animation for autobrightness changes
@@ -201,15 +199,12 @@
private UnsynchronizedWakeLock mPreventScreenOnPartialLock;
private UnsynchronizedWakeLock mProximityPartialLock;
private HandlerThread mHandlerThread;
+ private HandlerThread mScreenOffThread;
+ private Handler mScreenOffHandler;
private Handler mHandler;
private final TimeoutTask mTimeoutTask = new TimeoutTask();
- private final LightAnimator mLightAnimator = new LightAnimator();
private final BrightnessState mScreenBrightness
= new BrightnessState(SCREEN_BRIGHT_BIT);
- private final BrightnessState mKeyboardBrightness
- = new BrightnessState(KEYBOARD_BRIGHT_BIT);
- private final BrightnessState mButtonBrightness
- = new BrightnessState(BUTTON_BRIGHT_BIT);
private boolean mStillNeedSleepNotification;
private boolean mIsPowered = false;
private IActivityManager mActivityService;
@@ -261,6 +256,7 @@
private native void nativeInit();
private native void nativeSetPowerState(boolean screenOn, boolean screenBright);
+ private native void nativeStartSurfaceFlingerAnimation();
/*
static PrintStream mLog;
@@ -485,6 +481,35 @@
mKeyboardLight = lights.getLight(LightsService.LIGHT_ID_KEYBOARD);
mAttentionLight = lights.getLight(LightsService.LIGHT_ID_ATTENTION);
+ nativeInit();
+ synchronized (mLocks) {
+ updateNativePowerStateLocked();
+ }
+
+ mInitComplete = false;
+ mScreenOffThread = new HandlerThread("PowerManagerService.mScreenOffThread") {
+ @Override
+ protected void onLooperPrepared() {
+ mScreenOffHandler = new Handler();
+ synchronized (mScreenOffThread) {
+ mInitComplete = true;
+ mScreenOffThread.notifyAll();
+ }
+ }
+ };
+ mScreenOffThread.start();
+
+ synchronized (mScreenOffThread) {
+ while (!mInitComplete) {
+ try {
+ mScreenOffThread.wait();
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+
+ mInitComplete = false;
mHandlerThread = new HandlerThread("PowerManagerService") {
@Override
protected void onLooperPrepared() {
@@ -531,6 +556,9 @@
Resources resources = mContext.getResources();
+ mAnimateScreenLights = resources.getBoolean(
+ com.android.internal.R.bool.config_animateScreenLights);
+
mUnplugTurnsOnScreen = resources.getBoolean(
com.android.internal.R.bool.config_unplugTurnsOnScreen);
@@ -1093,8 +1121,6 @@
pw.println(" mUseSoftwareAutoBrightness=" + mUseSoftwareAutoBrightness);
pw.println(" mAutoBrightessEnabled=" + mAutoBrightessEnabled);
mScreenBrightness.dump(pw, " mScreenBrightness: ");
- mKeyboardBrightness.dump(pw, " mKeyboardBrightness: ");
- mButtonBrightness.dump(pw, " mButtonBrightness: ");
int N = mLocks.size();
pw.println();
@@ -1724,7 +1750,8 @@
// I don't think we need to check the current state here because all of these
// Power.setScreenState and sendNotificationLocked can both handle being
// called multiple times in the same state. -joeo
- EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime, mTouchCycles);
+ EventLog.writeEvent(EventLogTags.POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime,
+ mTouchCycles);
mLastTouchDown = 0;
int err = setScreenStateLocked(false);
if (err == 0) {
@@ -1754,145 +1781,95 @@
int onMask = 0;
int preferredBrightness = getPreferredBrightness();
- boolean startAnimation = false;
if ((difference & KEYBOARD_BRIGHT_BIT) != 0) {
- if (ANIMATE_KEYBOARD_LIGHTS) {
- if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
- mKeyboardBrightness.setTargetLocked(Power.BRIGHTNESS_OFF,
- ANIM_STEPS, INITIAL_KEYBOARD_BRIGHTNESS,
- Power.BRIGHTNESS_ON);
- } else {
- mKeyboardBrightness.setTargetLocked(Power.BRIGHTNESS_ON,
- ANIM_STEPS, INITIAL_KEYBOARD_BRIGHTNESS,
- Power.BRIGHTNESS_OFF);
- }
- startAnimation = true;
+ if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
+ offMask |= KEYBOARD_BRIGHT_BIT;
} else {
- if ((newState & KEYBOARD_BRIGHT_BIT) == 0) {
- offMask |= KEYBOARD_BRIGHT_BIT;
- } else {
- onMask |= KEYBOARD_BRIGHT_BIT;
- }
+ onMask |= KEYBOARD_BRIGHT_BIT;
}
}
if ((difference & BUTTON_BRIGHT_BIT) != 0) {
- if (ANIMATE_BUTTON_LIGHTS) {
- if ((newState & BUTTON_BRIGHT_BIT) == 0) {
- mButtonBrightness.setTargetLocked(Power.BRIGHTNESS_OFF,
- ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- Power.BRIGHTNESS_ON);
- } else {
- mButtonBrightness.setTargetLocked(Power.BRIGHTNESS_ON,
- ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- Power.BRIGHTNESS_OFF);
- }
- startAnimation = true;
+ if ((newState & BUTTON_BRIGHT_BIT) == 0) {
+ offMask |= BUTTON_BRIGHT_BIT;
} else {
- if ((newState & BUTTON_BRIGHT_BIT) == 0) {
- offMask |= BUTTON_BRIGHT_BIT;
- } else {
- onMask |= BUTTON_BRIGHT_BIT;
- }
+ onMask |= BUTTON_BRIGHT_BIT;
}
}
if ((difference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
- if (ANIMATE_SCREEN_LIGHTS) {
- int nominalCurrentValue = -1;
- // If there was an actual difference in the light state, then
- // figure out the "ideal" current value based on the previous
- // state. Otherwise, this is a change due to the brightness
- // override, so we want to animate from whatever the current
- // value is.
- if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
- switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
- case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
- nominalCurrentValue = preferredBrightness;
- break;
- case SCREEN_ON_BIT:
- nominalCurrentValue = Power.BRIGHTNESS_DIM;
- break;
- case 0:
- nominalCurrentValue = Power.BRIGHTNESS_OFF;
- break;
- case SCREEN_BRIGHT_BIT:
- default:
- // not possible
- nominalCurrentValue = (int)mScreenBrightness.curValue;
- break;
- }
+ int nominalCurrentValue = -1;
+ // If there was an actual difference in the light state, then
+ // figure out the "ideal" current value based on the previous
+ // state. Otherwise, this is a change due to the brightness
+ // override, so we want to animate from whatever the current
+ // value is.
+ if ((realDifference & (SCREEN_ON_BIT | SCREEN_BRIGHT_BIT)) != 0) {
+ switch (oldState & (SCREEN_BRIGHT_BIT|SCREEN_ON_BIT)) {
+ case SCREEN_BRIGHT_BIT | SCREEN_ON_BIT:
+ nominalCurrentValue = preferredBrightness;
+ break;
+ case SCREEN_ON_BIT:
+ nominalCurrentValue = Power.BRIGHTNESS_DIM;
+ break;
+ case 0:
+ nominalCurrentValue = Power.BRIGHTNESS_OFF;
+ break;
+ case SCREEN_BRIGHT_BIT:
+ default:
+ // not possible
+ nominalCurrentValue = (int)mScreenBrightness.curValue;
+ break;
}
- int brightness = preferredBrightness;
- int steps = ANIM_STEPS;
- if ((newState & SCREEN_BRIGHT_BIT) == 0) {
- // dim or turn off backlight, depending on if the screen is on
- // the scale is because the brightness ramp isn't linear and this biases
- // it so the later parts take longer.
- final float scale = 1.5f;
- float ratio = (((float)Power.BRIGHTNESS_DIM)/preferredBrightness);
- if (ratio > 1.0f) ratio = 1.0f;
- if ((newState & SCREEN_ON_BIT) == 0) {
- if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
- // was bright
- steps = ANIM_STEPS;
- } else {
- // was dim
- steps = (int)(ANIM_STEPS*ratio*scale);
- }
- brightness = Power.BRIGHTNESS_OFF;
+ }
+ int brightness = preferredBrightness;
+ int steps = ANIM_STEPS;
+ if ((newState & SCREEN_BRIGHT_BIT) == 0) {
+ // dim or turn off backlight, depending on if the screen is on
+ // the scale is because the brightness ramp isn't linear and this biases
+ // it so the later parts take longer.
+ final float scale = 1.5f;
+ float ratio = (((float)Power.BRIGHTNESS_DIM)/preferredBrightness);
+ if (ratio > 1.0f) ratio = 1.0f;
+ if ((newState & SCREEN_ON_BIT) == 0) {
+ if ((oldState & SCREEN_BRIGHT_BIT) != 0) {
+ // was bright
+ steps = ANIM_STEPS;
} else {
- if ((oldState & SCREEN_ON_BIT) != 0) {
- // was bright
- steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
- } else {
- // was dim
- steps = (int)(ANIM_STEPS*ratio);
- }
- if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
- // If the "stay on while plugged in" option is
- // turned on, then the screen will often not
- // automatically turn off while plugged in. To
- // still have a sense of when it is inactive, we
- // will then count going dim as turning off.
- mScreenOffTime = SystemClock.elapsedRealtime();
- }
- brightness = Power.BRIGHTNESS_DIM;
+ // was dim
+ steps = (int)(ANIM_STEPS*ratio*scale);
}
- }
- long identity = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteScreenBrightness(brightness);
- } catch (RemoteException e) {
- // Nothing interesting to do.
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- if (mScreenBrightness.setTargetLocked(brightness,
- steps, INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue)) {
- startAnimation = true;
- }
- } else {
- if ((newState & SCREEN_BRIGHT_BIT) == 0) {
- // dim or turn off backlight, depending on if the screen is on
- if ((newState & SCREEN_ON_BIT) == 0) {
- offMask |= SCREEN_BRIGHT_BIT;
- } else {
- dimMask |= SCREEN_BRIGHT_BIT;
- }
+ brightness = Power.BRIGHTNESS_OFF;
} else {
- onMask |= SCREEN_BRIGHT_BIT;
+ if ((oldState & SCREEN_ON_BIT) != 0) {
+ // was bright
+ steps = (int)(ANIM_STEPS*(1.0f-ratio)*scale);
+ } else {
+ // was dim
+ steps = (int)(ANIM_STEPS*ratio);
+ }
+ if (mStayOnConditions != 0 && mBatteryService.isPowered(mStayOnConditions)) {
+ // If the "stay on while plugged in" option is
+ // turned on, then the screen will often not
+ // automatically turn off while plugged in. To
+ // still have a sense of when it is inactive, we
+ // will then count going dim as turning off.
+ mScreenOffTime = SystemClock.elapsedRealtime();
+ }
+ brightness = Power.BRIGHTNESS_DIM;
}
}
- }
-
- if (startAnimation) {
- if (mSpew) {
- Slog.i(TAG, "Scheduling light animator!");
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteScreenBrightness(brightness);
+ } catch (RemoteException e) {
+ // Nothing interesting to do.
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- mHandler.removeCallbacks(mLightAnimator);
- mHandler.post(mLightAnimator);
+ mScreenBrightness.setTargetLocked(brightness, steps,
+ INITIAL_SCREEN_BRIGHTNESS, nominalCurrentValue);
}
if (offMask != 0) {
@@ -1934,7 +1911,7 @@
}
}
- class BrightnessState {
+ class BrightnessState implements Runnable {
final int mask;
boolean initialized;
@@ -1954,13 +1931,13 @@
+ " delta=" + delta);
}
- boolean setTargetLocked(int target, int stepsToTarget, int initialValue,
+ void setTargetLocked(int target, int stepsToTarget, int initialValue,
int nominalCurrentValue) {
if (!initialized) {
initialized = true;
curValue = (float)initialValue;
} else if (targetValue == target) {
- return false;
+ return;
}
targetValue = target;
delta = (targetValue -
@@ -1974,7 +1951,12 @@
+ noticeMe);
}
animating = true;
- return true;
+
+ if (mSpew) {
+ Slog.i(TAG, "scheduling light animator");
+ }
+ mScreenOffHandler.removeCallbacks(this);
+ mScreenOffHandler.post(this);
}
boolean stepLocked() {
@@ -2000,32 +1982,50 @@
more = false;
}
}
- //Slog.i(TAG, "Animating brightess " + curIntValue + ": " + mask);
+ if (mSpew) Slog.d(TAG, "Animating curIntValue=" + curIntValue + ": " + mask);
setLightBrightness(mask, curIntValue);
+ finishAnimation(more, curIntValue);
+ return more;
+ }
+
+ void jumpToTarget() {
+ if (mSpew) Slog.d(TAG, "jumpToTarget targetValue=" + targetValue + ": " + mask);
+ setLightBrightness(mask, targetValue);
+ final int tv = targetValue;
+ curValue = tv;
+ targetValue = -1;
+ finishAnimation(false, tv);
+ }
+
+ private void finishAnimation(boolean more, int curIntValue) {
animating = more;
if (!more) {
if (mask == SCREEN_BRIGHT_BIT && curIntValue == Power.BRIGHTNESS_OFF) {
screenOffFinishedAnimatingLocked(mScreenOffReason);
}
}
- return more;
}
- }
- private class LightAnimator implements Runnable {
public void run() {
- synchronized (mLocks) {
- long now = SystemClock.uptimeMillis();
- boolean more = mScreenBrightness.stepLocked();
- if (mKeyboardBrightness.stepLocked()) {
- more = true;
+ if (mAnimateScreenLights) {
+ synchronized (mLocks) {
+ long now = SystemClock.uptimeMillis();
+ boolean more = mScreenBrightness.stepLocked();
+ if (more) {
+ mScreenOffHandler.postAtTime(this, now+(1000/60));
+ }
}
- if (mButtonBrightness.stepLocked()) {
- more = true;
+ } else {
+ boolean animate;
+ boolean jump;
+ synchronized (mLocks) {
+ jump = animating; // we haven't already run this animation
+ animate = jump && targetValue == Power.BRIGHTNESS_OFF; // we're turning off
}
- if (more) {
- mHandler.postAtTime(mLightAnimator, now+(1000/60));
+ if (animate) {
+ nativeStartSurfaceFlingerAnimation();
}
+ mScreenBrightness.jumpToTarget();
}
}
}
@@ -2343,49 +2343,15 @@
Slog.d(TAG, "keyboardValue " + keyboardValue);
}
- boolean startAnimation = false;
if (mAutoBrightessEnabled && mScreenBrightnessOverride < 0) {
- if (ANIMATE_SCREEN_LIGHTS) {
- if (mScreenBrightness.setTargetLocked(lcdValue,
- AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_SCREEN_BRIGHTNESS,
- (int)mScreenBrightness.curValue)) {
- startAnimation = true;
- }
- } else {
- int brightnessMode = (mAutoBrightessEnabled
- ? LightsService.BRIGHTNESS_MODE_SENSOR
- : LightsService.BRIGHTNESS_MODE_USER);
- mLcdLight.setBrightness(lcdValue, brightnessMode);
- }
+ mScreenBrightness.setTargetLocked(lcdValue, AUTOBRIGHTNESS_ANIM_STEPS,
+ INITIAL_SCREEN_BRIGHTNESS, (int)mScreenBrightness.curValue);
}
if (mButtonBrightnessOverride < 0) {
- if (ANIMATE_BUTTON_LIGHTS) {
- if (mButtonBrightness.setTargetLocked(buttonValue,
- AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- (int)mButtonBrightness.curValue)) {
- startAnimation = true;
- }
- } else {
- mButtonLight.setBrightness(buttonValue);
- }
+ mButtonLight.setBrightness(buttonValue);
}
if (mButtonBrightnessOverride < 0 || !mKeyboardVisible) {
- if (ANIMATE_KEYBOARD_LIGHTS) {
- if (mKeyboardBrightness.setTargetLocked(keyboardValue,
- AUTOBRIGHTNESS_ANIM_STEPS, INITIAL_BUTTON_BRIGHTNESS,
- (int)mKeyboardBrightness.curValue)) {
- startAnimation = true;
- }
- } else {
- mKeyboardLight.setBrightness(keyboardValue);
- }
- }
- if (startAnimation) {
- if (mDebugLightSensor) {
- Slog.i(TAG, "lightSensorChangedLocked scheduling light animator");
- }
- mHandler.removeCallbacks(mLightAnimator);
- mHandler.post(mLightAnimator);
+ mKeyboardLight.setBrightness(keyboardValue);
}
}
}
@@ -2753,6 +2719,7 @@
}
}
+ // for watchdog
public void monitor() {
synchronized (mLocks) { }
}
@@ -2772,34 +2739,23 @@
public void setBacklightBrightness(int brightness) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
// Don't let applications turn the screen all the way off
- brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
- mLcdLight.setBrightness(brightness);
- mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
- mButtonLight.setBrightness(brightness);
- long identity = Binder.clearCallingIdentity();
- try {
- mBatteryStats.noteScreenBrightness(brightness);
- } catch (RemoteException e) {
- Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ synchronized (mLocks) {
+ brightness = Math.max(brightness, Power.BRIGHTNESS_DIM);
+ mLcdLight.setBrightness(brightness);
+ mKeyboardLight.setBrightness(mKeyboardVisible ? brightness : 0);
+ mButtonLight.setBrightness(brightness);
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mBatteryStats.noteScreenBrightness(brightness);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException calling noteScreenBrightness on BatteryStatsService", e);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
- // update our animation state
- if (ANIMATE_SCREEN_LIGHTS) {
- mScreenBrightness.curValue = brightness;
- mScreenBrightness.animating = false;
- mScreenBrightness.targetValue = -1;
- }
- if (ANIMATE_KEYBOARD_LIGHTS) {
- mKeyboardBrightness.curValue = brightness;
- mKeyboardBrightness.animating = false;
- mKeyboardBrightness.targetValue = -1;
- }
- if (ANIMATE_BUTTON_LIGHTS) {
- mButtonBrightness.curValue = brightness;
- mButtonBrightness.animating = false;
- mButtonBrightness.targetValue = -1;
+ // update our animation state
+ mScreenBrightness.targetValue = brightness;
+ mScreenBrightness.jumpToTarget();
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 26071ae..a2a5e67 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -17,6 +17,7 @@
package com.android.server;
import com.android.server.am.ActivityManagerService;
+import com.android.internal.app.ShutdownThread;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.SamplingProfilerIntegration;
import com.trustedlogic.trustednfc.android.server.NfcService;
@@ -89,6 +90,24 @@
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setCanSelfBackground(false);
+ // Check whether we failed to shut down last time we tried.
+ {
+ final String shutdownAction = SystemProperties.get(
+ ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
+ if (shutdownAction != null && shutdownAction.length() > 0) {
+ boolean reboot = (shutdownAction.charAt(0) == '1');
+
+ final String reason;
+ if (shutdownAction.length() > 1) {
+ reason = shutdownAction.substring(1, shutdownAction.length());
+ } else {
+ reason = null;
+ }
+
+ ShutdownThread.rebootOrShutdown(reboot, reason);
+ }
+ }
+
String factoryTestStr = SystemProperties.get("ro.factorytest");
int factoryTest = "".equals(factoryTestStr) ? SystemServer.FACTORY_TEST_OFF
: Integer.parseInt(factoryTestStr);
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 016ddcd..86c7bdf 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -2535,7 +2535,7 @@
mWaitingActivityLaunched.add(outResult);
do {
try {
- wait();
+ mService.wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
@@ -2551,7 +2551,7 @@
mWaitingActivityVisible.add(outResult);
do {
try {
- wait();
+ mService.wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
diff --git a/services/java/com/trustedlogic/trustednfc/android/server/NfcService.java b/services/java/com/trustedlogic/trustednfc/android/server/NfcService.java
index 431b798..bddbafc 100644
--- a/services/java/com/trustedlogic/trustednfc/android/server/NfcService.java
+++ b/services/java/com/trustedlogic/trustednfc/android/server/NfcService.java
@@ -17,44 +17,43 @@
package com.trustedlogic.trustednfc.android.server;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
-import java.util.Set;
-import com.trustedlogic.trustednfc.android.ILlcpConnectionlessSocket;
-import com.trustedlogic.trustednfc.android.ILlcpServiceSocket;
-import com.trustedlogic.trustednfc.android.INfcManager;
-import com.trustedlogic.trustednfc.android.ILlcpSocket;
-import com.trustedlogic.trustednfc.android.INfcTag;
-import com.trustedlogic.trustednfc.android.IP2pInitiator;
-import com.trustedlogic.trustednfc.android.IP2pTarget;
-import com.trustedlogic.trustednfc.android.LlcpPacket;
-import com.trustedlogic.trustednfc.android.NdefMessage;
-import com.trustedlogic.trustednfc.android.NfcException;
-import com.trustedlogic.trustednfc.android.NfcManager;
+import android.nfc.ErrorCodes;
+import android.nfc.FormatException;
+import android.nfc.ILlcpConnectionlessSocket;
+import android.nfc.ILlcpServiceSocket;
+import android.nfc.INfcAdapter;
+import android.nfc.ILlcpSocket;
+import android.nfc.INfcTag;
+import android.nfc.IP2pInitiator;
+import android.nfc.IP2pTarget;
+import android.nfc.LlcpPacket;
+import android.nfc.NdefMessage;
+import android.nfc.Tag;
+//import android.nfc.NfcException;
+//import android.nfc.NfcManager;
+import android.nfc.NfcAdapter;
import com.trustedlogic.trustednfc.android.internal.NativeLlcpConnectionlessSocket;
import com.trustedlogic.trustednfc.android.internal.NativeLlcpServiceSocket;
import com.trustedlogic.trustednfc.android.internal.NativeLlcpSocket;
import com.trustedlogic.trustednfc.android.internal.NativeNfcManager;
import com.trustedlogic.trustednfc.android.internal.NativeNfcTag;
import com.trustedlogic.trustednfc.android.internal.NativeP2pDevice;
-import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
-
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-public class NfcService extends INfcManager.Stub implements Runnable {
+public class NfcService extends INfcAdapter.Stub implements Runnable {
/**
* NFC Service tag
@@ -188,15 +187,15 @@
private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip";
- private Context mContext;
+ private final Context mContext;
- private HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
+ private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
- private HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
+ private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
- private LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>();
+ private final LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>();
- private int mLlcpLinkState = NfcManager.LLCP_LINK_STATE_DEACTIVATED;
+ private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
private int mGeneratedSocketHandle = 0;
@@ -216,9 +215,42 @@
private boolean mOpenPending = false;
- private NativeNfcManager mManager;
+ private final NativeNfcManager mManager;
- private ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() {
+ private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() {
+
+ private final int CONNECT_FLAG = 0x01;
+ private final int CLOSE_FLAG = 0x02;
+ private final int RECV_FLAG = 0x04;
+ private final int SEND_FLAG = 0x08;
+
+ private int concurrencyFlags;
+ private Object sync;
+
+ private void enterCritical(int mask, int current) {
+ int result = -1;
+ try {
+ while (result != 0) {
+ synchronized(this) {
+ result = concurrencyFlags & mask;
+ }
+ sync.wait();
+ }
+ }
+ catch(InterruptedException e) {
+ }
+ // Set flag
+ concurrencyFlags |= current;
+ }
+
+ private void leaveCritical(int current) {
+ synchronized(this) {
+ // Clear flag
+ concurrencyFlags &= ~current;
+ }
+ // Release waiting threads
+ sync.notifyAll();
+ }
public int close(int nativeHandle) throws RemoteException {
NativeLlcpSocket socket = null;
@@ -232,7 +264,7 @@
/* find the socket in the hmap */
socket = (NativeLlcpSocket) findSocket(nativeHandle);
if (socket != null) {
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_ACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
isSuccess = socket.doClose();
if (isSuccess) {
/* Remove the socket closed from the hmap */
@@ -476,7 +508,7 @@
};
- private ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() {
+ private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() {
public int accept(int nativeHandle) throws RemoteException {
NativeLlcpServiceSocket socket = null;
@@ -522,7 +554,7 @@
/* find the socket in the hmap */
socket = (NativeLlcpServiceSocket) findSocket(nativeHandle);
if (socket != null) {
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_ACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
isSuccess = socket.doClose();
if (isSuccess) {
/* Remove the socket closed from the hmap */
@@ -571,7 +603,7 @@
}
};
- private ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() {
+ private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() {
public void close(int nativeHandle) throws RemoteException {
NativeLlcpConnectionlessSocket socket = null;
@@ -585,7 +617,7 @@
/* find the socket in the hmap */
socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle);
if (socket != null) {
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_ACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
isSuccess = socket.doClose();
if (isSuccess) {
/* Remove the socket closed from the hmap */
@@ -669,7 +701,7 @@
}
};
- private INfcTag mNfcTagService = new INfcTag.Stub() {
+ private final INfcTag mNfcTagService = new INfcTag.Stub() {
public int close(int nativeHandle) throws RemoteException {
NativeNfcTag tag = null;
@@ -807,34 +839,55 @@
/* Create an NdefMessage */
try {
return new NdefMessage(buf);
- } catch (NfcException e) {
+ } catch (FormatException e) {
return null;
}
}
return null;
}
- public boolean write(int nativeHandle, NdefMessage msg) throws RemoteException {
+ public int write(int nativeHandle, NdefMessage msg) throws RemoteException {
NativeNfcTag tag;
- boolean isSuccess = false;
// Check if NFC is enabled
if (!mIsNfcEnabled) {
- return isSuccess;
+ return ErrorCodes.ERROR_NOT_INITIALIZED;
}
/* find the tag in the hmap */
tag = (NativeNfcTag) findObject(nativeHandle);
- if (tag != null) {
- isSuccess = tag.doWrite(msg.toByteArray());
+ if (tag == null) {
+ return ErrorCodes.ERROR_IO;
}
- return isSuccess;
+
+ if (tag.doWrite(msg.toByteArray())) {
+ return ErrorCodes.SUCCESS;
+ }
+ else {
+ return ErrorCodes.ERROR_IO;
+ }
}
+ public int getLastError(int nativeHandle) throws RemoteException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int getModeHint(int nativeHandle) throws RemoteException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public int makeReadOnly(int nativeHandle) throws RemoteException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+
};
- private IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() {
+ private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() {
public byte[] getGeneralBytes(int nativeHandle) throws RemoteException {
NativeP2pDevice device;
@@ -911,7 +964,7 @@
}
};
- private IP2pTarget mP2pTargetService = new IP2pTarget.Stub() {
+ private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() {
public int connect(int nativeHandle) throws RemoteException {
NativeP2pDevice device;
@@ -1033,8 +1086,8 @@
NativeNfcManager.INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION));
mContext.registerReceiver(mNfcServiceReceiver, new IntentFilter(
- NfcManager.LLCP_LINK_STATE_CHANGED_ACTION));
-
+ NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED));
+
mContext.registerReceiver(mNfcServiceReceiver, new IntentFilter(
NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION));
@@ -1088,7 +1141,7 @@
/* Store the socket handle */
int sockeHandle = mGeneratedSocketHandle;
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_ACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
NativeLlcpConnectionlessSocket socket;
socket = mManager.doCreateLlcpConnectionlessSocket(sap);
@@ -1167,7 +1220,7 @@
if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) {
int sockeHandle = mGeneratedSocketHandle;
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_ACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
NativeLlcpServiceSocket socket;
socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
@@ -1251,7 +1304,7 @@
int sockeHandle = mGeneratedSocketHandle;
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_ACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
NativeLlcpSocket socket;
socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
@@ -1333,7 +1386,7 @@
mManager.doDeselectSecureElement(mSelectedSeId);
mNfcSecureElementState = 0;
mSelectedSeId = 0;
-
+
/* Store that a secure element is deselected */
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.NFC_SECURE_ELEMENT_ON, 0);
@@ -1341,9 +1394,9 @@
/* Reset Secure Element ID */
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.NFC_SECURE_ELEMENT_ID, 0);
-
- return ErrorCodes.SUCCESS;
+
+ return ErrorCodes.SUCCESS;
}
public boolean disable() throws RemoteException {
@@ -1615,30 +1668,10 @@
}
- public int openTagConnection() throws RemoteException {
- NativeNfcTag tag;
- // Check if NFC is enabled
- if (!mIsNfcEnabled) {
- return ErrorCodes.ERROR_NOT_INITIALIZED;
- }
+ public void openTagConnection(Tag tag) throws RemoteException {
+ NativeNfcTag nativeTag = new NativeNfcTag(tag.getHandle(), "", tag.getId());
- mContext.enforceCallingPermission(android.Manifest.permission.NFC_RAW,
- "NFC_RAW permission required to open NFC Tag connection");
- if (!mOpenPending) {
- mOpenPending = true;
- tag = mManager.doOpenTagConnection(mTimeout);
- if (tag != null) {
- mObjectMap.put(tag.getHandle(), tag);
- return tag.getHandle();
- } else {
- mOpenPending = false;
- /* Restart polling loop for notification */
- mManager.enableDiscovery(DISCOVERY_MODE_READER);
- return ErrorCodes.ERROR_IO;
- }
- } else {
- return ErrorCodes.ERROR_BUSY;
- }
+ mObjectMap.put(nativeTag.getHandle(), nativeTag);
}
public int selectSecureElement(int seId) throws RemoteException {
@@ -1646,7 +1679,7 @@
if (!mIsNfcEnabled) {
return ErrorCodes.ERROR_NOT_INITIALIZED;
}
-
+
if (mSelectedSeId == seId) {
return ErrorCodes.ERROR_SE_ALREADY_SELECTED;
}
@@ -1668,7 +1701,7 @@
/* Store the ID of the Secure Element Selected */
Settings.System.putInt(mContext.getContentResolver(),
Settings.System.NFC_SECURE_ELEMENT_ID, mSelectedSeId);
-
+
mNfcSecureElementState = 1;
return ErrorCodes.SUCCESS;
@@ -1847,6 +1880,16 @@
return ErrorCodes.SUCCESS;
}
+ public NdefMessage localGet() throws RemoteException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void localSet(NdefMessage message) throws RemoteException {
+ // TODO Auto-generated method stub
+
+ }
+
// Reset all internals
private void reset() {
@@ -1856,7 +1899,7 @@
mRegisteredSocketList.clear();
// Reset variables
- mLlcpLinkState = NfcManager.LLCP_LINK_STATE_DEACTIVATED;
+ mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
mNbSocketCreated = 0;
mIsNfcEnabled = false;
mSelectedSeId = 0;
@@ -1869,6 +1912,9 @@
Object device = null;
device = mObjectMap.get(key);
+ if (device == null) {
+ Log.w(TAG, "Handle not found !");
+ }
return device;
}
@@ -1947,11 +1993,11 @@
* LLCP link in not activated
*/
private class RegisteredSocket {
- private int mType;
+ private final int mType;
- private int mHandle;
+ private final int mHandle;
- private int mSap;
+ private final int mSap;
private int mMiu;
@@ -1988,17 +2034,17 @@
}
}
- private BroadcastReceiver mNfcServiceReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mNfcServiceReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Internal NFC Intent received");
/* LLCP Link deactivation */
- if (intent.getAction().equals(NfcManager.LLCP_LINK_STATE_CHANGED_ACTION)) {
- mLlcpLinkState = intent.getIntExtra(NfcManager.LLCP_LINK_STATE_CHANGED_EXTRA,
- NfcManager.LLCP_LINK_STATE_DEACTIVATED);
+ if (intent.getAction().equals(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED)) {
+ mLlcpLinkState = intent.getIntExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
+ NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_DEACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_DEACTIVATED) {
/* restart polling loop */
mManager.enableDiscovery(DISCOVERY_MODE_READER);
}
@@ -2010,9 +2056,9 @@
mLlcpLinkState = intent.getIntExtra(
NativeNfcManager.INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
- NfcManager.LLCP_LINK_STATE_DEACTIVATED);
+ NfcAdapter.LLCP_LINK_STATE_DEACTIVATED);
- if (mLlcpLinkState == NfcManager.LLCP_LINK_STATE_ACTIVATED) {
+ if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) {
/* check if sockets are registered */
ListIterator<RegisteredSocket> it = mRegisteredSocketList.listIterator();
@@ -2086,16 +2132,16 @@
/* Broadcast Intent Link LLCP activated */
Intent LlcpLinkIntent = new Intent();
- LlcpLinkIntent.setAction(NfcManager.LLCP_LINK_STATE_CHANGED_ACTION);
+ LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
- LlcpLinkIntent.putExtra(NfcManager.LLCP_LINK_STATE_CHANGED_EXTRA,
- NfcManager.LLCP_LINK_STATE_ACTIVATED);
+ LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED,
+ NfcAdapter.LLCP_LINK_STATE_ACTIVATED);
Log.d(TAG, "Broadcasting LLCP activation");
mContext.sendOrderedBroadcast(LlcpLinkIntent,
android.Manifest.permission.NFC_LLCP);
}
- }
+ }
/* Target Deactivated */
else if (intent.getAction().equals(
NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) {
@@ -2104,8 +2150,8 @@
}
/* Restart polling loop for notification */
mManager.enableDiscovery(DISCOVERY_MODE_READER);
-
+
}
}
};
-}
+}
\ No newline at end of file
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index cdc0a6f..c90879d 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -23,7 +23,8 @@
libnativehelper \
libsystem_server \
libutils \
- libui
+ libui \
+ libsurfaceflinger_client
ifeq ($(TARGET_SIMULATOR),true)
ifeq ($(TARGET_OS),linux)
diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp
index 146c177..2ec20bd 100644
--- a/services/jni/com_android_server_PowerManagerService.cpp
+++ b/services/jni/com_android_server_PowerManagerService.cpp
@@ -20,9 +20,14 @@
#include "JNIHelp.h"
#include "jni.h"
+
#include <limits.h>
+
#include <android_runtime/AndroidRuntime.h>
#include <utils/Timers.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
#include "com_android_server_PowerManagerService.h"
namespace android {
@@ -119,6 +124,12 @@
gScreenBright = screenBright;
}
+static void android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation(JNIEnv* env,
+ jobject obj) {
+ sp<ISurfaceComposer> s(ComposerService::getComposerService());
+ s->turnElectronBeamOff(0);
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gPowerManagerServiceMethods[] = {
@@ -127,6 +138,8 @@
(void*) android_server_PowerManagerService_nativeInit },
{ "nativeSetPowerState", "(ZZ)V",
(void*) android_server_PowerManagerService_nativeSetPowerState },
+ { "nativeStartSurfaceFlingerAnimation", "()V",
+ (void*) android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation },
};
#define FIND_CLASS(var, className) \
diff --git a/services/jni/com_android_server_location_GpsLocationProvider.cpp b/services/jni/com_android_server_location_GpsLocationProvider.cpp
index 43e8467..1d93f82 100755
--- a/services/jni/com_android_server_location_GpsLocationProvider.cpp
+++ b/services/jni/com_android_server_location_GpsLocationProvider.cpp
@@ -590,9 +590,7 @@
jboolean connected, int type, jboolean roaming, jstring extraInfo)
{
const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
- if (interface &&
- (interface->size > ((char *)&interface->update_network_state - (char *)&interface)) &&
- interface->update_network_state) {
+ if (interface && interface->update_network_state) {
if (extraInfo) {
const char *extraInfoStr = env->GetStringUTFChars(extraInfo, NULL);
interface->update_network_state(connected, type, roaming, extraInfoStr);
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
index 1d09f84..90865da 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -359,7 +359,7 @@
DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
uint32_t displayIndex)
- : mCanDraw(true)
+ : mCanDraw(true), mScreenAcquired(true)
{
mDisplayEventThread = new DisplayEventThread(flinger);
if (mDisplayEventThread->initCheck() != NO_ERROR) {
@@ -374,18 +374,21 @@
mDisplayEventThread->requestExitAndWait();
}
+void DisplayHardwareBase::setCanDraw(bool canDraw)
+{
+ mCanDraw = canDraw;
+}
bool DisplayHardwareBase::canDraw() const
{
- return mCanDraw;
+ return mCanDraw && mScreenAcquired;
}
void DisplayHardwareBase::releaseScreen() const
{
status_t err = mDisplayEventThread->releaseScreen();
if (err >= 0) {
- //LOGD("screen given-up");
- mCanDraw = false;
+ mScreenAcquired = false;
}
}
@@ -393,9 +396,13 @@
{
status_t err = mDisplayEventThread->acquireScreen();
if (err >= 0) {
- //LOGD("screen returned");
- mCanDraw = true;
+ mScreenAcquired = true;
}
}
+bool DisplayHardwareBase::isScreenAcquired() const
+{
+ return mScreenAcquired;
+}
+
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
index 8369bb8..fa6a0c4 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
@@ -40,7 +40,11 @@
// console managment
void releaseScreen() const;
void acquireScreen() const;
+ bool isScreenAcquired() const;
+
bool canDraw() const;
+ void setCanDraw(bool canDraw);
+
private:
class DisplayEventThreadBase : public Thread {
@@ -89,6 +93,7 @@
sp<DisplayEventThreadBase> mDisplayEventThread;
mutable int mCanDraw;
+ mutable int mScreenAcquired;
};
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e5e87c6..3734969 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -80,6 +80,7 @@
mVisibleRegionsDirty(false),
mDeferReleaseConsole(false),
mFreezeDisplay(false),
+ mElectronBeamAnimation(false),
mFreezeCount(0),
mFreezeDisplayTime(0),
mDebugRegion(0),
@@ -421,16 +422,20 @@
int what = android_atomic_and(0, &mConsoleSignals);
if (what & eConsoleAcquired) {
hw.acquireScreen();
+ // this is a temporary work-around, eventually this should be called
+ // by the power-manager
+ if (mElectronBeamAnimation)
+ SurfaceFlinger::turnElectronBeamOn(0);
}
- if (mDeferReleaseConsole && hw.canDraw()) {
+ if (mDeferReleaseConsole && hw.isScreenAcquired()) {
// We got the release signal before the acquire signal
mDeferReleaseConsole = false;
hw.releaseScreen();
}
if (what & eConsoleReleased) {
- if (hw.canDraw()) {
+ if (hw.isScreenAcquired()) {
hw.releaseScreen();
} else {
mDeferReleaseConsole = true;
@@ -1456,6 +1461,8 @@
case FREEZE_DISPLAY:
case UNFREEZE_DISPLAY:
case BOOT_FINISHED:
+ case TURN_ELECTRON_BEAM_OFF:
+ case TURN_ELECTRON_BEAM_ON:
{
// codes that require permission check
IPCThreadState* ipc = IPCThreadState::self();
@@ -1546,6 +1553,446 @@
// ---------------------------------------------------------------------------
+status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
+ GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
+{
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
+ // get screen geometry
+ const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
+ const uint32_t hw_w = hw.getWidth();
+ const uint32_t hw_h = hw.getHeight();
+ GLfloat u = 1;
+ GLfloat v = 1;
+
+ // make sure to clear all GL error flags
+ while ( glGetError() != GL_NO_ERROR ) ;
+
+ // create a FBO
+ GLuint name, tname;
+ glGenTextures(1, &tname);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+ hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
+ if (glGetError() != GL_NO_ERROR) {
+ GLint tw = (2 << (31 - clz(hw_w)));
+ GLint th = (2 << (31 - clz(hw_h)));
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+ tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
+ u = GLfloat(hw_w) / tw;
+ v = GLfloat(hw_h) / th;
+ }
+ glGenFramebuffersOES(1, &name);
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+ glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
+ GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
+
+ // redraw the screen entirely...
+ glClearColor(0,0,0,1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const size_t count = layers.size();
+ for (size_t i=0 ; i<count ; ++i) {
+ const sp<LayerBase>& layer(layers[i]);
+ layer->drawForSreenShot();
+ }
+
+ // back to main framebuffer
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+ glDisable(GL_SCISSOR_TEST);
+ glDeleteFramebuffersOES(1, &name);
+
+ *textureName = tname;
+ *uOut = u;
+ *vOut = v;
+ return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
+{
+ status_t result = PERMISSION_DENIED;
+
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
+ // get screen geometry
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const uint32_t hw_w = hw.getWidth();
+ const uint32_t hw_h = hw.getHeight();
+ const Region screenBounds(hw.bounds());
+
+ GLfloat u, v;
+ GLuint tname;
+ result = renderScreenToTextureLocked(0, &tname, &u, &v);
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ GLfloat vtx[8];
+ const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, vtx);
+
+ class s_curve_interpolator {
+ const float nbFrames, s, v;
+ public:
+ s_curve_interpolator(int nbFrames, float s)
+ : nbFrames(1.0f / (nbFrames-1)), s(s),
+ v(1.0f + expf(-s + 0.5f*s)) {
+ }
+ float operator()(int f) {
+ const float x = f * nbFrames;
+ return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
+ }
+ };
+
+ class v_stretch {
+ const GLfloat hw_w, hw_h;
+ public:
+ v_stretch(uint32_t hw_w, uint32_t hw_h)
+ : hw_w(hw_w), hw_h(hw_h) {
+ }
+ void operator()(GLfloat* vtx, float v) {
+ const GLfloat w = hw_w + (hw_w * v);
+ const GLfloat h = hw_h - (hw_h * v);
+ const GLfloat x = (hw_w - w) * 0.5f;
+ const GLfloat y = (hw_h - h) * 0.5f;
+ vtx[0] = x; vtx[1] = y;
+ vtx[2] = x; vtx[3] = y + h;
+ vtx[4] = x + w; vtx[5] = y + h;
+ vtx[6] = x + w; vtx[7] = y;
+ }
+ };
+
+ class h_stretch {
+ const GLfloat hw_w, hw_h;
+ public:
+ h_stretch(uint32_t hw_w, uint32_t hw_h)
+ : hw_w(hw_w), hw_h(hw_h) {
+ }
+ void operator()(GLfloat* vtx, float v) {
+ const GLfloat w = hw_w - (hw_w * v);
+ const GLfloat h = 1.0f;
+ const GLfloat x = (hw_w - w) * 0.5f;
+ const GLfloat y = (hw_h - h) * 0.5f;
+ vtx[0] = x; vtx[1] = y;
+ vtx[2] = x; vtx[3] = y + h;
+ vtx[4] = x + w; vtx[5] = y + h;
+ vtx[6] = x + w; vtx[7] = y;
+ }
+ };
+
+ // the full animation is 24 frames
+ const int nbFrames = 12;
+ s_curve_interpolator itr(nbFrames, 7.5f);
+ s_curve_interpolator itg(nbFrames, 8.0f);
+ s_curve_interpolator itb(nbFrames, 8.5f);
+
+ v_stretch vverts(hw_w, hw_h);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ for (int i=0 ; i<nbFrames ; i++) {
+ float x, y, w, h;
+ const float vr = itr(i);
+ const float vg = itg(i);
+ const float vb = itb(i);
+
+ // clear screen
+ glColorMask(1,1,1,1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glEnable(GL_TEXTURE_2D);
+
+ // draw the red plane
+ vverts(vtx, vr);
+ glColorMask(1,0,0,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the green plane
+ vverts(vtx, vg);
+ glColorMask(0,1,0,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the blue plane
+ vverts(vtx, vb);
+ glColorMask(0,0,1,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the white highlight (we use the last vertices)
+ glDisable(GL_TEXTURE_2D);
+ glColorMask(1,1,1,1);
+ glColor4f(vg, vg, vg, 1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ hw.flip(screenBounds);
+ }
+
+ h_stretch hverts(hw_w, hw_h);
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glColorMask(1,1,1,1);
+ for (int i=0 ; i<nbFrames ; i++) {
+ const float v = itg(i);
+ hverts(vtx, v);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor4f(1-v, 1-v, 1-v, 1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ hw.flip(screenBounds);
+ }
+
+ glColorMask(1,1,1,1);
+ glEnable(GL_SCISSOR_TEST);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDeleteTextures(1, &tname);
+ return NO_ERROR;
+}
+
+status_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
+{
+ status_t result = PERMISSION_DENIED;
+
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
+
+ // get screen geometry
+ const DisplayHardware& hw(graphicPlane(0).displayHardware());
+ const uint32_t hw_w = hw.getWidth();
+ const uint32_t hw_h = hw.getHeight();
+ const Region screenBounds(hw.bounds());
+
+ GLfloat u, v;
+ GLuint tname;
+ result = renderScreenToTextureLocked(0, &tname, &u, &v);
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ // back to main framebuffer
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+ glDisable(GL_SCISSOR_TEST);
+
+ GLfloat vtx[8];
+ const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tname);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, vtx);
+
+ class s_curve_interpolator {
+ const float nbFrames, s, v;
+ public:
+ s_curve_interpolator(int nbFrames, float s)
+ : nbFrames(1.0f / (nbFrames-1)), s(s),
+ v(1.0f + expf(-s + 0.5f*s)) {
+ }
+ float operator()(int f) {
+ const float x = f * nbFrames;
+ return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
+ }
+ };
+
+ class v_stretch {
+ const GLfloat hw_w, hw_h;
+ public:
+ v_stretch(uint32_t hw_w, uint32_t hw_h)
+ : hw_w(hw_w), hw_h(hw_h) {
+ }
+ void operator()(GLfloat* vtx, float v) {
+ const GLfloat w = hw_w + (hw_w * v);
+ const GLfloat h = hw_h - (hw_h * v);
+ const GLfloat x = (hw_w - w) * 0.5f;
+ const GLfloat y = (hw_h - h) * 0.5f;
+ vtx[0] = x; vtx[1] = y;
+ vtx[2] = x; vtx[3] = y + h;
+ vtx[4] = x + w; vtx[5] = y + h;
+ vtx[6] = x + w; vtx[7] = y;
+ }
+ };
+
+ class h_stretch {
+ const GLfloat hw_w, hw_h;
+ public:
+ h_stretch(uint32_t hw_w, uint32_t hw_h)
+ : hw_w(hw_w), hw_h(hw_h) {
+ }
+ void operator()(GLfloat* vtx, float v) {
+ const GLfloat w = hw_w - (hw_w * v);
+ const GLfloat h = 1.0f;
+ const GLfloat x = (hw_w - w) * 0.5f;
+ const GLfloat y = (hw_h - h) * 0.5f;
+ vtx[0] = x; vtx[1] = y;
+ vtx[2] = x; vtx[3] = y + h;
+ vtx[4] = x + w; vtx[5] = y + h;
+ vtx[6] = x + w; vtx[7] = y;
+ }
+ };
+
+ // the full animation is 24 frames
+ const int nbFrames = 12;
+ s_curve_interpolator itr(nbFrames, 7.5f);
+ s_curve_interpolator itg(nbFrames, 8.0f);
+ s_curve_interpolator itb(nbFrames, 8.5f);
+
+ h_stretch hverts(hw_w, hw_h);
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glColorMask(1,1,1,1);
+ for (int i=nbFrames-1 ; i>=0 ; i--) {
+ const float v = itg(i);
+ hverts(vtx, v);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glColor4f(1-v, 1-v, 1-v, 1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ hw.flip(screenBounds);
+ }
+
+ v_stretch vverts(hw_w, hw_h);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_ONE, GL_ONE);
+ for (int i=nbFrames-1 ; i>=0 ; i--) {
+ float x, y, w, h;
+ const float vr = itr(i);
+ const float vg = itg(i);
+ const float vb = itb(i);
+
+ // clear screen
+ glColorMask(1,1,1,1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glEnable(GL_TEXTURE_2D);
+
+ // draw the red plane
+ vverts(vtx, vr);
+ glColorMask(1,0,0,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the green plane
+ vverts(vtx, vg);
+ glColorMask(0,1,0,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ // draw the blue plane
+ vverts(vtx, vb);
+ glColorMask(0,0,1,1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ hw.flip(screenBounds);
+ }
+
+ glColorMask(1,1,1,1);
+ glEnable(GL_SCISSOR_TEST);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDeleteTextures(1, &tname);
+
+ return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::turnElectronBeamOffImplLocked()
+{
+ DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
+ if (!hw.canDraw()) {
+ // we're already off
+ return NO_ERROR;
+ }
+ status_t result = electronBeamOffAnimationImplLocked();
+ if (result == NO_ERROR) {
+ hw.setCanDraw(false);
+ }
+ return result;
+}
+
+status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
+{
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
+ class MessageTurnElectronBeamOff : public MessageBase {
+ SurfaceFlinger* flinger;
+ status_t result;
+ public:
+ MessageTurnElectronBeamOff(SurfaceFlinger* flinger)
+ : flinger(flinger), result(PERMISSION_DENIED) {
+ }
+ status_t getResult() const {
+ return result;
+ }
+ virtual bool handler() {
+ Mutex::Autolock _l(flinger->mStateLock);
+ result = flinger->turnElectronBeamOffImplLocked();
+ return true;
+ }
+ };
+
+ sp<MessageBase> msg = new MessageTurnElectronBeamOff(this);
+ status_t res = postMessageSync(msg);
+ if (res == NO_ERROR) {
+ res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
+
+ // work-around: when the power-manager calls us we activate the
+ // animation. eventually, the "on" animation will be called
+ // by the power-manager itself
+ mElectronBeamAnimation = true;
+ }
+ return res;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::turnElectronBeamOnImplLocked()
+{
+ DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
+ if (hw.canDraw()) {
+ // we're already on
+ return NO_ERROR;
+ }
+ status_t result = electronBeamOnAnimationImplLocked();
+ if (result == NO_ERROR) {
+ hw.setCanDraw(true);
+ }
+ return result;
+}
+
+status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
+{
+ if (!GLExtensions::getInstance().haveFramebufferObject())
+ return INVALID_OPERATION;
+
+ class MessageTurnElectronBeamOn : public MessageBase {
+ SurfaceFlinger* flinger;
+ status_t result;
+ public:
+ MessageTurnElectronBeamOn(SurfaceFlinger* flinger)
+ : flinger(flinger), result(PERMISSION_DENIED) {
+ }
+ status_t getResult() const {
+ return result;
+ }
+ virtual bool handler() {
+ Mutex::Autolock _l(flinger->mStateLock);
+ result = flinger->turnElectronBeamOnImplLocked();
+ return true;
+ }
+ };
+
+ postMessageAsync( new MessageTurnElectronBeamOn(this) );
+ return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
sp<IMemoryHeap>* heap,
uint32_t* w, uint32_t* h, PixelFormat* f,
@@ -2005,6 +2452,10 @@
return *mHw;
}
+DisplayHardware& GraphicPlane::editDisplayHardware() {
+ return *mHw;
+}
+
const Transform& GraphicPlane::transform() const {
return mGlobalTransform;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f0a167b..d07a3ad 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -141,6 +141,7 @@
int getHeight() const;
const DisplayHardware& displayHardware() const;
+ DisplayHardware& editDisplayHardware();
const Transform& transform() const;
EGLDisplay getEGLDisplay() const;
@@ -200,6 +201,8 @@
PixelFormat* format,
uint32_t reqWidth,
uint32_t reqHeight);
+ virtual status_t turnElectronBeamOff(int32_t mode);
+ virtual status_t turnElectronBeamOn(int32_t mode);
void screenReleased(DisplayID dpy);
void screenAcquired(DisplayID dpy);
@@ -325,6 +328,13 @@
uint32_t* width, uint32_t* height, PixelFormat* format,
uint32_t reqWidth = 0, uint32_t reqHeight = 0);
+ status_t turnElectronBeamOffImplLocked();
+ status_t turnElectronBeamOnImplLocked();
+ status_t electronBeamOffAnimationImplLocked();
+ status_t electronBeamOnAnimationImplLocked();
+ status_t renderScreenToTextureLocked(DisplayID dpy,
+ GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
+
friend class FreezeLock;
sp<FreezeLock> getFreezeLock() const;
inline void incFreezeCount() {
@@ -385,6 +395,7 @@
bool mVisibleRegionsDirty;
bool mDeferReleaseConsole;
bool mFreezeDisplay;
+ bool mElectronBeamAnimation;
int32_t mFreezeCount;
nsecs_t mFreezeDisplayTime;
Vector< sp<LayerBase> > mVisibleLayersSortedByZ;
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index 3419567..46ef118 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -24,6 +24,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.SystemProperties;
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.PhoneLookup;
@@ -36,8 +37,7 @@
*/
public class CallerInfoAsyncQuery {
-
- private static final boolean DBG = true; // STOPSHIP: disable debugging before ship
+ private static final boolean DBG = (SystemProperties.getInt("ro.debuggable", 0) == 1);
private static final String LOG_TAG = "CallerInfoAsyncQuery";
private static final int EVENT_NEW_QUERY = 1;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index f71ebb9..873ebac 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -871,6 +871,15 @@
error.string());
goto bail;
}
+ } else if (tag == "uses-gl-texture") {
+ String8 name = getAttribute(tree, NAME_ATTR, &error);
+ if (name != "" && error == "") {
+ printf("uses-gl-texture:'%s'\n", name.string());
+ } else {
+ fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
+ error.string());
+ goto bail;
+ }
}
} else if (depth == 3 && withinApplication) {
withinActivity = false;
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index b02c1cb..9866876 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -13,6 +13,8 @@
LOCAL_SRC_FILES := \
Main.cpp
+LOCAL_CFLAGS := -Wall -Werror
+
#LOCAL_C_INCLUDES +=
LOCAL_STATIC_LIBRARIES := \
@@ -27,4 +29,21 @@
include $(BUILD_HOST_EXECUTABLE)
+# Non-Linux hosts might not have OpenSSL libcrypto
+ifeq ($(HOST_OS),linux)
+ include $(CLEAR_VARS)
+
+ LOCAL_MODULE := pbkdf2gen
+
+ LOCAL_MODULE_TAGS := optional
+
+ LOCAL_CFLAGS := -Wall -Werror
+
+ LOCAL_SRC_FILES := pbkdf2gen.cpp
+
+ LOCAL_SHARED_LIBRARIES := libcrypto
+
+ include $(BUILD_HOST_EXECUTABLE)
+endif # HOST_OS == linux
+
endif # TARGET_BUILD_APPS
diff --git a/tools/obbtool/Main.cpp b/tools/obbtool/Main.cpp
index 49e077f..932dbec 100644
--- a/tools/obbtool/Main.cpp
+++ b/tools/obbtool/Main.cpp
@@ -20,6 +20,7 @@
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
using namespace android;
@@ -29,7 +30,9 @@
static int wantUsage = 0;
static int wantVersion = 0;
-#define ADD_OPTS "n:v:o"
+#define SALT_LEN 8
+
+#define ADD_OPTS "n:v:os:"
static const struct option longopts[] = {
{"help", no_argument, &wantUsage, 1},
{"version", no_argument, &wantVersion, 1},
@@ -38,14 +41,27 @@
{"name", required_argument, NULL, 'n'},
{"version", required_argument, NULL, 'v'},
{"overlay", optional_argument, NULL, 'o'},
+ {"salt", required_argument, NULL, 's'},
{NULL, 0, NULL, '\0'}
};
-struct package_info_t {
+class PackageInfo {
+public:
+ PackageInfo()
+ : packageName(NULL)
+ , packageVersion(-1)
+ , overlay(false)
+ , salted(false)
+ {
+ memset(&salt, 0, sizeof(salt));
+ }
+
char* packageName;
int packageVersion;
bool overlay;
+ bool salted;
+ unsigned char salt[SALT_LEN];
};
/*
@@ -59,6 +75,13 @@
" %s a[dd] [ OPTIONS ] FILENAME\n"
" Adds an OBB signature to the file.\n\n", gProgName);
fprintf(stderr,
+ " Options:\n"
+ " -n <package name> sets the OBB package name (required)\n"
+ " -v <OBB version> sets the OBB version (required)\n"
+ " -o sets the OBB overlay flag\n"
+ " -s <8 byte hex salt> sets the crypto key salt (if encrypted)\n"
+ "\n");
+ fprintf(stderr,
" %s r[emove] FILENAME\n"
" Removes the OBB signature from the file.\n\n", gProgName);
fprintf(stderr,
@@ -66,7 +89,7 @@
" Prints the OBB signature information of a file.\n\n", gProgName);
}
-void doAdd(const char* filename, struct package_info_t* info) {
+void doAdd(const char* filename, struct PackageInfo* info) {
ObbFile *obb = new ObbFile();
if (obb->readFrom(filename)) {
fprintf(stderr, "ERROR: %s: OBB signature already present\n", filename);
@@ -76,6 +99,9 @@
obb->setPackageName(String8(info->packageName));
obb->setVersion(info->packageVersion);
obb->setOverlay(info->overlay);
+ if (info->salted) {
+ obb->setSalt(info->salt, SALT_LEN);
+ }
if (!obb->writeTo(filename)) {
fprintf(stderr, "ERROR: %s: couldn't write OBB signature: %s\n",
@@ -113,6 +139,40 @@
printf(" Version: %d\n", obb->getVersion());
printf(" Flags: 0x%08x\n", obb->getFlags());
printf(" Overlay: %s\n", obb->isOverlay() ? "true" : "false");
+ printf(" Salt: ");
+
+ size_t saltLen;
+ const unsigned char* salt = obb->getSalt(&saltLen);
+ if (salt != NULL) {
+ for (int i = 0; i < SALT_LEN; i++) {
+ printf("%02x", salt[i]);
+ }
+ printf("\n");
+ } else {
+ printf("<empty>\n");
+ }
+}
+
+bool fromHex(char h, unsigned char *b) {
+ if (h >= '0' && h <= '9') {
+ *b = h - '0';
+ return true;
+ } else if (h >= 'a' && h <= 'f') {
+ *b = h - 'a' + 10;
+ return true;
+ } else if (h >= 'A' && h <= 'F') {
+ *b = h - 'A' + 10;
+ return true;
+ }
+ return false;
+}
+
+bool hexToByte(char h1, char h2, unsigned char* b) {
+ unsigned char first, second;
+ if (!fromHex(h1, &first)) return false;
+ if (!fromHex(h2, &second)) return false;
+ *b = (first << 4) | second;
+ return true;
}
/*
@@ -120,11 +180,9 @@
*/
int main(int argc, char* const argv[])
{
- const char *prog = argv[0];
- struct options *options;
int opt;
int option_index = 0;
- struct package_info_t package_info;
+ struct PackageInfo package_info;
int result = 1; // pessimistically assume an error.
@@ -145,7 +203,7 @@
package_info.packageName = optarg;
break;
case 'v': {
- char *end;
+ char* end;
package_info.packageVersion = strtol(optarg, &end, 10);
if (*optarg == '\0' || *end != '\0') {
fprintf(stderr, "ERROR: invalid version; should be integer!\n\n");
@@ -157,6 +215,25 @@
case 'o':
package_info.overlay = true;
break;
+ case 's':
+ if (strlen(optarg) != SALT_LEN * 2) {
+ fprintf(stderr, "ERROR: salt must be 8 bytes in hex (e.g., ABCD65031337D00D)\n\n");
+ wantUsage = 1;
+ goto bail;
+ }
+
+ package_info.salted = true;
+
+ unsigned char b;
+ for (int i = 0, j = 0; i < SALT_LEN; i++, j+=2) {
+ if (!hexToByte(optarg[j], optarg[j+1], &b)) {
+ fprintf(stderr, "ERROR: salt must be in hex (e.g., ABCD65031337D00D)\n");
+ wantUsage = 1;
+ goto bail;
+ }
+ package_info.salt[i] = b;
+ }
+ break;
case '?':
wantUsage = 1;
goto bail;
diff --git a/tools/obbtool/mkobb.sh b/tools/obbtool/mkobb.sh
index ba5256f..725250d 100755
--- a/tools/obbtool/mkobb.sh
+++ b/tools/obbtool/mkobb.sh
@@ -35,6 +35,7 @@
UMOUNTBIN=`which umount`
DDBIN=`which dd`
RSYNCBIN=`which rsync`
+ PBKDF2GEN=`which pbkdf2gen`
}
check_prereqs() {
@@ -76,6 +77,11 @@
echo "ERROR: ${LOSETUPBIN} is not executable!"
exit 1
fi
+
+ if [ "${PBKDF2GEN}x" = "x" ]; then \
+ echo "ERROR: Could not find pbkdf2gen in your path!"
+ exit 1
+ fi
}
cleanup() {
@@ -142,7 +148,6 @@
usage() {
echo "mkobb.sh -- Create OBB files for use on Android"
echo ""
- echo " -c Use an encrypted OBB; must specify key"
echo " -d <directory> Use <directory> as input for OBB files"
echo " -k <key> Use <key> to encrypt OBB file"
echo " -K Prompt for key to encrypt OBB file"
@@ -156,7 +161,7 @@
use_crypto=0
-args=`getopt -o cd:hk:Ko:v -- "$@"`
+args=`getopt -o d:hk:Ko:v -- "$@"`
eval set -- "$args"
while true; do \
@@ -223,9 +228,9 @@
${LOSETUPBIN} ${loop_dev} ${tempfile} || ( echo "ERROR: couldn't create loopback device"; exit 1 )
if [ ${use_crypto} -eq 1 ]; then \
- hashed_key=`echo -n "${key}" | md5sum | awk '{ print $1 }'`
+ eval `${PBKDF2GEN} ${key}`
unique_dm_name=`basename ${tempfile}`
- echo "0 `blockdev --getsize ${loop_dev}` crypt ${CRYPTO} ${hashed_key} 0 ${loop_dev} 0" | dmsetup create ${unique_dm_name}
+ echo "0 `blockdev --getsize ${loop_dev}` crypt ${CRYPTO} ${key} 0 ${loop_dev} 0" | dmsetup create ${unique_dm_name}
old_loop_dev=${loop_dev}
loop_dev=/dev/mapper/${unique_dm_name}
fi
@@ -253,6 +258,11 @@
echo "Successfully created \`${filename}'"
+if [ ${use_crypto} -eq 1 ]; then \
+ echo "salt for use with obbtool is:"
+ echo "${salt}"
+fi
+
#
# Undo all the temporaries
#
diff --git a/tools/obbtool/pbkdf2gen.cpp b/tools/obbtool/pbkdf2gen.cpp
new file mode 100644
index 0000000..98d67c0
--- /dev/null
+++ b/tools/obbtool/pbkdf2gen.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#include <openssl/evp.h>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/**
+ * Simple program to generate a key based on PBKDF2 with preset inputs.
+ *
+ * Will print out the salt and key in hex.
+ */
+
+#define SALT_LEN 8
+#define ROUNDS 1024
+#define KEY_BITS 128
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <password>\n", argv[0]);
+ exit(1);
+ }
+
+ int fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Could not open /dev/urandom: %s\n", strerror(errno));
+ close(fd);
+ exit(1);
+ }
+
+ unsigned char salt[SALT_LEN];
+
+ if (read(fd, &salt, SALT_LEN) != SALT_LEN) {
+ fprintf(stderr, "Could not read salt from /dev/urandom: %s\n", strerror(errno));
+ close(fd);
+ exit(1);
+ }
+ close(fd);
+
+ unsigned char rawKey[KEY_BITS];
+
+ if (PKCS5_PBKDF2_HMAC_SHA1(argv[1], strlen(argv[1]), salt, SALT_LEN,
+ ROUNDS, KEY_BITS, rawKey) != 1) {
+ fprintf(stderr, "Could not generate PBKDF2 output: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ printf("salt=");
+ for (int i = 0; i < SALT_LEN; i++) {
+ printf("%02x", salt[i]);
+ }
+ printf("\n");
+
+ printf("key=");
+ for (int i = 0; i < (KEY_BITS / 8); i++) {
+ printf("%02x", rawKey[i]);
+ }
+ printf("\n");
+}
diff --git a/tools/preload/WritePreloadedClassFile.java b/tools/preload/WritePreloadedClassFile.java
index 96c539b..b067bc2 100644
--- a/tools/preload/WritePreloadedClassFile.java
+++ b/tools/preload/WritePreloadedClassFile.java
@@ -34,6 +34,11 @@
*/
static final int MIN_LOAD_TIME_MICROS = 1250;
+ /**
+ * Preload any class that was loaded by at least MIN_PROCESSES processes.
+ */
+ static final int MIN_PROCESSES = 10;
+
public static void main(String[] args) throws IOException,
ClassNotFoundException {
if (args.length != 1) {
@@ -58,6 +63,7 @@
out.write("# Automatically generated by frameworks/base/tools/preload/"
+ WritePreloadedClassFile.class.getSimpleName() + ".java.\n");
out.write("# MIN_LOAD_TIME_MICROS=" + MIN_LOAD_TIME_MICROS + "\n");
+ out.write("# MIN_PROCESSES=" + MIN_PROCESSES + "\n");
/*
* The set of classes to preload. We preload a class if:
@@ -73,7 +79,12 @@
// the memory associated with these classes will be shared.
for (LoadedClass loadedClass : root.loadedClasses.values()) {
Set<String> names = loadedClass.processNames();
- if (shouldPreload(loadedClass) && names.size() > 1) {
+ if (!Policy.isPreloadable(loadedClass)) {
+ continue;
+ }
+
+ if (names.size() >= MIN_PROCESSES ||
+ (loadedClass.medianTimeMicros() > MIN_LOAD_TIME_MICROS && names.size() > 1)) {
toPreload.add(loadedClass);
}
}
diff --git a/tools/preload/loadclass/Android.mk b/tools/preload/loadclass/Android.mk
index 435699d..65828be 100644
--- a/tools/preload/loadclass/Android.mk
+++ b/tools/preload/loadclass/Android.mk
@@ -2,6 +2,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE_TAGS := tests
LOCAL_MODULE := loadclass
diff --git a/voip/java/com/android/server/sip/SipService.java b/voip/java/com/android/server/sip/SipService.java
index 6f426c9..f41f156c 100644
--- a/voip/java/com/android/server/sip/SipService.java
+++ b/voip/java/com/android/server/sip/SipService.java
@@ -39,6 +39,7 @@
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -54,6 +55,7 @@
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Timer;
@@ -92,7 +94,8 @@
new HashMap<String, ISipSession>();
private ConnectivityReceiver mConnectivityReceiver;
- private boolean mScreenOn;
+ private boolean mWifiEnabled;
+ private MyWakeLock mMyWakeLock;
/**
* Starts the SIP service. Do nothing if the SIP API is not supported on the
@@ -112,23 +115,34 @@
mConnectivityReceiver = new ConnectivityReceiver();
context.registerReceiver(mConnectivityReceiver,
new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
- context.registerReceiver(mScreenOnOffReceiver,
- new IntentFilter(Intent.ACTION_SCREEN_ON));
- context.registerReceiver(mScreenOnOffReceiver,
- new IntentFilter(Intent.ACTION_SCREEN_OFF));
+ context.registerReceiver(mWifiStateReceiver,
+ new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
+ mMyWakeLock = new MyWakeLock((PowerManager)
+ context.getSystemService(Context.POWER_SERVICE));
mTimer = new WakeupTimer(context);
mWifiOnly = SipManager.isSipWifiOnly(context);
}
- BroadcastReceiver mScreenOnOffReceiver = new BroadcastReceiver() {
+ BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (Intent.ACTION_SCREEN_OFF.equals(action)) {
- mScreenOn = true;
- } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
- mScreenOn = false;
+ if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
+ int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_UNKNOWN);
+ synchronized (SipService.this) {
+ switch (state) {
+ case WifiManager.WIFI_STATE_ENABLED:
+ mWifiEnabled = true;
+ if (anyOpened()) grabWifiLock();
+ break;
+ case WifiManager.WIFI_STATE_DISABLED:
+ mWifiEnabled = false;
+ releaseWifiLock();
+ break;
+ }
+ }
}
}
};
@@ -182,7 +196,7 @@
incomingCallPendingIntent, listener);
if (localProfile.getAutoRegistration()) {
group.openToReceiveCalls();
- if (isWifiActive()) grabWifiLock();
+ if (mWifiEnabled) grabWifiLock();
}
} catch (SipException e) {
Log.e(TAG, "openToReceiveCalls()", e);
@@ -216,7 +230,11 @@
group = mSipGroups.remove(localProfileUri);
notifyProfileRemoved(group.getLocalProfile());
group.close();
- if (isWifiActive() && !anyOpened()) releaseWifiLock();
+
+ if (!anyOpened()) {
+ releaseWifiLock();
+ mMyWakeLock.reset(); // in case there's leak
+ }
}
public synchronized boolean isOpened(String localProfileUri) {
@@ -349,7 +367,7 @@
private void grabWifiLock() {
if (mWifiLock == null) {
- if (DEBUG) Log.d(TAG, "acquire wifi lock");
+ if (DEBUG) Log.d(TAG, "~~~~~~~~~~~~~~~~~~~~~ acquire wifi lock");
mWifiLock = ((WifiManager)
mContext.getSystemService(Context.WIFI_SERVICE))
.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG);
@@ -359,16 +377,12 @@
private void releaseWifiLock() {
if (mWifiLock != null) {
- if (DEBUG) Log.d(TAG, "release wifi lock");
+ if (DEBUG) Log.d(TAG, "~~~~~~~~~~~~~~~~~~~~~ release wifi lock");
mWifiLock.release();
mWifiLock = null;
}
}
- private boolean isWifiActive() {
- return "WIFI".equalsIgnoreCase(mNetworkType);
- }
-
private synchronized void onConnectivityChanged(
String type, boolean connected) {
if (DEBUG) Log.d(TAG, "onConnectivityChanged(): "
@@ -382,14 +396,6 @@
boolean isWifi = "WIFI".equalsIgnoreCase(type);
boolean wifiOff = (isWifi && !connected) || (wasWifi && !sameType);
boolean wifiOn = isWifi && connected;
- if (wifiOff) {
- if (mScreenOn) releaseWifiLock();
- // If the screen is off, we still keep the wifi lock in order
- // to be able to reassociate with any available AP. Otherwise,
- // the wifi driver could be stopped after 15 mins of idle time.
- } else if (wifiOn) {
- if (anyOpened()) grabWifiLock();
- }
try {
boolean wasConnected = mConnected;
@@ -408,8 +414,9 @@
for (SipSessionGroupExt group : mSipGroups.values()) {
group.onConnectivityChanged(true);
}
+ } else {
+ mMyWakeLock.reset(); // in case there's a leak
}
-
} catch (SipException e) {
Log.e(TAG, "onConnectivityChanged()", e);
}
@@ -585,7 +592,7 @@
}
// KeepAliveProcess is controlled by AutoRegistrationProcess.
- // All methods will be invoked in sync with SipService.this except realRun()
+ // All methods will be invoked in sync with SipService.this.
private class KeepAliveProcess implements Runnable {
private static final String TAG = "\\KEEPALIVE/";
private static final int INTERVAL = 10;
@@ -604,43 +611,33 @@
// timeout handler
public void run() {
- if (!mRunning) return;
- final SipSessionGroup.SipSessionImpl session = mSession;
-
- // delegate to mExecutor
- getExecutor().addTask(new Runnable() {
- public void run() {
- realRun(session);
- }
- });
- }
-
- // real timeout handler
- private void realRun(SipSessionGroup.SipSessionImpl session) {
synchronized (SipService.this) {
- if (notCurrentSession(session)) return;
+ if (!mRunning) return;
- session = session.duplicate();
- if (DEBUGV) Log.v(TAG, "~~~ keepalive");
- mTimer.cancel(this);
- session.sendKeepAlive();
- if (session.isReRegisterRequired()) {
- mSession.register(EXPIRY_TIME);
- } else {
- mTimer.set(INTERVAL * 1000, this);
+ if (DEBUGV) Log.v(TAG, "~~~ keepalive: "
+ + mSession.getLocalProfile().getUriString());
+ SipSessionGroup.SipSessionImpl session = mSession.duplicate();
+ try {
+ session.sendKeepAlive();
+ if (session.isReRegisterRequired()) {
+ // Acquire wake lock for the registration process. The
+ // lock will be released when registration is complete.
+ mMyWakeLock.acquire(mSession);
+ mSession.register(EXPIRY_TIME);
+ }
+ } catch (Throwable t) {
+ Log.w(TAG, "keepalive error: " + t);
}
}
}
public void stop() {
+ if (DEBUGV && (mSession != null)) Log.v(TAG, "stop keepalive:"
+ + mSession.getLocalProfile().getUriString());
mRunning = false;
mSession = null;
mTimer.cancel(this);
}
-
- private boolean notCurrentSession(ISipSession session) {
- return (session != mSession) || !mRunning;
- }
}
private class AutoRegistrationProcess extends SipSessionAdapter
@@ -671,6 +668,7 @@
// start unregistration to clear up old registration at server
// TODO: when rfc5626 is deployed, use reg-id and sip.instance
// in registration to avoid adding duplicate entries to server
+ mMyWakeLock.acquire(mSession);
mSession.unregister();
if (DEBUG) Log.d(TAG, "start AutoRegistrationProcess for "
+ mSession.getLocalProfile().getUriString());
@@ -680,8 +678,11 @@
public void stop() {
if (!mRunning) return;
mRunning = false;
- mSession.setListener(null);
- if (mConnected && mRegistered) mSession.unregister();
+ mMyWakeLock.release(mSession);
+ if (mSession != null) {
+ mSession.setListener(null);
+ if (mConnected && mRegistered) mSession.unregister();
+ }
mTimer.cancel(this);
if (mKeepAliveProcess != null) {
@@ -738,29 +739,18 @@
return mRegistered;
}
- // timeout handler
+ // timeout handler: re-register
public void run() {
synchronized (SipService.this) {
if (!mRunning) return;
- final SipSessionGroup.SipSessionImpl session = mSession;
- // delegate to mExecutor
- getExecutor().addTask(new Runnable() {
- public void run() {
- realRun(session);
- }
- });
- }
- }
-
- // real timeout handler
- private void realRun(SipSessionGroup.SipSessionImpl session) {
- synchronized (SipService.this) {
- if (notCurrentSession(session)) return;
mErrorCode = SipErrorCode.NO_ERROR;
mErrorMessage = null;
if (DEBUG) Log.d(TAG, "~~~ registering");
- if (mConnected) session.register(EXPIRY_TIME);
+ if (mConnected) {
+ mMyWakeLock.acquire(mSession);
+ mSession.register(EXPIRY_TIME);
+ }
}
}
@@ -810,6 +800,7 @@
private boolean notCurrentSession(ISipSession session) {
if (session != mSession) {
((SipSessionGroup.SipSessionImpl) session).setListener(null);
+ mMyWakeLock.release(session);
return true;
}
return !mRunning;
@@ -846,6 +837,7 @@
mKeepAliveProcess.start();
}
}
+ mMyWakeLock.release(session);
} else {
mRegistered = false;
mExpiryTime = -1L;
@@ -876,6 +868,7 @@
mErrorCode = errorCode;
mErrorMessage = message;
mProxy.onRegistrationFailed(session, errorCode, message);
+ mMyWakeLock.release(session);
}
}
@@ -888,6 +881,7 @@
mErrorCode = SipErrorCode.TIME_OUT;
mProxy.onRegistrationTimeout(session);
restartLater();
+ mMyWakeLock.release(session);
}
}
@@ -906,7 +900,16 @@
private MyTimerTask mTask;
@Override
- public void onReceive(Context context, Intent intent) {
+ public void onReceive(final Context context, final Intent intent) {
+ // Run the handler in MyExecutor to be protected by wake lock
+ getExecutor().execute(new Runnable() {
+ public void run() {
+ onReceiveInternal(context, intent);
+ }
+ });
+ }
+
+ private void onReceiveInternal(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
Bundle b = intent.getExtras();
@@ -974,11 +977,13 @@
if (mTask != null) mTask.cancel();
mTask = new MyTimerTask(type, connected);
mTimer.schedule(mTask, 2 * 1000L);
- // TODO: hold wakup lock so that we can finish change before
- // the device goes to sleep
+ // hold wakup lock so that we can finish changes before the
+ // device goes to sleep
+ mMyWakeLock.acquire(mTask);
} else {
if ((mTask != null) && mTask.mNetworkType.equals(type)) {
mTask.cancel();
+ mMyWakeLock.release(mTask);
}
onConnectivityChanged(type, false);
}
@@ -998,7 +1003,7 @@
@Override
public void run() {
// delegate to mExecutor
- getExecutor().addTask(new Runnable() {
+ getExecutor().execute(new Runnable() {
public void run() {
realRun();
}
@@ -1016,6 +1021,7 @@
if (DEBUG) Log.d(TAG, " deliver change for " + mNetworkType
+ (mConnected ? " CONNECTED" : "DISCONNECTED"));
onConnectivityChanged(mNetworkType, mConnected);
+ mMyWakeLock.release(this);
}
}
}
@@ -1023,7 +1029,6 @@
// TODO: clean up pending SipSession(s) periodically
-
/**
* Timer that can schedule events to occur even when the device is in sleep.
* Only used internally in this package.
@@ -1213,7 +1218,8 @@
}
@Override
- public synchronized void onReceive(Context context, Intent intent) {
+ public void onReceive(Context context, Intent intent) {
+ // This callback is already protected by AlarmManager's wake lock.
String action = intent.getAction();
if (getAction().equals(action)
&& intent.getExtras().containsKey(TRIGGER_TIME)) {
@@ -1240,7 +1246,7 @@
}
}
- private void execute(long triggerTime) {
+ private synchronized void execute(long triggerTime) {
if (DEBUG_TIMER) Log.d(TAG, "time's up, triggerTime = "
+ showTime(triggerTime) + ": " + mEventQueue.size());
if (stopped() || mEventQueue.isEmpty()) return;
@@ -1252,9 +1258,8 @@
event.mLastTriggerTime = event.mTriggerTime;
event.mTriggerTime += event.mPeriod;
- // run the callback in a new thread to prevent deadlock
- new Thread(event.mCallback, "SipServiceTimerCallbackThread")
- .start();
+ // run the callback in the handler thread to prevent deadlock
+ getExecutor().execute(event.mCallback);
}
if (DEBUG_TIMER) {
Log.d(TAG, "after timeout execution");
@@ -1318,29 +1323,78 @@
}
}
- // Single-threaded executor
- private static class MyExecutor extends Handler {
+ private static Looper createLooper() {
+ HandlerThread thread = new HandlerThread("SipService.Executor");
+ thread.start();
+ return thread.getLooper();
+ }
+
+ // Executes immediate tasks in a single thread.
+ // Hold/release wake lock for running tasks
+ private class MyExecutor extends Handler {
MyExecutor() {
super(createLooper());
}
- private static Looper createLooper() {
- HandlerThread thread = new HandlerThread("SipService");
- thread.start();
- return thread.getLooper();
- }
-
- void addTask(Runnable task) {
+ void execute(Runnable task) {
+ mMyWakeLock.acquire(task);
Message.obtain(this, 0/* don't care */, task).sendToTarget();
}
@Override
public void handleMessage(Message msg) {
if (msg.obj instanceof Runnable) {
- ((Runnable) msg.obj).run();
+ executeInternal((Runnable) msg.obj);
} else {
Log.w(TAG, "can't handle msg: " + msg);
}
}
+
+ private void executeInternal(Runnable task) {
+ try {
+ task.run();
+ } catch (Throwable t) {
+ Log.e(TAG, "run task: " + task, t);
+ } finally {
+ mMyWakeLock.release(task);
+ }
+ }
+ }
+
+ private static class MyWakeLock {
+ private PowerManager mPowerManager;
+ private PowerManager.WakeLock mWakeLock;
+ private HashSet<Object> mHolders = new HashSet<Object>();
+
+ MyWakeLock(PowerManager powerManager) {
+ mPowerManager = powerManager;
+ }
+
+ synchronized void reset() {
+ mHolders.clear();
+ release(null);
+ if (DEBUGV) Log.v(TAG, "~~~ hard reset wakelock");
+ }
+
+ synchronized void acquire(Object holder) {
+ mHolders.add(holder);
+ if (mWakeLock == null) {
+ mWakeLock = mPowerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, "SipWakeLock");
+ }
+ if (!mWakeLock.isHeld()) mWakeLock.acquire();
+ if (DEBUGV) Log.v(TAG, "acquire wakelock: holder count="
+ + mHolders.size());
+ }
+
+ synchronized void release(Object holder) {
+ mHolders.remove(holder);
+ if ((mWakeLock != null) && mHolders.isEmpty()
+ && mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ if (DEBUGV) Log.v(TAG, "release wakelock: holder count="
+ + mHolders.size());
+ }
}
}
diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java
index 57b3710..2b8058f 100644
--- a/voip/java/com/android/server/sip/SipSessionGroup.java
+++ b/voip/java/com/android/server/sip/SipSessionGroup.java
@@ -153,7 +153,13 @@
}
synchronized void onConnectivityChanged() {
- for (SipSessionImpl s : mSessionMap.values()) {
+ SipSessionImpl[] ss = mSessionMap.values().toArray(
+ new SipSessionImpl[mSessionMap.size()]);
+ // Iterate on the copied array instead of directly on mSessionMap to
+ // avoid ConcurrentModificationException being thrown when
+ // SipSessionImpl removes itself from mSessionMap in onError() in the
+ // following loop.
+ for (SipSessionImpl s : ss) {
s.onError(SipErrorCode.DATA_CONNECTION_LOST,
"data connection lost");
}
@@ -541,8 +547,14 @@
mState = SipSession.State.PINGING;
try {
processCommand(new OptionsCommand());
- while (SipSession.State.PINGING == mState) {
- Thread.sleep(1000);
+ for (int i = 0; i < 15; i++) {
+ if (SipSession.State.PINGING != mState) break;
+ Thread.sleep(200);
+ }
+ if (SipSession.State.PINGING == mState) {
+ // FIXME: what to do if server doesn't respond
+ reset();
+ if (DEBUG) Log.w(TAG, "no response from ping");
}
} catch (SipException e) {
Log.e(TAG, "sendKeepAlive failed", e);
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 281077c..06f6696 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -1285,15 +1285,13 @@
if (macaddr != null) {
mWifiInfo.setMacAddress(macaddr);
}
- if (mRunState == RUN_STATE_STARTING) {
- mRunState = RUN_STATE_RUNNING;
- if (!mIsScanOnly) {
- reconnectCommand();
- } else {
- // In some situations, supplicant needs to be kickstarted to
- // start the background scanning
- scan(true);
- }
+ mRunState = RUN_STATE_RUNNING;
+ if (!mIsScanOnly) {
+ reconnectCommand();
+ } else {
+ // In some situations, supplicant needs to be kickstarted to
+ // start the background scanning
+ scan(true);
}
}
break;
@@ -1613,12 +1611,10 @@
}
public synchronized boolean restart() {
- if (mRunState == RUN_STATE_STOPPED) {
+ if (isDriverStopped()) {
mRunState = RUN_STATE_STARTING;
resetConnections(true);
return startDriver();
- } else if (mRunState == RUN_STATE_STOPPING) {
- mRunState = RUN_STATE_STARTING;
}
return true;
}