Merge changes I244b5469,I32044e91 into gingerbread

* changes:
  [3253328, 3171580] Treat GONE and INVISIBLE views the same when calculating transparent regions
  [3171580] Fix two typos related to fixed-size buffers
diff --git a/Android.mk b/Android.mk
index 6147022..e299250 100644
--- a/Android.mk
+++ b/Android.mk
@@ -119,11 +119,11 @@
 	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/nfc/INfcSecureElement.aidl \
 	core/java/android/os/IHardwareService.aidl \
 	core/java/android/os/IMessenger.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
@@ -252,7 +252,6 @@
 	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 d19f3f8..2ee8f31 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -72,6 +72,7 @@
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
 $(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)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
 
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 1b799ae..4a75514 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1532,7 +1532,7 @@
      * </ul>
      *
      * <p>
-     * <center><img src="../../../images/axis_device_inverted.png"
+     * <center><img src="../../../images/axis_globe_inverted.png"
      * alt="Inverted world coordinate-system diagram." border="0" /></center>
      * </p>
      * <p>
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index cd08e33..a663fb8 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -24,6 +24,7 @@
 import android.nfc.INfcTag;
 import android.nfc.IP2pTarget;
 import android.nfc.IP2pInitiator;
+import android.nfc.INfcSecureElement;
 
 /**
  * @hide
@@ -36,9 +37,12 @@
     INfcTag getNfcTagInterface();
     IP2pTarget getP2pTargetInterface();
     IP2pInitiator getP2pInitiatorInterface();
+    INfcSecureElement getNfcSecureElementInterface();
 
     // NfcAdapter-class related methods
     boolean isEnabled();
+    NdefMessage localGet();
+    void localSet(in NdefMessage message);
     void openTagConnection(in Tag tag);
 
     // Non-public methods
diff --git a/core/java/android/nfc/INdefTag.aidl b/core/java/android/nfc/INfcSecureElement.aidl
old mode 100644
new mode 100755
similarity index 68%
rename from core/java/android/nfc/INdefTag.aidl
rename to core/java/android/nfc/INfcSecureElement.aidl
index d131ebe..aa98dd2
--- a/core/java/android/nfc/INdefTag.aidl
+++ b/core/java/android/nfc/INfcSecureElement.aidl
@@ -16,13 +16,13 @@
 
 package android.nfc;
 
-import android.nfc.NdefMessage;
-
 /**
- * @hide
+ * {@hide}
  */
-interface INdefTag
-{
-    NdefMessage read(int nativeHandle);
-    boolean write(int nativeHandle, in NdefMessage msg);
+interface INfcSecureElement {
+    int openSecureElementConnection();
+    int closeSecureElementConnection(int nativeHandle);
+    byte[] exchangeAPDU(int nativeHandle, in byte[] data);
+    int[] getSecureElementTechList(int nativeHandle);
+    byte[] getSecureElementUid(int nativeHandle);
 }
\ No newline at end of file
diff --git a/core/java/android/nfc/INfcTag.aidl b/core/java/android/nfc/INfcTag.aidl
index 13b97d6..ad3c1bb 100644
--- a/core/java/android/nfc/INfcTag.aidl
+++ b/core/java/android/nfc/INfcTag.aidl
@@ -25,7 +25,7 @@
 {
     int close(int nativeHandle);
     int connect(int nativeHandle);
-    String getType(int nativeHandle);
+    int[] getTechList(int nativeHandle);
     byte[] getUid(int nativeHandle);
     boolean isNdef(int nativeHandle);
     boolean isPresent(int nativeHandle);
diff --git a/core/java/android/nfc/NdefTag.aidl b/core/java/android/nfc/NdefTag.aidl
deleted file mode 100644
index 288f667..0000000
--- a/core/java/android/nfc/NdefTag.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-parcelable NdefTag;
\ No newline at end of file
diff --git a/core/java/android/nfc/NdefTag.java b/core/java/android/nfc/NdefTag.java
deleted file mode 100644
index eb9d0dc..0000000
--- a/core/java/android/nfc/NdefTag.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents a discovered tag that contains {@link NdefMessage}s (or a tag that can store them).
- * In practice, a tag is a thing that an NFC-enabled device can communicate with. This
- * class is a representation of such a tag and can contain the NDEF messages shared by the tag.
- * <p>An NDEF tag can contain zero or more NDEF messages (represented by {@link NdefMessage}
- * objects) in addition to the basic tag properties of UID and Type.
- * <p>
- * {@link NdefTag}s that have been initialized will usually contain a single {@link NdefMessage}
- * (and that Message can contain multiple {@link NdefRecord}s). However it
- * is possible for {@link NdefTag}s to contain multiple {@link NdefMessage}s.
- * <p>{@link NfcAdapter#createNdefTagConnection createNdefTagConnection()} can be used to modify the
- * contents of some tags.
- * <p>This is an immutable data class. All properties are set at Tag discovery
- * time and calls on this class will retrieve those read-only properties, and
- * not cause any further RF activity or block. Note however that arrays passed to and
- * returned by this class are *not* cloned, so be careful not to modify them.
- * @hide
- */
-public class NdefTag extends Tag implements Parcelable {
-    /**
-     * Target for NFC Forum Type 1 compliant tag.
-     * <p>This is based on Jewel/Topaz technology
-     */
-    public static final String TARGET_TYPE_1 = "type_1";
-
-    /**
-     * Target for NFC Forum Type 2 compliant tag.
-     * <p>This is based on Mifare Ultralight technology.
-     */
-    public static final String TARGET_TYPE_2 = "type_2";
-
-    /**
-     * Target for NFC Forum Type 3 compliant tag.
-     * <p>This is based on Felica technology.
-     */
-    public static final String TARGET_TYPE_3 = "type_3";
-
-    /**
-     * Target for NFC Forum Type 4 compliant tag.
-     * <p>This is based on Mifare Desfire technology.
-     */
-    public static final String TARGET_TYPE_4 = "type_4";
-
-    /**
-     * Target for NFC Forum Enabled: Mifare Classic tag.
-     * <p>This is not strictly a NFC Forum tag type, but is a common
-     * NDEF message container.
-     */
-    public static final String TARGET_MIFARE_CLASSIC = "type_mifare_classic";
-
-    /**
-     * Any other target.
-     */
-    public static final String TARGET_OTHER = "other";
-
-    private final String[] mNdefTargets;
-    private final NdefMessage[][] mMessages;  // one NdefMessage[] per NDEF target
-    private NdefMessage[] mFlatMessages;  // collapsed mMessages, built lazily, protected by (this)
-
-    /**
-     * Hidden constructor to be used by NFC service only.
-     * @hide
-     */
-    public NdefTag(byte[] id, String[] rawTargets, byte[] pollBytes, byte[] activationBytes,
-            int serviceHandle, String[] ndefTargets, NdefMessage[][] messages) {
-        super(id, true, rawTargets, pollBytes, activationBytes, serviceHandle);
-        if (ndefTargets == null || messages == null) {
-            throw new IllegalArgumentException("ndefTargets or messages cannot be null");
-        }
-        if (ndefTargets.length != messages.length){
-            throw new IllegalArgumentException("ndefTargets and messages arrays must match");
-        }
-        for (NdefMessage[] ms : messages) {
-            if (ms == null) {
-                throw new IllegalArgumentException("messages elements cannot be null");
-            }
-        }
-        mNdefTargets = ndefTargets;
-        mMessages = messages;
-    }
-
-    /**
-     * Construct a mock NdefTag.
-     * <p>This is an application constructed tag, so NfcAdapter methods on this
-     * Tag such as {@link NfcAdapter#createRawTagConnection} will fail with
-     * {@link IllegalArgumentException} since it does not represent a physical Tag.
-     * <p>This constructor might be useful for mock testing.
-     * @param id The tag identifier, can be null
-     * @param rawTargets must not be null
-     * @param pollBytes can be null
-     * @param activationBytes can be null
-     * @param ndefTargets NDEF target array, such as {TARGET_TYPE_2}, cannot be null
-     * @param messages messages, one array per NDEF target, cannot be null
-     * @return freshly constructed NdefTag
-     */
-    public static NdefTag createMockNdefTag(byte[] id, String[] rawTargets, byte[] pollBytes,
-            byte[] activationBytes, String[] ndefTargets, NdefMessage[][] messages) {
-        // set serviceHandle to 0 to indicate mock tag
-        return new NdefTag(id, rawTargets, pollBytes, activationBytes, 0, ndefTargets, messages);
-    }
-
-    /**
-     * 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() {
-        // common-case optimization
-        if (mMessages.length == 1) {
-            return mMessages[0];
-        }
-
-        // return cached flat array
-        synchronized(this) {
-            if (mFlatMessages != null) {
-                return mFlatMessages;
-            }
-            // not cached - build a flat array
-            int sz = 0;
-            for (NdefMessage[] ms : mMessages) {
-                sz += ms.length;
-            }
-            mFlatMessages = new NdefMessage[sz];
-            int i = 0;
-            for (NdefMessage[] ms : mMessages) {
-                System.arraycopy(ms, 0, mFlatMessages, i, ms.length);
-                i += ms.length;
-            }
-            return mFlatMessages;
-        }
-    }
-
-    /**
-     * Get only the NDEF Messages from a single NDEF target on a tag.
-     * <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.
-     *
-     * @param target one of targets strings provided by getNdefTargets()
-     * @return NDEF Messages found at Tag discovery
-     */
-    public NdefMessage[] getNdefMessages(String target) {
-        for (int i=0; i<mNdefTargets.length; i++) {
-            if (target.equals(mNdefTargets[i])) {
-                return mMessages[i];
-            }
-        }
-        throw new IllegalArgumentException("target (" + target + ") not found");
-    }
-
-    /**
-     * Return the NDEF targets on this Tag that support NDEF messages.
-     *
-     * @return
-     */
-    public String[] getNdefTargets() {
-        return mNdefTargets;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        // Tag fields
-        dest.writeInt(mIsNdef ? 1 : 0);
-        writeBytesWithNull(dest, mId);
-        dest.writeInt(mRawTargets.length);
-        dest.writeStringArray(mRawTargets);
-        writeBytesWithNull(dest, mPollBytes);
-        writeBytesWithNull(dest, mActivationBytes);
-        dest.writeInt(mServiceHandle);
-
-        // NdefTag fields
-        dest.writeInt(mNdefTargets.length);
-        dest.writeStringArray(mNdefTargets);
-        dest.writeInt(mMessages.length);
-        for (NdefMessage[] ms : mMessages) {
-            dest.writeInt(ms.length);
-            dest.writeTypedArray(ms, flags);
-        }
-    }
-
-    public static final Parcelable.Creator<NdefTag> CREATOR =
-            new Parcelable.Creator<NdefTag>() {
-        public NdefTag createFromParcel(Parcel in) {
-            boolean isNdef = (in.readInt() == 1);
-            if (!isNdef) {
-                throw new IllegalArgumentException("Creating NdefTag from Tag parcel");
-            }
-
-            // Tag fields
-            byte[] id = readBytesWithNull(in);
-            String[] rawTargets = new String[in.readInt()];
-            in.readStringArray(rawTargets);
-            byte[] pollBytes = readBytesWithNull(in);
-            byte[] activationBytes = readBytesWithNull(in);
-            int serviceHandle = in.readInt();
-
-            // NdefTag fields
-            String[] ndefTargets = new String[in.readInt()];
-            in.readStringArray(ndefTargets);
-            NdefMessage[][] messages = new NdefMessage[in.readInt()][];
-            for (int i=0; i<messages.length; i++) {
-                messages[i] = new NdefMessage[in.readInt()];
-                in.readTypedArray(messages[i], NdefMessage.CREATOR);
-            }
-            return new NdefTag(id, rawTargets, pollBytes, activationBytes, serviceHandle,
-                    ndefTargets, 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
deleted file mode 100644
index aafdbfd..0000000
--- a/core/java/android/nfc/NdefTagConnection.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.nfc;
-
-import java.io.IOException;
-
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * A connection to an NDEF target on an {@link NdefTag}.
- * <p>You can acquire this kind of connection with {@link NfcAdapter#createNdefTagConnection
- * createNdefTagConnection()}. Use the connection to read or write {@link NdefMessage}s.
- * <p class="note"><strong>Note:</strong>
- * Use of this class requires the {@link android.Manifest.permission#NFC}
- * permission.
- * @hide
- */
-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
-     */
-    /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag, String target) throws RemoteException {
-        super(adapter, tag);
-        String[] targets = tag.getNdefTargets();
-        int i;
-
-        // Check target validity
-        for (i=0; i<targets.length; i++) {
-            if (target.equals(targets[i])) {
-                break;
-            }
-        }
-        if (i >= targets.length) {
-            // Target not found
-            throw new IllegalArgumentException();
-        }
-    }
-
-    /**
-     * Internal constructor, to be used by NfcAdapter
-     * @hide
-     */
-    /* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag) throws RemoteException {
-        this(adapter, tag, tag.getNdefTargets()[0]);
-    }
-
-    /**
-     * Read NDEF message(s).
-     * This will always return the most up to date payload, and can block.
-     * It can be canceled with {@link RawTagConnection#close}.
-     * Most NDEF tags will contain just one NDEF message.
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     * @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.mServiceHandle);
-            if (msg == null) {
-                int errorCode = mTagService.getLastError(mTag.mServiceHandle);
-                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) {
-            attemptDeadServiceRecovery(e);
-            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 {@link RawTagConnection#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 {@link NdefRecord} to write several records to a single tag.
-     * For write-many tags, use {@link #makeReadOnly} after this method to attempt
-     * to prevent further modification. For write-once tags this is not
-     * necessary.
-     * <p>Requires {@link android.Manifest.permission#NFC} 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.mServiceHandle, 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) {
-            attemptDeadServiceRecovery(e);
-        }
-    }
-
-    /**
-     * 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 {@link RawTagConnection#close}.
-     * <p>Requires {@link android.Manifest.permission#NFC} 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.mServiceHandle);
-            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) {
-            attemptDeadServiceRecovery(e);
-            return false;
-        }
-    }
-
-    /**
-     * Read/Write mode hint.
-     * Provides a hint if further reads or writes are likely to succeed.
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     * @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.mServiceHandle);
-            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) {
-            attemptDeadServiceRecovery(e);
-            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
index 88b6ea4..a1c22bf 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -1,25 +1,26 @@
 /*
- * 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.
+ * 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.app.ActivityThread;
-import android.content.Context;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.nfc.INfcAdapter;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -40,6 +41,12 @@
     public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
 
     /**
+     * Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
+     * @hide
+     */
+    public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST";
+
+    /**
      * Mandatory Tag extra for the ACTION_TAG intents.
      * @hide
      */
@@ -170,6 +177,14 @@
     }
 
     /**
+     * Returns the binder interface to the service.
+     * @hide
+     */
+    public INfcAdapter getService() {
+        return mService;
+    }
+    
+    /**
      * Helper to check if this device has FEATURE_NFC, but without using
      * a context.
      * Equivalent to
@@ -230,8 +245,11 @@
         }
     }
 
-    /** NFC service dead - attempt best effort recovery */
-    /*package*/ void attemptDeadServiceRecovery(Exception e) {
+    /**
+     * NFC service dead - attempt best effort recovery
+     * @hide
+     */
+    public void attemptDeadServiceRecovery(Exception e) {
         Log.e(TAG, "NFC service dead - attempting to recover", e);
         INfcAdapter service = getServiceInterface();
         if (service == null) {
@@ -301,16 +319,41 @@
     }
 
     /**
-     * Create a raw tag connection to the default Target
+     * 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 {@link android.Manifest.permission#NFC} permission.
+     *
+     * @param message NDEF message to make public
      * @hide
      */
-    public RawTagConnection createRawTagConnection(Tag tag) {
-        if (tag.mServiceHandle == 0) {
-            throw new IllegalArgumentException("mock tag cannot be used for connections");
-        }
+    public void setLocalNdefMessage(NdefMessage message) {
         try {
-            return new RawTagConnection(this, tag);
+            mService.localSet(message);
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+        }
+    }
+
+    /**
+     * Get the NDEF Message that this adapter appears as to Tag readers.
+     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     *
+     * @return NDEF Message that is publicly readable
+     * @hide
+     */
+    public NdefMessage getLocalNdefMessage() {
+        try {
+            return mService.localGet();
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             return null;
@@ -318,52 +361,14 @@
     }
 
     /**
-     * Create a raw tag connection to the specified Target
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     * Create an Nfc Secure Element Connection
      * @hide
      */
-    public RawTagConnection createRawTagConnection(Tag tag, String target) {
-        if (tag.mServiceHandle == 0) {
-            throw new IllegalArgumentException("mock tag cannot be used for connections");
-        }
+    public NfcSecureElement createNfcSecureElementConnection() {
         try {
-            return new RawTagConnection(this, tag, target);
+            return new NfcSecureElement(mService.getNfcSecureElementInterface());
         } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            return null;
-        }
-    }
-
-    /**
-     * Create an NDEF tag connection to the default Target
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     * @hide
-     */
-    public NdefTagConnection createNdefTagConnection(NdefTag tag) {
-        if (tag.mServiceHandle == 0) {
-            throw new IllegalArgumentException("mock tag cannot be used for connections");
-        }
-        try {
-            return new NdefTagConnection(this, tag);
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
-            return null;
-        }
-    }
-
-    /**
-     * Create an NDEF tag connection to the specified Target
-     * <p>Requires {@link android.Manifest.permission#NFC} permission.
-     * @hide
-     */
-    public NdefTagConnection createNdefTagConnection(NdefTag tag, String target) {
-        if (tag.mServiceHandle == 0) {
-            throw new IllegalArgumentException("mock tag cannot be used for connections");
-        }
-        try {
-            return new NdefTagConnection(this, tag, target);
-        } catch (RemoteException e) {
-            attemptDeadServiceRecovery(e);
+            Log.e(TAG, "createNfcSecureElementConnection failed", e);
             return null;
         }
     }
diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java
new file mode 100755
index 0000000..5f4c066
--- /dev/null
+++ b/core/java/android/nfc/NfcSecureElement.java
@@ -0,0 +1,138 @@
+/*
+ * 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.technology.TagTechnology;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.IOException;
+
+//import android.util.Log;
+
+/**
+ * This class provides the primary API for managing all aspects Secure Element.
+ * Get an instance of this class by calling
+ * Context.getSystemService(Context.NFC_SERVICE).
+ * @hide
+ */
+public final class NfcSecureElement {
+
+    private static final String TAG = "NfcSecureElement";
+
+    private INfcSecureElement mService;
+    
+       
+    /**
+     * @hide
+     */
+    public NfcSecureElement(INfcSecureElement mSecureElementService) {
+        mService = mSecureElementService;
+    }
+
+    public int openSecureElementConnection(String seType) throws IOException {
+        if (seType.equals("SmartMX")) {
+            try {
+                int handle = mService.openSecureElementConnection();
+                // Handle potential errors
+                if (handle != 0) {
+                    return handle;
+                } else {
+                    throw new IOException("SmartMX connection not allowed");
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException in openSecureElementConnection(): ", e);
+                return 0;
+            }
+
+        } else if (seType.equals("UICC")) {
+            return 0;
+        } else {
+        	throw new IOException("Wrong Secure Element type");
+        }
+    }
+
+
+    public byte [] exchangeAPDU(int handle,byte [] data) throws IOException {
+        
+
+        // Perform exchange APDU
+        try {
+            byte[] response = mService.exchangeAPDU(handle, data);
+            // Handle potential errors
+            if (response == null) {
+            	throw new IOException("Exchange APDU failed");
+            }
+            return response;
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in exchangeAPDU(): ", e);
+            return null;
+        }
+    }
+
+    public void closeSecureElementConnection(int handle) throws IOException {
+         
+        try {
+            int status = mService.closeSecureElementConnection(handle);
+            // Handle potential errors
+            if (ErrorCodes.isError(status)) {
+            	throw new IOException("Error during the conection close");
+            };
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in closeSecureElement(): ", e);
+        }
+    }
+    
+    
+    /**
+     * Returns target type. constants.
+     * 
+     * @return Secure Element technology type. The possible values are defined in
+     * {@link TagTechnology}
+     * 
+     */
+    public int[] getSecureElementTechList(int handle) throws IOException {
+        try {
+            return mService.getSecureElementTechList(handle);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in getType(): ", e);
+            return null;
+        }
+    }
+    
+    /**
+     * Returns Secure Element UID.
+     * 
+     * @return Secure Element UID.
+     */
+    public byte[] getSecureElementUid(int handle) throws IOException {
+        
+        byte[] uid = null;
+        try {            
+            uid = mService.getSecureElementUid(handle);
+            // Handle potential errors
+            if (uid == null) {
+                throw new IOException("Get Secure Element UID failed");
+            }
+            return uid;
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in getType(): ", e);
+            return null;
+        }
+    }
+
+}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 5d0b04c..2f6b3a5 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -16,8 +16,21 @@
 
 package android.nfc;
 
+import android.nfc.technology.IsoDep;
+import android.nfc.technology.MifareClassic;
+import android.nfc.technology.MifareUltralight;
+import android.nfc.technology.NfcV;
+import android.nfc.technology.Ndef;
+import android.nfc.technology.NfcA;
+import android.nfc.technology.NfcB;
+import android.nfc.technology.NfcF;
+import android.nfc.technology.TagTechnology;
+import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+
+import java.util.Arrays;
 
 /**
  * Represents a (generic) discovered tag.
@@ -30,13 +43,13 @@
  * {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra
  * in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable
  * and represents the state of the tag at the time of discovery. It can be
- * directly queried for its UID and Type, or used to create a {@link RawTagConnection}
- * (with {@link NfcAdapter#createRawTagConnection createRawTagConnection()}).
+ * directly queried for its UID and Type, or used to create a {@link TagTechnology}
+ * (with {@link Tag#getTechnology(int)}).
  * <p>
- * A {@link Tag} can  be used to create a {@link RawTagConnection} only while the tag is in
+ * A {@link Tag} can  be used to create a {@link TagTechnology} only while the tag is in
  * range. If it is removed and then returned to range, then the most recent
  * {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a
- * {@link RawTagConnection}.
+ * {@link TagTechnology}.
  * <p>This is an immutable data class. All properties are set at Tag discovery
  * time and calls on this class will retrieve those read-only properties, and
  * not cause any further RF activity or block. Note however that arrays passed to and
@@ -44,78 +57,39 @@
  * @hide
  */
 public class Tag implements Parcelable {
-    /**
-     * ISO 14443-3A technology.
-     * <p>
-     * Includes Topaz (which is -3A compatible)
-     */
-    public static final String TARGET_ISO_14443_3A = "iso14443_3a";
-
-    /**
-     * ISO 14443-3B technology.
-     */
-    public static final String TARGET_ISO_14443_3B = "iso14443_3b";
-
-    /**
-     * ISO 14443-4 technology.
-     */
-    public static final String TARGET_ISO_14443_4 = "iso14443_4";
-
-    /**
-     * ISO 15693 technology, commonly known as RFID.
-     */
-    public static final String TARGET_ISO_15693 = "iso15693";
-
-    /**
-     * JIS X-6319-4 technology, commonly known as Felica.
-     */
-    public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4";
-
-    /**
-     * Any other technology.
-     */
-    public static final String TARGET_OTHER = "other";
-
-    /*package*/ final boolean mIsNdef;
     /*package*/ final byte[] mId;
-    /*package*/ final String[] mRawTargets;
-    /*package*/ final byte[] mPollBytes;
-    /*package*/ final byte[] mActivationBytes;
+    /*package*/ final int[] mTechList;
+    /*package*/ final Bundle[] mTechExtras;
     /*package*/ final int mServiceHandle;  // for use by NFC service, 0 indicates a mock
 
     /**
      * Hidden constructor to be used by NFC service and internal classes.
      * @hide
      */
-    public Tag(byte[] id, boolean isNdef, String[] rawTargets, byte[] pollBytes,
-            byte[] activationBytes, int serviceHandle) {
-        if (rawTargets == null) {
+    public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle) {
+        if (techList == null) {
             throw new IllegalArgumentException("rawTargets cannot be null");
         }
-        mIsNdef = isNdef;
         mId = id;
-        mRawTargets = rawTargets;
-        mPollBytes = pollBytes;
-        mActivationBytes = activationBytes;
+        mTechList = Arrays.copyOf(techList, techList.length);
+        // Ensure mTechExtras is as long as mTechList
+        mTechExtras = Arrays.copyOf(techListExtras, techList.length);
         mServiceHandle = serviceHandle;
     }
 
     /**
      * Construct a mock Tag.
      * <p>This is an application constructed tag, so NfcAdapter methods on this
-     * Tag such as {@link NfcAdapter#createRawTagConnection} will fail with
+     * Tag such as {@link #getTechnology} may fail with
      * {@link IllegalArgumentException} since it does not represent a physical Tag.
      * <p>This constructor might be useful for mock testing.
      * @param id The tag identifier, can be null
-     * @param rawTargets must not be null
-     * @param pollBytes can be null
-     * @param activationBytes can be null
+     * @param techList must not be null
      * @return freshly constructed tag
      */
-    public static Tag createMockTag(byte[] id, String[] rawTargets, byte[] pollBytes,
-            byte[] activationBytes) {
+    public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) {
         // set serviceHandle to 0 to indicate mock tag
-        return new Tag(id, false, rawTargets, pollBytes, activationBytes, 0);
+        return new Tag(id, techList, techListExtras, 0);
     }
 
     /**
@@ -127,16 +101,6 @@
     }
 
     /**
-     * Return the available targets that this NFC adapter can use to create
-     * a RawTagConnection.
-     *
-     * @return raw targets, will not be null
-     */
-    public String[] getRawTargets() {
-        return mRawTargets;
-    }
-
-    /**
      * Get the Tag Identifier (if it has one).
      * <p>Tag ID is usually a serial number for the tag.
      *
@@ -147,37 +111,69 @@
     }
 
     /**
-     * Get the low-level bytes returned by this Tag at poll-time.
-     * <p>These can be used to help with advanced identification of a Tag.
-     * <p>The meaning of these bytes depends on the Tag technology.
-     * <p>ISO14443-3A: ATQA/SENS_RES
-     * <p>ISO14443-3B: Application data (4 bytes) and Protocol Info (3 bytes) from ATQB/SENSB_RES
-     * <p>JIS_X_6319_4: PAD0 (2 byte), PAD1 (2 byte), MRTI(2 byte), PAD2 (1 byte), RC (2 byte)
-     * <p>ISO15693: response flags (1 byte), DSFID (1 byte)
-     * from SENSF_RES
+     * Returns technologies present in the tag that this implementation understands,
+     * or a zero length array if there are no supported technologies on this tag.
      *
-     * @return poll bytes, or null if they do not exist for this Tag technology
-     * @hide
+     * The elements of the list are guaranteed be one of the constants defined in
+     * {@link TagTechnology}. 
+     *
+     * The ordering of the returned array is undefined and should not be relied upon.
      */
-    public byte[] getPollBytes() {
-        return mPollBytes;
+    public int[] getTechnologyList() { 
+        return Arrays.copyOf(mTechList, mTechList.length);
     }
 
     /**
-     * Get the low-level bytes returned by this Tag at activation-time.
-     * <p>These can be used to help with advanced identification of a Tag.
-     * <p>The meaning of these bytes depends on the Tag technology.
-     * <p>ISO14443-3A: SAK/SEL_RES
-     * <p>ISO14443-3B: null
-     * <p>ISO14443-3A & ISO14443-4: SAK/SEL_RES, historical bytes from ATS  <TODO: confirm>
-     * <p>ISO14443-3B & ISO14443-4: ATTRIB response
-     * <p>JIS_X_6319_4: null
-     * <p>ISO15693: response flags (1 byte), DSFID (1 byte): null
-     * @return activation bytes, or null if they do not exist for this Tag technology
-     * @hide
+     * Returns the technology, or null if not present
      */
-    public byte[] getActivationBytes() {
-        return mActivationBytes;
+    public TagTechnology getTechnology(int tech) {
+        int pos = -1;
+        for (int idx = 0; idx < mTechList.length; idx++) {
+          if (mTechList[idx] == tech) {
+              pos = idx;
+              break;
+          }
+        }
+        if (pos < 0) {
+            return null;
+        }
+
+        Bundle extras = mTechExtras[pos];
+        NfcAdapter adapter = NfcAdapter.getDefaultAdapter();
+        try {
+            switch (tech) {
+                case TagTechnology.NFC_A: {
+                    return new NfcA(adapter, this, extras);
+                }
+                case TagTechnology.NFC_B: {
+                    return new NfcB(adapter, this, extras);
+                }
+                case TagTechnology.ISO_DEP: {
+                    return new IsoDep(adapter, this, extras);
+                }
+                case TagTechnology.NFC_V: {
+                    return new NfcV(adapter, this, extras);
+                }
+                case TagTechnology.NDEF: {
+                    return new Ndef(adapter, this, tech, extras);
+                }
+                case TagTechnology.NFC_F: {
+                    return new NfcF(adapter, this, extras);
+                }
+                case TagTechnology.MIFARE_CLASSIC: {
+                    return new MifareClassic(adapter, this, extras);
+                }
+                case TagTechnology.MIFARE_ULTRALIGHT: {
+                    return new MifareUltralight(adapter, this, extras);
+                }
+
+                default: {
+                    throw new UnsupportedOperationException("Tech " + tech + " not supported");
+                }
+            }
+        } catch (RemoteException e) {
+            return null;
+        }
     }
 
     @Override
@@ -185,13 +181,9 @@
         StringBuilder sb = new StringBuilder("TAG ")
             .append("uid = ")
             .append(mId)
-            .append(" poll ")
-            .append(mPollBytes)
-            .append(" activation ")
-            .append(mActivationBytes)
-            .append(" Raw [");
-        for (String s : mRawTargets) {
-            sb.append(s)
+            .append(" Tech [");
+        for (int i : mTechList) {
+            sb.append(i)
             .append(", ");
         }
         return sb.toString();
@@ -221,37 +213,32 @@
         return 0;
     }
 
-
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mIsNdef ? 1 : 0);
         writeBytesWithNull(dest, mId);
-        dest.writeInt(mRawTargets.length);
-        dest.writeStringArray(mRawTargets);
-        writeBytesWithNull(dest, mPollBytes);
-        writeBytesWithNull(dest, mActivationBytes);
+        dest.writeInt(mTechList.length);
+        dest.writeIntArray(mTechList);
+        dest.writeTypedArray(mTechExtras, 0);
         dest.writeInt(mServiceHandle);
     }
 
     public static final Parcelable.Creator<Tag> CREATOR =
             new Parcelable.Creator<Tag>() {
+        @Override
         public Tag createFromParcel(Parcel in) {
-            boolean isNdef = (in.readInt() == 1);
-            if (isNdef) {
-                throw new IllegalArgumentException("Creating Tag from NdefTag parcel");
-            }
             // Tag fields
             byte[] id = Tag.readBytesWithNull(in);
-            String[] rawTargets = new String[in.readInt()];
-            in.readStringArray(rawTargets);
-            byte[] pollBytes = Tag.readBytesWithNull(in);
-            byte[] activationBytes = Tag.readBytesWithNull(in);
+            int[] techList = new int[in.readInt()];
+            in.readIntArray(techList);
+            Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
             int serviceHandle = in.readInt();
 
-            return new Tag(id, isNdef, rawTargets, pollBytes, activationBytes, serviceHandle);
+            return new Tag(id, techList, techExtras, serviceHandle);
         }
+
+        @Override
         public Tag[] newArray(int size) {
             return new Tag[size];
         }
     };
-}
\ No newline at end of file
+}
diff --git a/core/java/android/nfc/RawTagConnection.java b/core/java/android/nfc/technology/BasicTagTechnology.java
similarity index 75%
rename from core/java/android/nfc/RawTagConnection.java
rename to core/java/android/nfc/technology/BasicTagTechnology.java
index bfdaa77..6b281b9 100644
--- a/core/java/android/nfc/RawTagConnection.java
+++ b/core/java/android/nfc/technology/BasicTagTechnology.java
@@ -14,31 +14,25 @@
  * limitations under the License.
  */
 
-package android.nfc;
+package android.nfc.technology;
 
 import java.io.IOException;
 
+import android.nfc.INfcAdapter;
+import android.nfc.INfcTag;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
 import android.os.RemoteException;
 import android.util.Log;
 
 /**
- * A low-level connection to a {@link Tag} target.
- * <p>You can acquire this kind of connection with {@link NfcAdapter#createRawTagConnection
- * createRawTagConnection()}. Use the connection to send and receive data with {@link #transceive
- * transceive()}.
- * <p>
- * Applications must implement their own protocol stack on top of {@link #transceive transceive()}.
- *
- * <p class="note"><strong>Note:</strong>
- * Use of this class requires the {@link android.Manifest.permission#NFC}
- * permission.
- * @hide
+ * A base class for tag technologies that are built on top of transceive().
  */
-public class RawTagConnection {
+/* package */ abstract class BasicTagTechnology implements TagTechnology {
 
     /*package*/ final Tag mTag;
     /*package*/ boolean mIsConnected;
-    /*package*/ String mSelectedTarget;
+    /*package*/ int mSelectedTechnology;
     private final NfcAdapter mAdapter;
 
     // Following fields are final after construction, except for
@@ -49,30 +43,40 @@
 
     private static final String TAG = "NFC";
 
-    /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag, String target) throws RemoteException {
-        String[] targets = tag.getRawTargets();
+    /**
+     * @hide
+     */
+    public BasicTagTechnology(NfcAdapter adapter, Tag tag, int tech) throws RemoteException {
+        int[] techList = tag.getTechnologyList();
         int i;
 
         // Check target validity
-        for (i=0;i<targets.length;i++) {
-            if (target.equals(targets[i])) {
+        for (i = 0; i < techList.length; i++) {
+            if (tech == techList[i]) {
                 break;
             }
         }
-        if (i >= targets.length) {
-            // Target not found
-            throw new IllegalArgumentException();
+        if (i >= techList.length) {
+            // Technology not found
+            throw new IllegalArgumentException("Technology " + tech + " not present on tag " + tag);
         }
 
         mAdapter = adapter;
-        mService = mAdapter.mService;
-        mTagService = mService.getNfcTagInterface();
+        mService = mAdapter.getService();
+        try {
+          mTagService = mService.getNfcTagInterface();
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+        }
         mTag = tag;
-        mSelectedTarget = target;
+        mSelectedTechnology = tech;
     }
 
-    /*package*/ RawTagConnection(NfcAdapter adapter, Tag tag) throws RemoteException {
-        this(adapter, tag, tag.getRawTargets()[0]);
+    /**
+     * @hide
+     */
+    public BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException {
+        this(adapter, tag, tag.getTechnologyList()[0]);
     }
 
     /** NFC service dead - attempt best effort recovery */
@@ -80,7 +84,7 @@
         mAdapter.attemptDeadServiceRecovery(e);
         /* assigning to mService is not thread-safe, but this is best-effort code
          * and on a well-behaved system should never happen */
-        mService = mAdapter.mService;
+        mService = mAdapter.getService();
         try {
             mTagService = mService.getNfcTagInterface();
         } catch (RemoteException e2) {
@@ -92,6 +96,7 @@
      * Get the {@link Tag} this connection is associated with.
      * <p>Requires {@link android.Manifest.permission#NFC} permission.
      */
+    @Override
     public Tag getTag() {
         return mTag;
     }
@@ -99,8 +104,9 @@
     /**
      * <p>Requires {@link android.Manifest.permission#NFC} permission.
      */
-    public String getTagTarget() {
-        return mSelectedTarget;
+    @Override
+    public int getTechnologyId() {
+        return mSelectedTechnology;
     }
 
     /**
@@ -119,7 +125,7 @@
         }
 
         try {
-            return mTagService.isPresent(mTag.mServiceHandle);
+            return mTagService.isPresent(mTag.getServiceHandle());
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
             return false;
@@ -136,6 +142,7 @@
      * <p>Requires {@link android.Manifest.permission#NFC} permission.
      * @throws IOException if the target is lost, or connect canceled
      */
+    @Override
     public void connect() throws IOException {
         //TODO(nxp): enforce exclusivity
         mIsConnected = true;
@@ -151,10 +158,11 @@
      * calls to {@link #transceive transceive()} or {@link #connect} will fail.
      * <p>Requires {@link android.Manifest.permission#NFC} permission.
      */
+    @Override
     public void close() {
         mIsConnected = false;
         try {
-            mTagService.close(mTag.mServiceHandle);
+            mTagService.close(mTag.getServiceHandle());
         } catch (RemoteException e) {
             attemptDeadServiceRecovery(e);
         }
@@ -173,7 +181,7 @@
      */
     public byte[] transceive(byte[] data) throws IOException {
         try {
-            byte[] response = mTagService.transceive(mTag.mServiceHandle, data);
+            byte[] response = mTagService.transceive(mTag.getServiceHandle(), data);
             if (response == null) {
                 throw new IOException("transcieve failed");
             }
diff --git a/core/java/android/nfc/technology/IsoDep.java b/core/java/android/nfc/technology/IsoDep.java
new file mode 100644
index 0000000..5346c67
--- /dev/null
+++ b/core/java/android/nfc/technology/IsoDep.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as
+ * ISO1443-4.
+ *
+ * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class IsoDep extends BasicTagTechnology {
+    /** @hide */
+    public static final String EXTRA_ATTRIB = "attrib";
+    /** @hide */
+    public static final String EXTRA_HIST_BYTES = "histbytes";
+
+    private byte[] mAttrib = null;
+    private byte[] mHistBytes = null;
+
+    public IsoDep(NfcAdapter adapter, Tag tag, Bundle extras)
+            throws RemoteException {
+        super(adapter, tag, TagTechnology.ISO_DEP);
+        if (extras != null) {
+            mAttrib = extras.getByteArray(EXTRA_ATTRIB);
+            mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
+        }
+    }
+
+    /**
+     * 3A only
+     */
+    public byte[] getHistoricalBytes() { return mHistBytes; }
+
+    /**
+     * 3B only
+     */
+    public byte[] getAttrib() { return mAttrib; }
+
+    /**
+     * Attempts to select the given application on the tag. Note that this only works
+     * if the tag supports ISO7816-4, which not all IsoDep tags support. If the tag doesn't
+     * support ISO7816-4 this will throw {@link UnsupportedOperationException}.
+     *
+     * This method requires that you call {@link #connect} before calling it.
+     *
+     * @throws IOException, UnsupportedOperationException
+     */
+    public void selectAid(byte[] aid) throws IOException, UnsupportedOperationException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/core/java/android/nfc/technology/MifareClassic.java b/core/java/android/nfc/technology/MifareClassic.java
new file mode 100644
index 0000000..ba3a425
--- /dev/null
+++ b/core/java/android/nfc/technology/MifareClassic.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * Concrete class for TagTechnology.MIFARE_CLASSIC
+ *
+ * Mifare classic has n sectors, with varying sizes, although
+ * they are at least the same pattern for any one mifare classic
+ * product. Each sector has two keys. Authentication with the correct
+ * key is needed before access to any sector.
+ *
+ * Each sector has k blocks.
+ * Block size is constant across the whole mifare classic family.
+ */
+public final class MifareClassic extends BasicTagTechnology {
+    /**
+     * The well-known, default MIFARE read key.
+     * Use this key to effectively make the payload in this sector
+     * public.
+     */
+    public static final byte[] KEY_DEFAULT =
+            {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
+    /**
+     * The well-known, default Mifare Application Directory read key.
+     */
+    public static final byte[] KEY_MIFARE_APPLICATION_DIRECTORY =
+            {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
+    /**
+     * The well-known, default read key for NDEF data on a Mifare Classic
+     */
+    public static final byte[] KEY_NFC_FORUM =
+            {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
+
+    public static final int TYPE_CLASSIC = 0;
+    public static final int TYPE_PLUS = 1;
+    public static final int TYPE_PRO = 2;
+    public static final int TYPE_DESFIRE = 3;
+    public static final int TYPE_ULTRALIGHT = 4;
+    public static final int TYPE_UNKNOWN = 5;
+
+    public static final int SIZE_1K = 1024;
+    public static final int SIZE_2K = 2048;
+    public static final int SIZE_4K = 4096;
+    public static final int SIZE_MINI = 320;
+    public static final int SIZE_UNKNOWN = 0;
+
+    private boolean mIsEmulated;
+    private int mType;
+    private int mSize;
+
+    public MifareClassic(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
+        super(adapter, tag, TagTechnology.MIFARE_CLASSIC);
+
+        // Check if this could actually be a Mifare
+        NfcA a = (NfcA) tag.getTechnology(TagTechnology.NFC_A);
+        //short[] ATQA = getATQA(tag);
+
+        mIsEmulated = false;
+        mType = TYPE_UNKNOWN;
+        mSize = SIZE_UNKNOWN;
+
+        switch (a.getSak()) {
+            case 0x00:
+                // could be UL or UL-C
+                mType = TYPE_ULTRALIGHT;
+                break;
+            case 0x08:
+                // Type == classic
+                // Size = 1K
+                mType = TYPE_CLASSIC;
+                mSize = SIZE_1K;
+                break;
+            case 0x09:
+                // Type == classic mini
+                // Size == ?
+                mType = TYPE_CLASSIC;
+                mSize = SIZE_MINI;
+                break;
+            case 0x10:
+                // Type == MF+
+                // Size == 2K
+                // SecLevel = SL2
+                mType = TYPE_PLUS;
+                mSize = SIZE_2K;
+                break;
+            case 0x11:
+                // Type == MF+
+                // Size == 4K
+                // Seclevel = SL2
+                mType = TYPE_PLUS;
+                mSize = SIZE_4K;
+                break;
+            case 0x18:
+                // Type == classic
+                // Size == 4k
+                mType = TYPE_CLASSIC;
+                mSize = SIZE_4K;
+                break;
+            case 0x20:
+                // TODO this really should be a short, not byte
+                if (a.getAtqa()[0] == 0x03) {
+                    // Type == DESFIRE
+                    mType = TYPE_DESFIRE;
+                } else {
+                    // Type == MF+
+                    // SL = SL3
+                    mType = TYPE_PLUS;
+                    mSize = SIZE_UNKNOWN;
+                }
+                break;
+            case 0x28:
+                // Type == MF Classic
+                // Size == 1K
+                // Emulated == true
+                mType = TYPE_CLASSIC;
+                mSize = SIZE_1K;
+                mIsEmulated = true;
+                break;
+            case 0x38:
+                // Type == MF Classic
+                // Size == 4K
+                // Emulated == true
+                mType = TYPE_CLASSIC;
+                mSize = SIZE_4K;
+                mIsEmulated = true;
+                break;
+            case 0x88:
+                // Type == MF Classic
+                // Size == 1K
+                // NXP-tag: false
+                mType = TYPE_CLASSIC;
+                mSize = SIZE_1K;
+                break;
+            case 0x98:
+            case 0xB8:
+                // Type == MF Pro
+                // Size == 4K
+                mType = TYPE_PRO;
+                mSize = SIZE_4K;
+                break;
+            default:
+                // Unknown, not MIFARE
+                break;
+        }
+    }
+
+    // Immutable data known at discovery time
+    public int getSize() {
+        return mSize;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    public boolean isEmulated() {
+        return mIsEmulated;
+    }
+
+    public int getSectorCount() {
+        switch (mSize) {
+            case SIZE_1K: {
+                return 16;
+            }
+            case SIZE_2K: {
+                return 32;
+            }
+            case SIZE_4K: {
+                return 40;
+            }
+            case SIZE_MINI: {
+                return 5;
+            }
+            default: {
+                return 0;
+            }
+        }
+    }
+
+    public int getSectorSize(int sector) {
+        return getBlockCount(sector) * 16;
+    }
+
+    public int getBlockCount(int sector) {
+        if (sector >= getSectorCount()) {
+            throw new IllegalArgumentException("this card only has " + getSectorCount() +
+                    " sectors");
+        }
+
+        if (sector <= 32) {
+            return 4;
+        } else {
+            return 16;
+        }
+    }
+
+    private byte firstBlockInSector(int sector) {
+        if (sector < 32) {
+            return (byte) ((sector * 4) & 0xff);
+        } else {
+            return (byte) ((32 * 4 + ((sector - 32) * 16)) & 0xff);
+        }
+    }
+
+    // Methods that require connect()
+    /**
+     * Authenticate for a given sector.
+     */
+    public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
+        byte[] cmd = new byte[12];
+
+        // First byte is the command
+        if (keyA) {
+            cmd[0] = 0x60; // phHal_eMifareAuthentA
+        } else {
+            cmd[0] = 0x61; // phHal_eMifareAuthentB
+        }
+
+        // Second byte is block address
+        cmd[1] = firstBlockInSector(sector);
+
+        // Next 4 bytes are last 4 bytes of UID
+        byte[] uid = getTag().getId();
+        System.arraycopy(uid, uid.length - 4, cmd, 2, 4);
+
+        // Next 6 bytes are key
+        System.arraycopy(key, 0, cmd, 6, 6);
+
+        try {
+            if ((transceive(cmd) != null)) {
+                return true;
+            }
+        } catch (IOException e) {
+            // No need to deal with, will return false anyway
+        }
+        return false;
+    }
+
+    /**
+     * Sector indexing starts at 0.
+     * Block indexing starts at 0, and resets in each sector.
+     * @throws IOException
+     */
+    public byte[] readBlock(int sector, int block) throws IOException {
+        byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
+        byte[] blockread_cmd = { 0x30, addr }; // phHal_eMifareRead
+
+        // TODO deal with authentication problems
+        return transceive(blockread_cmd);
+    }
+
+//    public byte[] readSector(int sector);
+    //TODO: define an enumeration for access control settings
+//    public int readSectorAccessControl(int sector);
+
+    /**
+     * @throws IOException
+     * @throws NotAuthenticatedException
+     */
+/*
+    public void writeBlock(int block, byte[] data);
+    public void writeSector(int block, byte[] sector);
+    public void writeSectorAccessControl(int sector, int access);
+    public void increment(int block);
+    public void decrement(int block);
+*/
+}
diff --git a/core/java/android/nfc/technology/MifareUltralight.java b/core/java/android/nfc/technology/MifareUltralight.java
new file mode 100644
index 0000000..dd1dae9
--- /dev/null
+++ b/core/java/android/nfc/technology/MifareUltralight.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * Concrete class for TagTechnology.MIFARE_ULTRALIGHT
+ *
+ * Mifare classic has n sectors, with varying sizes, although
+ * they are at least the same pattern for any one mifare classic
+ * product. Each sector has two keys. Authentication with the correct
+ * key is needed before access to any sector.
+ *
+ * Each sector has k blocks.
+ * Block size is constant across the whole mifare classic family.
+ */
+public final class MifareUltralight extends BasicTagTechnology {
+    public static final int TYPE_ULTRALIGHT = 1;
+    public static final int TYPE_ULTRALIGHT_C = 2;
+    public static final int TYPE_UNKNOWN = 10;
+
+		private static final int NXP_MANUFACTURER_ID = 0x04;
+
+    private int mType;
+
+    public MifareUltralight(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
+        super(adapter, tag, TagTechnology.MIFARE_ULTRALIGHT);
+
+        // Check if this could actually be a Mifare
+        NfcA a = (NfcA) tag.getTechnology(TagTechnology.NFC_A);
+
+        mType = TYPE_UNKNOWN;
+
+        if( a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID ) {
+					// could be UL or UL-C
+					mType = TYPE_ULTRALIGHT;
+        }
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    // Methods that require connect()
+    /**
+     * @throws IOException
+     */
+    public byte[] readBlock(int block) throws IOException {
+        byte[] blockread_cmd = { 0x30, (byte)block }; // phHal_eMifareRead
+        return transceive(blockread_cmd);
+    }
+
+    /**
+     * @throws IOException
+     */
+/*
+    public byte[] readOTP();
+    public void writePage(int block, byte[] data);
+    public void writeBlock(int block, byte[] data);
+*/
+}
diff --git a/core/java/android/nfc/technology/Ndef.java b/core/java/android/nfc/technology/Ndef.java
new file mode 100644
index 0000000..1e3da2a
--- /dev/null
+++ b/core/java/android/nfc/technology/Ndef.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.ErrorCodes;
+import android.nfc.FormatException;
+import android.nfc.NdefMessage;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * A high-level connection to a {@link Tag} using one of the NFC type 1, 2, 3, or 4 technologies
+ * to interact with NDEF data. MiFare Classic cards that present NDEF data may also be used
+ * via this class. To determine the exact technology being used call {@link #getTechnologyId()}
+ *
+ * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class Ndef extends BasicTagTechnology {
+    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;
+
+    /** @hide */
+    public static final String EXTRA_NDEF_MSG = "ndefmsg";
+
+    /**
+     * Internal constructor, to be used by NfcAdapter
+     * @hide
+     */
+    public Ndef(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
+        super(adapter, tag, tech);
+    }
+
+    /**
+     * Get the primary NDEF message on this tag. This data is read at discovery time
+     * and does not require a connection.
+     */
+    public NdefMessage getNdefMessage() throws IOException, FormatException {
+        try {
+            int serviceHandle = mTag.getServiceHandle();
+            NdefMessage msg = mTagService.read(serviceHandle);
+            if (msg == null) {
+                int errorCode = mTagService.getLastError(serviceHandle);
+                switch (errorCode) {
+                    case ErrorCodes.ERROR_IO:
+                        throw new IOException();
+                    case ErrorCodes.ERROR_INVALID_PARAM:
+                        throw new FormatException();
+                    default:
+                        // Should not happen
+                        throw new IOException();
+                }
+            }
+            return msg;
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            return null;
+        }
+    }
+
+    /**
+     * Get optional extra NDEF messages.
+     * Some tags may contain extra NDEF messages, but not all
+     * implementations will be able to read them.
+     */
+    public NdefMessage[] getExtraNdefMessage() throws IOException, FormatException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Get maximum NDEF message size in bytes
+     */
+    public int getSize() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Read/Write mode hint.
+     * Provides a hint if further reads or writes are likely to succeed.
+     * <p>Requires {@link android.Manifest.permission#NFC} permission.
+     * @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.getServiceHandle());
+            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) {
+            attemptDeadServiceRecovery(e);
+            return NDEF_MODE_UNKNOWN;
+        }
+    }
+
+    // Methods that require connect()
+    /**
+     * Overwrite the primary NDEF message
+     * @throws IOException
+     */
+    public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
+        try {
+            int errorCode = mTagService.write(mTag.getServiceHandle(), msg);
+            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) {
+            attemptDeadServiceRecovery(e);
+        }
+    }
+
+    /**
+     * Attempt to write extra NDEF messages.
+     * Implementations may be able to write extra NDEF
+     * message after the first primary message, but it is not
+     * guaranteed. Even if it can be written, other implementations
+     * may not be able to read NDEF messages after the primary message.
+     * It is recommended to use additional NDEF records instead.
+     *
+     * @throws IOException
+     */
+    public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Set the CC field to indicate this tag is read-only
+     * @throws IOException
+     */
+    public boolean makeReadonly() throws IOException {
+        try {
+            int errorCode = mTagService.makeReadOnly(mTag.getServiceHandle());
+            switch (errorCode) {
+                case ErrorCodes.SUCCESS:
+                    return true;
+                case ErrorCodes.ERROR_IO:
+                    throw new IOException();
+                case ErrorCodes.ERROR_INVALID_PARAM:
+                    return false;
+                default:
+                    // Should not happen
+                    throw new IOException();
+            }
+        } catch (RemoteException e) {
+            attemptDeadServiceRecovery(e);
+            return false;
+        }
+    }
+
+    /**
+     * Attempt to use tag specific technology to really make
+     * the tag read-only
+     * For NFC Forum Type 1 and 2 only.
+     */
+    public void makeLowLevelReadonly() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/core/java/android/nfc/technology/NdefFormatable.java b/core/java/android/nfc/technology/NdefFormatable.java
new file mode 100644
index 0000000..7c4f9ab
--- /dev/null
+++ b/core/java/android/nfc/technology/NdefFormatable.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.ErrorCodes;
+import android.nfc.FormatException;
+import android.nfc.NdefMessage;
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.io.IOException;
+
+/**
+ * An interface to a {@link Tag} allowing to format the tag as NDEF.
+ *
+ * <p>You can acquire this kind of interface with {@link Tag#getTechnology(int)}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NdefFormatable extends BasicTagTechnology {
+    /**
+     * Internal constructor, to be used by NfcAdapter
+     * @hide
+     */
+    public NdefFormatable(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
+        super(adapter, tag, tech);
+    }
+
+    /**
+     * Returns whether a tag can be formatted with {@link
+     * NdefFormatable#format(NdefMessage)}
+     */
+    public boolean canBeFormatted() throws IOException {
+      throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Formats a tag as NDEF, if possible. You may supply a first
+     * NdefMessage to be written on the tag.
+     */
+    public void format(NdefMessage firstMessage) throws IOException {
+      throw new UnsupportedOperationException();
+    }
+}
diff --git a/core/java/android/nfc/technology/NfcA.java b/core/java/android/nfc/technology/NfcA.java
new file mode 100644
index 0000000..ef46762
--- /dev/null
+++ b/core/java/android/nfc/technology/NfcA.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+/**
+ * A low-level connection to a {@link Tag} using the NFC-A technology, also known as
+ * ISO1443-3A.
+ *
+ * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NfcA extends BasicTagTechnology {
+    /** @hide */
+    public static final String EXTRA_SAK = "sak";
+    /** @hide */
+    public static final String EXTRA_ATQA = "atqa";
+
+    private short mSak;
+    private byte[] mAtqa;
+
+    public NfcA(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
+        super(adapter, tag, TagTechnology.NFC_A);
+        mSak = extras.getShort(EXTRA_SAK);
+        mAtqa = extras.getByteArray(EXTRA_ATQA);
+    }
+
+    /**
+     * Returns the ATQA/SENS_RES bytes discovered at tag discovery.
+     */
+    public byte[] getAtqa() {
+        return mAtqa;
+    }
+
+    /**
+     * Returns the SAK/SEL_RES discovered at tag discovery.
+     */
+    public short getSak() {
+        return mSak;
+    }
+}
diff --git a/core/java/android/nfc/technology/NfcB.java b/core/java/android/nfc/technology/NfcB.java
new file mode 100644
index 0000000..64cb08a
--- /dev/null
+++ b/core/java/android/nfc/technology/NfcB.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+/**
+ * A low-level connection to a {@link Tag} using the NFC-B technology, also known as
+ * ISO1443-3B.
+ *
+ * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NfcB extends BasicTagTechnology {
+    /** @hide */
+    public static final String EXTRA_ATQB = "atqb";
+
+    private byte[] mAtqb;
+
+    public NfcB(NfcAdapter adapter, Tag tag, Bundle extras)
+            throws RemoteException {
+        super(adapter, tag, TagTechnology.NFC_B);
+    }
+
+    /**
+     * Returns the ATQB/SENSB_RES bytes discovered at tag discovery.
+     */
+    public byte[] getAtqb() {
+        return mAtqb;
+    }
+}
diff --git a/core/java/android/nfc/technology/NfcF.java b/core/java/android/nfc/technology/NfcF.java
new file mode 100644
index 0000000..6741ac8
--- /dev/null
+++ b/core/java/android/nfc/technology/NfcF.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+/**
+ * A low-level connection to a {@link Tag} using the NFC-F technology, also known as
+ * JIS6319-4.
+ *
+ * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NfcF extends BasicTagTechnology {
+    /** @hide */
+    public static final String EXTRA_SC = "systemcode";
+    /** @hide */
+    public static final String EXTRA_PMM = "pmm";
+
+    private byte[] mSystemCode = null;
+    private byte[] mManufacturer = null;
+
+    public NfcF(NfcAdapter adapter, Tag tag, Bundle extras)
+            throws RemoteException {
+        super(adapter, tag, TagTechnology.NFC_F);
+        if (extras != null) {
+            mSystemCode = extras.getByteArray(EXTRA_SC);
+            mManufacturer = extras.getByteArray(EXTRA_PMM);
+        }
+    }
+
+    public byte[] getSystemCode() {
+      return mSystemCode;
+    }
+
+    public byte[] getManufacturer() {
+      return mManufacturer;
+    }
+}
diff --git a/core/java/android/nfc/technology/NfcV.java b/core/java/android/nfc/technology/NfcV.java
new file mode 100644
index 0000000..9b6a16a
--- /dev/null
+++ b/core/java/android/nfc/technology/NfcV.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.NfcAdapter;
+import android.nfc.Tag;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+/**
+ * A low-level connection to a {@link Tag} using the NFC-V technology, also known as
+ * ISO15693.
+ *
+ * <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
+ * Use this class to send and receive data with {@link #transceive transceive()}.
+ *
+ * <p>Applications must implement their own protocol stack on top of
+ * {@link #transceive transceive()}.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * Use of this class requires the {@link android.Manifest.permission#NFC}
+ * permission.
+ */
+public final class NfcV extends BasicTagTechnology {
+    public NfcV(NfcAdapter adapter, Tag tag, Bundle extras)
+            throws RemoteException {
+        super(adapter, tag, TagTechnology.NFC_V);
+    }
+}
diff --git a/core/java/android/nfc/technology/TagTechnology.java b/core/java/android/nfc/technology/TagTechnology.java
new file mode 100644
index 0000000..4704f2b
--- /dev/null
+++ b/core/java/android/nfc/technology/TagTechnology.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc.technology;
+
+import android.nfc.Tag;
+
+import java.io.IOException;
+
+public interface TagTechnology {
+    /**
+     * This object is an instance of {@link NfcA}
+     */
+    public static final int NFC_A = 1;
+
+    /**
+     * This object is an instance of {@link NfcB}
+     */
+    public static final int NFC_B = 2;
+
+    /**
+     * This object is an instance of {@link IsoDep}
+     */
+    public static final int ISO_DEP = 3;
+
+    /**
+     * This object is an instance of {@link NfcF}
+     */
+    public static final int NFC_F = 11;
+
+    /**
+     * This object is an instance of {@link NfcV}
+     */
+    public static final int NFC_V = 21;
+
+    /**
+     * This object is an instance of {@link Ndef}
+     */
+    public static final int NDEF = 101;
+
+    /**
+     * This object is an instance of {@link NdefFormatable}
+     */
+    public static final int NDEF_FORMATABLE = 110;
+
+    /**
+     * This object is an instance of {@link MifareClassic}
+     */
+    public static final int MIFARE_CLASSIC = 200;
+
+    /**
+     * A Mifare Classic tag with NDEF data
+     */
+    public static final int MIFARE_CLASSIC_NDEF = 201;
+
+    /**
+     * This object is an instance of {@link MifareUltralight}
+     */
+    public static final int MIFARE_ULTRALIGHT = 202;
+
+    /**
+     * A Mifare DESFire tag
+     */
+    public static final int MIFARE_DESFIRE = 203;
+
+    /**
+     * Returns the technology type for this tag connection.
+     */
+    public int getTechnologyId();
+
+    /**
+     * Get the backing tag object.
+     */
+    public Tag getTag();
+
+    /**
+     * @throws IOException
+     */
+    public void connect() throws IOException;
+
+    /**
+     * Non-blocking. Immediately causes all blocking calls
+     * to throw IOException.
+     */
+    public void close();
+}
diff --git a/core/java/android/nfc/technology/package.html b/core/java/android/nfc/technology/package.html
new file mode 100644
index 0000000..26b8a32
--- /dev/null
+++ b/core/java/android/nfc/technology/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+{@hide}
+</BODY>
+</HTML>
\ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 07a48e7..b83aea8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -86,7 +86,6 @@
     <protected-broadcast android:name="android.hardware.action.USB_DISCONNECTED" />
     <protected-broadcast android:name="android.hardware.action.USB_STATE" />
 
-    <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" />
 
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_0.png b/core/res/res/drawable-hdpi/stat_sys_battery_0.png
index 82f2509..572e0d3 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_0.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_10.png b/core/res/res/drawable-hdpi/stat_sys_battery_10.png
index 4486553..c9d9436 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_10.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_10.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_100.png b/core/res/res/drawable-hdpi/stat_sys_battery_100.png
index e49448d..754cdf6 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_100.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_15.png b/core/res/res/drawable-hdpi/stat_sys_battery_15.png
new file mode 100644
index 0000000..0b9bed8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_20.png b/core/res/res/drawable-hdpi/stat_sys_battery_20.png
index c8f9c92..c22fead 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_20.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_20.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_25.png b/core/res/res/drawable-hdpi/stat_sys_battery_25.png
new file mode 100644
index 0000000..7c7030a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_25.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_30.png b/core/res/res/drawable-hdpi/stat_sys_battery_30.png
new file mode 100644
index 0000000..d0342df
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_30.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_35.png b/core/res/res/drawable-hdpi/stat_sys_battery_35.png
new file mode 100644
index 0000000..00190ab
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_35.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_40.png b/core/res/res/drawable-hdpi/stat_sys_battery_40.png
index 441bbfb..ced08cd 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_40.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_40.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_45.png b/core/res/res/drawable-hdpi/stat_sys_battery_45.png
new file mode 100644
index 0000000..8f60486
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_45.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_5.png b/core/res/res/drawable-hdpi/stat_sys_battery_5.png
new file mode 100644
index 0000000..d9c6135
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_50.png b/core/res/res/drawable-hdpi/stat_sys_battery_50.png
new file mode 100644
index 0000000..ff0ef0d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_50.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_55.png b/core/res/res/drawable-hdpi/stat_sys_battery_55.png
new file mode 100644
index 0000000..3f7581d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_55.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_60.png b/core/res/res/drawable-hdpi/stat_sys_battery_60.png
index d9467ed..359d65e 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_60.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_60.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_65.png b/core/res/res/drawable-hdpi/stat_sys_battery_65.png
new file mode 100644
index 0000000..b3dc834
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_65.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_70.png b/core/res/res/drawable-hdpi/stat_sys_battery_70.png
new file mode 100644
index 0000000..4995289
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_70.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_75.png b/core/res/res/drawable-hdpi/stat_sys_battery_75.png
new file mode 100644
index 0000000..011f82e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_75.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_80.png b/core/res/res/drawable-hdpi/stat_sys_battery_80.png
index e3f4805..24b32c1 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_80.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_80.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_85.png b/core/res/res/drawable-hdpi/stat_sys_battery_85.png
new file mode 100644
index 0000000..2be76e0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_90.png b/core/res/res/drawable-hdpi/stat_sys_battery_90.png
new file mode 100644
index 0000000..74c3e49
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_90.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_95.png b/core/res/res/drawable-hdpi/stat_sys_battery_95.png
new file mode 100644
index 0000000..2cac442
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_95.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
index c7464f7..061bd2a 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png
index 997feb3..895ade2 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png
index 426a66b..ba57679 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png
index 21582ca..85f461a 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png
index 8a94763..4766067 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png
index fad0d65..8708473 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png b/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png
index dadfe8d..9d65883 100755
--- a/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_unknown.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_0.png b/core/res/res/drawable-mdpi/stat_sys_battery_0.png
index a7068b2..aff0868 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_10.png b/core/res/res/drawable-mdpi/stat_sys_battery_10.png
index 8fd88f3..eedc2b0 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_10.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_10.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_100.png b/core/res/res/drawable-mdpi/stat_sys_battery_100.png
index 5267517..17a955d 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_100.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_15.png b/core/res/res/drawable-mdpi/stat_sys_battery_15.png
new file mode 100644
index 0000000..eef8c92
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_20.png b/core/res/res/drawable-mdpi/stat_sys_battery_20.png
index 8bc41f0..999299f 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_20.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_20.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_25.png b/core/res/res/drawable-mdpi/stat_sys_battery_25.png
new file mode 100644
index 0000000..9f5f68d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_25.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_30.png b/core/res/res/drawable-mdpi/stat_sys_battery_30.png
new file mode 100644
index 0000000..b77c5e3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_30.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_35.png b/core/res/res/drawable-mdpi/stat_sys_battery_35.png
new file mode 100644
index 0000000..018f980
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_35.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_40.png b/core/res/res/drawable-mdpi/stat_sys_battery_40.png
index d827ce9..42e556d 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_40.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_40.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_45.png b/core/res/res/drawable-mdpi/stat_sys_battery_45.png
new file mode 100644
index 0000000..e6b6a6c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_45.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_5.png b/core/res/res/drawable-mdpi/stat_sys_battery_5.png
new file mode 100644
index 0000000..60636a5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_50.png b/core/res/res/drawable-mdpi/stat_sys_battery_50.png
new file mode 100644
index 0000000..eea9221
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_50.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_55.png b/core/res/res/drawable-mdpi/stat_sys_battery_55.png
new file mode 100644
index 0000000..067cbf1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_55.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_60.png b/core/res/res/drawable-mdpi/stat_sys_battery_60.png
index 53399dc..0d4ea98 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_60.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_60.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_65.png b/core/res/res/drawable-mdpi/stat_sys_battery_65.png
new file mode 100644
index 0000000..9e36b78
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_65.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_70.png b/core/res/res/drawable-mdpi/stat_sys_battery_70.png
new file mode 100644
index 0000000..0d22fbc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_70.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_75.png b/core/res/res/drawable-mdpi/stat_sys_battery_75.png
new file mode 100644
index 0000000..409127b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_75.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_80.png b/core/res/res/drawable-mdpi/stat_sys_battery_80.png
index f38af5d..9bb5a4d 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_80.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_80.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_85.png b/core/res/res/drawable-mdpi/stat_sys_battery_85.png
new file mode 100644
index 0000000..5d832cf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_90.png b/core/res/res/drawable-mdpi/stat_sys_battery_90.png
new file mode 100644
index 0000000..5245336
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_90.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_95.png b/core/res/res/drawable-mdpi/stat_sys_battery_95.png
new file mode 100644
index 0000000..2e72e4e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_95.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
index 9f3da11..59ee091 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png
index 8f8c81e..5d9bd74 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png
index 12fd03f..5f0e9bc 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png
index 641896c..c0fd42c 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png
index 6bd19b5..6d39d70 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png
index f9353c0..e5e3ac5 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
index 506cb45..8c31cd1 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_battery.xml b/core/res/res/drawable/stat_sys_battery.xml
index 968595d..8261243 100644
--- a/core/res/res/drawable/stat_sys_battery.xml
+++ b/core/res/res/drawable/stat_sys_battery.xml
@@ -19,12 +19,26 @@
 -->
 
 <level-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:maxLevel="4" android:drawable="@android:drawable/stat_sys_battery_0" />
-    <item android:maxLevel="14" android:drawable="@android:drawable/stat_sys_battery_10" />
-    <item android:maxLevel="29" android:drawable="@android:drawable/stat_sys_battery_20" />
-    <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_40" />
-    <item android:maxLevel="69" android:drawable="@android:drawable/stat_sys_battery_60" />
-    <item android:maxLevel="89" android:drawable="@android:drawable/stat_sys_battery_80" />
+    <item android:maxLevel="2" android:drawable="@android:drawable/stat_sys_battery_0" />
+    <item android:maxLevel="7" android:drawable="@android:drawable/stat_sys_battery_5" />
+    <item android:maxLevel="12" android:drawable="@android:drawable/stat_sys_battery_10" />
+    <item android:maxLevel="17" android:drawable="@android:drawable/stat_sys_battery_15" />
+    <item android:maxLevel="22" android:drawable="@android:drawable/stat_sys_battery_20" />
+    <item android:maxLevel="27" android:drawable="@android:drawable/stat_sys_battery_25" />
+    <item android:maxLevel="32" android:drawable="@android:drawable/stat_sys_battery_30" />
+    <item android:maxLevel="37" android:drawable="@android:drawable/stat_sys_battery_35" />
+    <item android:maxLevel="42" android:drawable="@android:drawable/stat_sys_battery_40" />
+    <item android:maxLevel="47" android:drawable="@android:drawable/stat_sys_battery_45" />
+    <item android:maxLevel="52" android:drawable="@android:drawable/stat_sys_battery_50" />
+    <item android:maxLevel="57" android:drawable="@android:drawable/stat_sys_battery_55" />
+    <item android:maxLevel="62" android:drawable="@android:drawable/stat_sys_battery_60" />
+    <item android:maxLevel="67" android:drawable="@android:drawable/stat_sys_battery_65" />
+    <item android:maxLevel="72" android:drawable="@android:drawable/stat_sys_battery_70" />
+    <item android:maxLevel="77" android:drawable="@android:drawable/stat_sys_battery_75" />
+    <item android:maxLevel="82" android:drawable="@android:drawable/stat_sys_battery_80" />
+    <item android:maxLevel="87" android:drawable="@android:drawable/stat_sys_battery_85" />
+    <item android:maxLevel="92" android:drawable="@android:drawable/stat_sys_battery_90" />
+    <item android:maxLevel="97" android:drawable="@android:drawable/stat_sys_battery_95" />
     <item android:maxLevel="100" android:drawable="@android:drawable/stat_sys_battery_100" />
 </level-list>
 
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index 7efc6d7..743fbb2 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -359,6 +359,9 @@
     }
     if (listener != NULL) {
         listener->postDataTimestamp(timestamp, msgType, dataPtr);
+    } else {
+        LOGW("No listener was set. Drop a recording frame.");
+        releaseRecordingFrame(dataPtr);
     }
 }
 
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index ab260d5..29a5a96 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -40,6 +40,8 @@
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
 
+#include <ui/egl/android_natives.h>
+
 #include "hooks.h"
 #include "egl_impl.h"
 #include "Loader.h"
@@ -196,15 +198,16 @@
 {
     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
 
-    egl_surface_t(EGLDisplay dpy, EGLSurface surface, EGLConfig config,
-            int impl, egl_connection_t const* cnx) 
-    : dpy(dpy), surface(surface), config(config), impl(impl), cnx(cnx) {
+    egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
+            EGLSurface surface, int impl, egl_connection_t const* cnx)
+    : dpy(dpy), surface(surface), config(config), win(win), impl(impl), cnx(cnx) {
     }
     ~egl_surface_t() {
     }
     EGLDisplay                  dpy;
     EGLSurface                  surface;
     EGLConfig                   config;
+    sp<ANativeWindow>           win;
     int                         impl;
     egl_connection_t const*     cnx;
 };
@@ -984,11 +987,22 @@
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
+        EGLDisplay iDpy = dp->disp[ dp->configs[intptr_t(config)].impl ].dpy;
+        EGLConfig iConfig = dp->configs[intptr_t(config)].config;
+        EGLint format;
+
+        // set the native window's buffers format to match this config
+        if (cnx->egl.eglGetConfigAttrib(iDpy,
+                iConfig, EGL_NATIVE_VISUAL_ID, &format)) {
+            if (format != 0) {
+                native_window_set_buffers_geometry(window, 0, 0, format);
+            }
+        }
+
         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
-                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
-                dp->configs[intptr_t(config)].config, window, attrib_list);
+                iDpy, iConfig, window, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+            egl_surface_t* s = new egl_surface_t(dpy, config, window, surface,
                     dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
@@ -1007,7 +1021,7 @@
                 dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
                 dp->configs[intptr_t(config)].config, pixmap, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface,
                     dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
@@ -1025,7 +1039,7 @@
                 dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
                 dp->configs[intptr_t(config)].config, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface,
                     dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
@@ -1046,6 +1060,9 @@
     EGLBoolean result = s->cnx->egl.eglDestroySurface(
             dp->disp[s->impl].dpy, s->surface);
     if (result == EGL_TRUE) {
+        if (s->win != NULL) {
+            native_window_set_buffers_geometry(s->win.get(), 0, 0, 0);
+        }
         _s.terminate();
     }
     return result;
diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
index 5cf25313..a92ac1c 100755
--- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java
+++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java
@@ -383,7 +383,9 @@
         Connection dial(String originalNumber) throws SipException {
             String calleeSipUri = originalNumber;
             if (!calleeSipUri.contains("@")) {
-                calleeSipUri += "@" + getSipDomain(mProfile);
+                calleeSipUri = mProfile.getUriString().replaceFirst(
+                        mProfile.getUserName() + "@",
+                        calleeSipUri + "@");
             }
             try {
                 SipProfile callee =
diff --git a/voip/java/android/net/sip/SipProfile.java b/voip/java/android/net/sip/SipProfile.java
index 6977e30..4029ed0 100644
--- a/voip/java/android/net/sip/SipProfile.java
+++ b/voip/java/android/net/sip/SipProfile.java
@@ -20,6 +20,7 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 
+import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.text.ParseException;
 import javax.sip.InvalidArgumentException;
@@ -40,12 +41,15 @@
 public class SipProfile implements Parcelable, Serializable, Cloneable {
     private static final long serialVersionUID = 1L;
     private static final int DEFAULT_PORT = 5060;
+    private static final String TCP = "TCP";
+    private static final String UDP = "UDP";
     private Address mAddress;
     private String mProxyAddress;
     private String mPassword;
     private String mDomain;
-    private String mProtocol = ListeningPoint.UDP;
+    private String mProtocol = UDP;
     private String mProfileName;
+    private int mPort = DEFAULT_PORT;
     private boolean mSendKeepAlive = false;
     private boolean mAutoRegistration = true;
     private transient int mCallingUid = 0;
@@ -95,6 +99,7 @@
             mUri.setUserPassword(profile.getPassword());
             mDisplayName = profile.getDisplayName();
             mProxyAddress = profile.getProxyAddress();
+            mProfile.mPort = profile.getPort();
         }
 
         /**
@@ -171,12 +176,11 @@
          * @throws IllegalArgumentException if the port number is out of range
          */
         public Builder setPort(int port) throws IllegalArgumentException {
-            try {
-                mUri.setPort(port);
-                return this;
-            } catch (InvalidArgumentException e) {
-                throw new IllegalArgumentException(e);
+            if ((port > 65535) || (port < 1000)) {
+                throw new IllegalArgumentException("incorrect port arugment");
             }
+            mProfile.mPort = port;
+            return this;
         }
 
         /**
@@ -193,7 +197,7 @@
                 throw new NullPointerException("protocol cannot be null");
             }
             protocol = protocol.toUpperCase();
-            if (!protocol.equals("UDP") && !protocol.equals("TCP")) {
+            if (!protocol.equals(UDP) && !protocol.equals(TCP)) {
                 throw new IllegalArgumentException(
                         "unsupported protocol: " + protocol);
             }
@@ -258,13 +262,22 @@
             mProfile.mPassword = mUri.getUserPassword();
             mUri.setUserPassword(null);
             try {
-                mProfile.mAddress = mAddressFactory.createAddress(
-                        mDisplayName, mUri);
                 if (!TextUtils.isEmpty(mProxyAddress)) {
                     SipURI uri = (SipURI)
                             mAddressFactory.createURI(fix(mProxyAddress));
                     mProfile.mProxyAddress = uri.getHost();
+                } else {
+                    if (!mProfile.mProtocol.equals(UDP)) {
+                        mUri.setTransportParam(mProfile.mProtocol);
+                    }
+                    if (mProfile.mPort != DEFAULT_PORT) {
+                        mUri.setPort(mProfile.mPort);
+                    }
                 }
+                mProfile.mAddress = mAddressFactory.createAddress(
+                        mDisplayName, mUri);
+            } catch (InvalidArgumentException e) {
+                throw new RuntimeException(e);
             } catch (ParseException e) {
                 // must not occur
                 throw new RuntimeException(e);
@@ -286,6 +299,7 @@
         mSendKeepAlive = (in.readInt() == 0) ? false : true;
         mAutoRegistration = (in.readInt() == 0) ? false : true;
         mCallingUid = in.readInt();
+        mPort = in.readInt();
     }
 
     @Override
@@ -299,6 +313,7 @@
         out.writeInt(mSendKeepAlive ? 1 : 0);
         out.writeInt(mAutoRegistration ? 1 : 0);
         out.writeInt(mCallingUid);
+        out.writeInt(mPort);
     }
 
     @Override
@@ -322,7 +337,13 @@
      * @return the SIP URI string of this profile
      */
     public String getUriString() {
-        return mAddress.getURI().toString();
+        // We need to return the sip uri domain instead of
+        // the SIP URI with transport, port information if
+        // the outbound proxy address exists.
+        if (!TextUtils.isEmpty(mProxyAddress)) {
+            return "sip:" + getUserName() + "@" + mDomain;
+        }
+        return getUri().toString();
     }
 
     /**
@@ -377,8 +398,7 @@
      * @return the port number of the SIP server
      */
     public int getPort() {
-        int port = getUri().getPort();
-        return (port == -1) ? DEFAULT_PORT : port;
+        return mPort;
     }
 
     /**
@@ -441,4 +461,10 @@
     public int getCallingUid() {
         return mCallingUid;
     }
+
+    private Object readResolve() throws ObjectStreamException {
+        // For compatibility.
+        if (mPort == 0) mPort = DEFAULT_PORT;
+        return this;
+    }
 }
diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java
index 13e6f14..518543a 100644
--- a/voip/java/com/android/server/sip/SipHelper.java
+++ b/voip/java/com/android/server/sip/SipHelper.java
@@ -215,8 +215,9 @@
             String tag) throws ParseException, SipException {
         FromHeader fromHeader = createFromHeader(userProfile, tag);
         ToHeader toHeader = createToHeader(userProfile);
-        SipURI requestURI = mAddressFactory.createSipURI("sip:"
-                + userProfile.getSipDomain());
+        SipURI requestURI = mAddressFactory.createSipURI(
+                userProfile.getUriString().replaceFirst(
+                userProfile.getUserName() + "@", ""));
         List<ViaHeader> viaHeaders = createViaHeaders();
         CallIdHeader callIdHeader = createCallIdHeader();
         CSeqHeader cSeqHeader = createCSeqHeader(requestType);
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 5540174..27e6a72 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -933,10 +933,8 @@
                     resetConnections(true);
                 }
                 // When supplicant dies, kill the DHCP thread
-                if (mDhcpTarget != null) {
-                    mDhcpTarget.getLooper().quit();
-                    mDhcpTarget = null;
-                }
+                mDhcpTarget.getLooper().quit();
+
                 mContext.removeStickyBroadcast(new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION));
                 if (ActivityManagerNative.isSystemReady()) {
                     intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
@@ -1407,10 +1405,9 @@
         NetworkUtils.resetConnections(mInterfaceName);
 
         // Stop DHCP
-        if (mDhcpTarget != null) {
-            mDhcpTarget.setCancelCallback(true);
-            mDhcpTarget.removeMessages(EVENT_DHCP_START);
-        }
+        mDhcpTarget.setCancelCallback(true);
+        mDhcpTarget.removeMessages(EVENT_DHCP_START);
+
         if (!NetworkUtils.stopDhcp(mInterfaceName)) {
             Log.e(TAG, "Could not stop DHCP");
         }