Merge "Do not merge: Add some input checking to prevent problems" into honeycomb-LTE
diff --git a/Android.mk b/Android.mk
index a28bde2..de0112c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -123,10 +123,10 @@
core/java/android/nfc/ILlcpServiceSocket.aidl \
core/java/android/nfc/ILlcpSocket.aidl \
core/java/android/nfc/INfcAdapter.aidl \
+ core/java/android/nfc/INfcAdapterExtras.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 \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2eee813..023ce59 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -95,7 +95,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/PerfTest_intermediates/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/RSTest_intermediates/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/hardware/IUsbManager.java)
-
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index d439a48..870127c 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -28,7 +28,7 @@
import android.nfc.INfcTag;
import android.nfc.IP2pTarget;
import android.nfc.IP2pInitiator;
-import android.nfc.INfcSecureElement;
+import android.nfc.INfcAdapterExtras;
/**
* @hide
@@ -41,13 +41,12 @@
INfcTag getNfcTagInterface();
IP2pTarget getP2pTargetInterface();
IP2pInitiator getP2pInitiatorInterface();
- INfcSecureElement getNfcSecureElementInterface();
+ INfcAdapterExtras getNfcAdapterExtrasInterface();
// NfcAdapter-class related methods
boolean isEnabled();
NdefMessage localGet();
void localSet(in NdefMessage message);
- void openTagConnection(in Tag tag);
void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
in IntentFilter[] filters, in TechListParcel techLists);
void disableForegroundDispatch(in ComponentName activity);
@@ -59,12 +58,8 @@
int createLlcpConnectionlessSocket(int sap);
int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
- int deselectSecureElement();
boolean disable();
boolean enable();
String getProperties(String param);
- int[] getSecureElementList();
- int getSelectedSecureElement();
- int selectSecureElement(int seId);
int setProperties(String param, String value);
-}
\ No newline at end of file
+}
diff --git a/core/java/android/nfc/INfcSecureElement.aidl b/core/java/android/nfc/INfcAdapterExtras.aidl
similarity index 63%
rename from core/java/android/nfc/INfcSecureElement.aidl
rename to core/java/android/nfc/INfcAdapterExtras.aidl
index aa98dd2..ab5c1a6 100755
--- a/core/java/android/nfc/INfcSecureElement.aidl
+++ b/core/java/android/nfc/INfcAdapterExtras.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,15 @@
package android.nfc;
+import android.os.Bundle;
+
/**
* {@hide}
*/
-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
+interface INfcAdapterExtras {
+ Bundle open(IBinder b);
+ Bundle close();
+ Bundle transceive(in byte[] data_in);
+ int getCardEmulationRoute();
+ void setCardEmulationRoute(int route);
+}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 8c56fda..4689804 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -157,31 +157,6 @@
public static final String EXTRA_ID = "android.nfc.extra.ID";
/**
- * Broadcast Action: a transaction with a secure element has been detected.
- * <p>
- * Always contains the extra field
- * {@link android.nfc.NfcAdapter#EXTRA_AID}
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TRANSACTION_DETECTED =
- "android.nfc.action.TRANSACTION_DETECTED";
-
- /**
- * Broadcast Action: an RF field ON has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_ON_DETECTED =
- "android.nfc.action.RF_FIELD_ON_DETECTED";
-
- /**
- * Broadcast Action: an RF Field OFF has been detected.
- * @hide
- */
- public static final String ACTION_RF_FIELD_OFF_DETECTED =
- "android.nfc.action.RF_FIELD_OFF_DETECTED";
-
- /**
* Broadcast Action: an adapter's state changed between enabled and disabled.
*
* The new value is stored in the extra EXTRA_NEW_BOOLEAN_STATE and just contains
@@ -201,15 +176,6 @@
public static final String EXTRA_NEW_BOOLEAN_STATE = "android.nfc.isEnabled";
/**
- * Mandatory byte array extra field in
- * {@link android.nfc.NfcAdapter#ACTION_TRANSACTION_DETECTED}.
- * <p>
- * Contains the AID of the applet involved in the transaction.
- * @hide
- */
- public static final String EXTRA_AID = "android.nfc.extra.AID";
-
- /**
* LLCP link status: The LLCP link is activated.
* @hide
*/
@@ -691,39 +657,14 @@
}
/**
- * Create an Nfc Secure Element Connection
* @hide
*/
- public NfcSecureElement createNfcSecureElementConnection() {
+ public INfcAdapterExtras getNfcAdapterExtrasInterface() {
try {
- return new NfcSecureElement(sService.getNfcSecureElementInterface());
+ return sService.getNfcAdapterExtrasInterface();
} catch (RemoteException e) {
- Log.e(TAG, "createNfcSecureElementConnection failed", e);
+ attemptDeadServiceRecovery(e);
return null;
}
}
-
- /**
- * To change the Secure Element Card Emulation state (ON/OFF)
- * @hide
- */
- public void changeNfcSecureElementCardEmulationState(boolean state)
- {
- int seId = 11259375;
- if(state){
- /* Enable card emulation */
- try {
- sService.selectSecureElement(seId);
- } catch (RemoteException e) {
- Log.e(TAG, "Enable card emulation failed", e);
- }
- }else{
- /* Disable card emulation */
- try {
- sService.deselectSecureElement();
- } catch (RemoteException e) {
- Log.e(TAG, " card emulation failed", e);
- }
- }
- }
}
diff --git a/core/java/android/nfc/NfcSecureElement.java b/core/java/android/nfc/NfcSecureElement.java
deleted file mode 100755
index 3b5f39e..0000000
--- a/core/java/android/nfc/NfcSecureElement.java
+++ /dev/null
@@ -1,138 +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.nfc.tech.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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c684e7e..0c9a2ef 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -91,10 +91,15 @@
<protected-broadcast android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
<protected-broadcast android:name="android.nfc.action.LLCP_LINK_STATE_CHANGED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_ON_DETECTED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED" />
+ <protected-broadcast android:name="com.android.nfc_extras.action.AID_SELECTED" />
+
<protected-broadcast android:name="android.nfc.action.TRANSACTION_DETECTED" />
<protected-broadcast android:name="android.intent.action.CLEAR_DNS_CACHE" />
<protected-broadcast android:name="android.intent.action.PROXY_CHANGE" />
+
<!-- ====================================== -->
<!-- Permissions for things that cost money -->
<!-- ====================================== -->
diff --git a/core/res/res/drawable-hdpi/ic_paste_bubble_holo_disabled.png b/core/res/res/drawable-hdpi/ic_paste_bubble_holo_disabled.png
new file mode 100644
index 0000000..15bd8b2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_paste_bubble_holo_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_paste_bubble_holo_disabled.png b/core/res/res/drawable-mdpi/ic_paste_bubble_holo_disabled.png
new file mode 100644
index 0000000..e483e84
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_paste_bubble_holo_disabled.png
Binary files differ
diff --git a/core/res/res/layout/text_edit_no_paste_window.xml b/core/res/res/layout/text_edit_no_paste_window.xml
index fa50275..f804986 100644
--- a/core/res/res/layout/text_edit_no_paste_window.xml
+++ b/core/res/res/layout/text_edit_no_paste_window.xml
@@ -25,7 +25,7 @@
android:paddingRight="16dip"
android:paddingTop="8dip"
android:paddingBottom="8dip"
- android:drawableLeft="@android:drawable/ic_menu_paste_dark"
+ android:drawableLeft="@android:drawable/ic_paste_bubble_holo_disabled"
android:drawablePadding="8dip"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
diff --git a/core/res/res/layout/text_edit_side_no_paste_window.xml b/core/res/res/layout/text_edit_side_no_paste_window.xml
index 0ed3849..903bcb6 100644
--- a/core/res/res/layout/text_edit_side_no_paste_window.xml
+++ b/core/res/res/layout/text_edit_side_no_paste_window.xml
@@ -25,7 +25,7 @@
android:paddingRight="16dip"
android:paddingTop="8dip"
android:paddingBottom="8dip"
- android:drawableLeft="@android:drawable/ic_menu_paste_dark"
+ android:drawableLeft="@android:drawable/ic_paste_bubble_holo_disabled"
android:drawablePadding="8dip"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index fd12e19..9d0cba3 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -110,6 +110,8 @@
private static final int MSG_PLAY_SOUND_EFFECT = 7;
private static final int MSG_BTA2DP_DOCK_TIMEOUT = 8;
private static final int MSG_LOAD_SOUND_EFFECTS = 9;
+ private static final int MSG_SET_FORCE_USE = 10;
+
private static final int BTA2DP_DOCK_TIMEOUT_MILLIS = 8000;
@@ -1170,22 +1172,15 @@
if (!checkAudioSettingsPermission("setSpeakerphoneOn()")) {
return;
}
- if (on) {
- AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_SPEAKER);
- mForcedUseForComm = AudioSystem.FORCE_SPEAKER;
- } else {
- AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE);
- mForcedUseForComm = AudioSystem.FORCE_NONE;
- }
+ mForcedUseForComm = on ? AudioSystem.FORCE_SPEAKER : AudioSystem.FORCE_NONE;
+
+ sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SHARED_MSG, SENDMSG_QUEUE,
+ AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
}
/** @see AudioManager#isSpeakerphoneOn() */
public boolean isSpeakerphoneOn() {
- if (mForcedUseForComm == AudioSystem.FORCE_SPEAKER) {
- return true;
- } else {
- return false;
- }
+ return (mForcedUseForComm == AudioSystem.FORCE_SPEAKER);
}
/** @see AudioManager#setBluetoothScoOn() */
@@ -1193,24 +1188,17 @@
if (!checkAudioSettingsPermission("setBluetoothScoOn()")) {
return;
}
- if (on) {
- AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_BT_SCO);
- AudioSystem.setForceUse(AudioSystem.FOR_RECORD, AudioSystem.FORCE_BT_SCO);
- mForcedUseForComm = AudioSystem.FORCE_BT_SCO;
- } else {
- AudioSystem.setForceUse(AudioSystem.FOR_COMMUNICATION, AudioSystem.FORCE_NONE);
- AudioSystem.setForceUse(AudioSystem.FOR_RECORD, AudioSystem.FORCE_NONE);
- mForcedUseForComm = AudioSystem.FORCE_NONE;
- }
+ mForcedUseForComm = on ? AudioSystem.FORCE_BT_SCO : AudioSystem.FORCE_NONE;
+
+ sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SHARED_MSG, SENDMSG_QUEUE,
+ AudioSystem.FOR_COMMUNICATION, mForcedUseForComm, null, 0);
+ sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SHARED_MSG, SENDMSG_QUEUE,
+ AudioSystem.FOR_RECORD, mForcedUseForComm, null, 0);
}
/** @see AudioManager#isBluetoothScoOn() */
public boolean isBluetoothScoOn() {
- if (mForcedUseForComm == AudioSystem.FORCE_BT_SCO) {
- return true;
- } else {
- return false;
- }
+ return (mForcedUseForComm == AudioSystem.FORCE_BT_SCO);
}
/** @see AudioManager#startBluetoothSco() */
@@ -1935,6 +1923,10 @@
}
}
+ private void setForceUse(int usage, int config) {
+ AudioSystem.setForceUse(usage, config);
+ }
+
@Override
public void handleMessage(Message msg) {
int baseMsgWhat = getMsgBase(msg.what);
@@ -2026,6 +2018,10 @@
// msg.obj == address of BTA2DP device
makeA2dpDeviceUnavailableNow( (String) msg.obj );
break;
+
+ case MSG_SET_FORCE_USE:
+ setForceUse(msg.arg1, msg.arg2);
+ break;
}
}
}
diff --git a/nfc-extras/Android.mk b/nfc-extras/Android.mk
new file mode 100644
index 0000000..2033508
--- /dev/null
+++ b/nfc-extras/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE:= com.android.nfc_extras
+
+include $(BUILD_JAVA_LIBRARY)
+
+# put the com.android.nfc_extras.jar into the dist directory
+$(call dist-for-goals, droidcore, $(LOCAL_BUILT_MODULE):com.android.nfc_extras.jar)
diff --git a/nfc-extras/com.android.nfc_extras.xml b/nfc-extras/com.android.nfc_extras.xml
new file mode 100644
index 0000000..370145d
--- /dev/null
+++ b/nfc-extras/com.android.nfc_extras.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<permissions>
+ <library name="com.android.nfc_extras"
+ file="/system/framework/com.android.nfc_extras.jar" />
+</permissions>
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
new file mode 100644
index 0000000..cf38bd1
--- /dev/null
+++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.nfc_extras;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.nfc.INfcAdapterExtras;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Provides additional methods on an {@link NfcAdapter} for Card Emulation
+ * and management of {@link NfcExecutionEnvironment}'s.
+ *
+ * There is a 1-1 relationship between an {@link NfcAdapterExtras} object and
+ * a {@link NfcAdapter} object.
+ */
+public final class NfcAdapterExtras {
+ private static final String TAG = "NfcAdapterExtras";
+
+ /**
+ * Broadcast Action: an RF field ON has been detected.
+ *
+ * <p class="note">This is an unreliable signal, and will be removed.
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ public static final String ACTION_RF_FIELD_ON_DETECTED =
+ "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED";
+
+ /**
+ * Broadcast Action: an RF field OFF has been detected.
+ *
+ * <p class="note">This is an unreliable signal, and will be removed.
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ public static final String ACTION_RF_FIELD_OFF_DETECTED =
+ "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED";
+
+ // protected by NfcAdapterExtras.class, and final after first construction
+ private static INfcAdapterExtras sService;
+ private static boolean sIsInitialized = false;
+ private static NfcAdapterExtras sSingleton;
+ private static NfcExecutionEnvironment sEmbeddedEe;
+ private static CardEmulationRoute sRouteOff;
+ private static CardEmulationRoute sRouteOnWhenScreenOn;
+
+ /**
+ * Get the {@link NfcAdapterExtras} for the given {@link NfcAdapter}.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @param adapter a {@link NfcAdapter}, must not be null
+ * @return the {@link NfcAdapterExtras} object for the given {@link NfcAdapter}
+ */
+ public static NfcAdapterExtras get(NfcAdapter adapter) {
+ synchronized(NfcAdapterExtras.class) {
+ if (!sIsInitialized) {
+ sIsInitialized = true;
+ sService = adapter.getNfcAdapterExtrasInterface();
+ sEmbeddedEe = new NfcExecutionEnvironment(sService);
+ sRouteOff = new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
+ sRouteOnWhenScreenOn = new CardEmulationRoute(
+ CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, sEmbeddedEe);
+ sSingleton = new NfcAdapterExtras();
+ }
+ return sSingleton;
+ }
+ }
+
+ private NfcAdapterExtras() {}
+
+ /**
+ * Immutable data class that describes a card emulation route.
+ */
+ public final static class CardEmulationRoute {
+ /**
+ * Card Emulation is turned off on this NfcAdapter.
+ * <p>This is the default routing state after boot.
+ */
+ public static final int ROUTE_OFF = 1;
+
+ /**
+ * Card Emulation is routed to {@link #nfcEe} only when the screen is on,
+ * otherwise it is turned off.
+ */
+ public static final int ROUTE_ON_WHEN_SCREEN_ON = 2;
+
+ /**
+ * A route such as {@link #ROUTE_OFF} or {@link #ROUTE_ON_WHEN_SCREEN_ON}.
+ */
+ public final int route;
+
+ /**
+ * The {@link NFcExecutionEnvironment} that is Card Emulation is routed to.
+ * <p>null if {@link #route} is {@link #ROUTE_OFF}, otherwise not null.
+ */
+ public final NfcExecutionEnvironment nfcEe;
+
+ public CardEmulationRoute(int route, NfcExecutionEnvironment nfcEe) {
+ if (route == ROUTE_OFF && nfcEe != null) {
+ throw new IllegalArgumentException("must not specifiy a NFC-EE with ROUTE_OFF");
+ } else if (route != ROUTE_OFF && nfcEe == null) {
+ throw new IllegalArgumentException("must specifiy a NFC-EE for this route");
+ }
+ this.route = route;
+ this.nfcEe = nfcEe;
+ }
+ }
+
+ /**
+ * Get the routing state of this NFC EE.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @return
+ */
+ public CardEmulationRoute getCardEmulationRoute() {
+ try {
+ int route = sService.getCardEmulationRoute();
+ return route == CardEmulationRoute.ROUTE_OFF ?
+ sRouteOff :
+ sRouteOnWhenScreenOn;
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ return sRouteOff;
+ }
+ }
+
+ /**
+ * Set the routing state of this NFC EE.
+ *
+ * <p>This routing state is not persisted across reboot.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @param route a {@link #CardEmulationRoute}
+ */
+ public void setCardEmulationRoute(CardEmulationRoute route) {
+ try {
+ sService.setCardEmulationRoute(route.route);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ }
+
+ /**
+ * Get the {@link NfcExecutionEnvironment} that is embedded with the
+ * {@link NFcAdapter}.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @return a {@link NfcExecutionEnvironment}, or null if there is no embedded NFC-EE
+ */
+ public NfcExecutionEnvironment getEmbeddedExecutionEnvironment() {
+ return sEmbeddedEe;
+ }
+}
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
new file mode 100644
index 0000000..3efe492
--- /dev/null
+++ b/nfc-extras/java/com/android/nfc_extras/NfcExecutionEnvironment.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.nfc_extras;
+
+import java.io.IOException;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+import android.nfc.INfcAdapterExtras;
+import android.nfc.NfcAdapter;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+public class NfcExecutionEnvironment {
+ private final INfcAdapterExtras mService;
+
+ /**
+ * Broadcast Action: An ISO-DEP AID was selected.
+ *
+ * <p>This happens as the result of a 'SELECT AID' command from an
+ * external NFC reader/writer.
+ *
+ * <p>Always contains the extra field {@link #EXTRA_AID}
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission
+ * to receive.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_AID_SELECTED =
+ "com.android.nfc_extras.action.AID_SELECTED";
+
+ /**
+ * Mandatory byte array extra field in {@link #ACTION_AID_SELECTED}.
+ *
+ * <p>Contains the AID selected.
+ * @hide
+ */
+ public static final String EXTRA_AID = "com.android.nfc_extras.extra.AID";
+
+ NfcExecutionEnvironment(INfcAdapterExtras service) {
+ mService = service;
+ }
+
+ /**
+ * Open the NFC Execution Environment on its contact interface.
+ *
+ * <p>Only one process may open the secure element at a time. If it is
+ * already open, an {@link IOException} is thrown.
+ *
+ * <p>All other NFC functionality is disabled while the NFC-EE is open
+ * on its contact interface, so make sure to call {@link #close} once complete.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is already open, or some other error occurs
+ */
+ public void open() throws IOException {
+ try {
+ Bundle b = mService.open(new Binder());
+ throwBundle(b);
+ } catch (RemoteException e) {
+ return;
+ }
+ }
+
+ /**
+ * Close the NFC Execution Environment on its contact interface.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is already open, or some other error occurs
+ */
+ public void close() throws IOException {
+ try {
+ throwBundle(mService.close());
+ } catch (RemoteException e) {
+ return;
+ }
+ }
+
+ /**
+ * Send raw commands to the NFC-EE and receive the response.
+ *
+ * <p class="note">
+ * Requires the {@link android.Manifest.permission#WRITE_SECURE_SETTINGS} permission.
+ *
+ * @throws IOException if the NFC-EE is not open, or some other error occurs
+ */
+ public byte[] transceive(byte[] in) throws IOException {
+ Bundle b;
+ try {
+ b = mService.transceive(in);
+ } catch (RemoteException e) {
+ throw new IOException(e.getMessage());
+ }
+ throwBundle(b);
+ return b.getByteArray("out");
+ }
+
+ private static void throwBundle(Bundle b) throws IOException {
+ if (b.getInt("e") == -1) {
+ throw new IOException(b.getString("m"));
+ }
+ }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index fa63edb..744798e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -27,6 +27,7 @@
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
+import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
@@ -58,15 +59,20 @@
private static final String KEY_SECURE = "secure";
private static final String KEY_LOCALE = "locale";
+ //Version 2 adds STATE_WIFI_CONFIG
+ private static final int STATE_VERSION_1 = 1;
+ private static final int STATE_VERSION_1_SIZE = 4;
+
// Versioning of the state file. Increment this version
// number any time the set of state items is altered.
- private static final int STATE_VERSION = 1;
+ private static final int STATE_VERSION = 2;
- private static final int STATE_SYSTEM = 0;
- private static final int STATE_SECURE = 1;
- private static final int STATE_LOCALE = 2;
- private static final int STATE_WIFI = 3;
- private static final int STATE_SIZE = 4; // The number of state items
+ private static final int STATE_SYSTEM = 0;
+ private static final int STATE_SECURE = 1;
+ private static final int STATE_LOCALE = 2;
+ private static final int STATE_WIFI_SUPPLICANT = 3;
+ private static final int STATE_WIFI_CONFIG = 4;
+ private static final int STATE_SIZE = 5; // The number of state items
private static String[] sortedSystemKeys = null;
private static String[] sortedSecureKeys = null;
@@ -91,12 +97,18 @@
// the key to store the WIFI data under, should be sorted as last, so restore happens last.
// use very late unicode character to quasi-guarantee last sort position.
private static final String KEY_WIFI_SUPPLICANT = "\uffedWIFI";
+ private static final String KEY_WIFI_CONFIG = "\uffedCONFIG_WIFI";
private SettingsHelper mSettingsHelper;
+ private WifiManager mWfm;
+ private static String mWifiConfigFile;
public void onCreate() {
mSettingsHelper = new SettingsHelper(this);
super.onCreate();
+
+ WifiManager mWfm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ if (mWfm != null) mWifiConfigFile = mWfm.getConfigFile();
}
@Override
@@ -106,7 +118,8 @@
byte[] systemSettingsData = getSystemSettings();
byte[] secureSettingsData = getSecureSettings();
byte[] locale = mSettingsHelper.getLocaleData();
- byte[] wifiData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
+ byte[] wifiSupplicantData = getWifiSupplicant(FILE_WIFI_SUPPLICANT);
+ byte[] wifiConfigData = getFileData(mWifiConfigFile);
long[] stateChecksums = readOldChecksums(oldState);
@@ -116,8 +129,12 @@
writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
stateChecksums[STATE_LOCALE] =
writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
- stateChecksums[STATE_WIFI] =
- writeIfChanged(stateChecksums[STATE_WIFI], KEY_WIFI_SUPPLICANT, wifiData, data);
+ stateChecksums[STATE_WIFI_SUPPLICANT] =
+ writeIfChanged(stateChecksums[STATE_WIFI_SUPPLICANT], KEY_WIFI_SUPPLICANT,
+ wifiSupplicantData, data);
+ stateChecksums[STATE_WIFI_CONFIG] =
+ writeIfChanged(stateChecksums[STATE_WIFI_CONFIG], KEY_WIFI_CONFIG, wifiConfigData,
+ data);
writeNewChecksums(stateChecksums, newState);
}
@@ -148,7 +165,9 @@
byte[] localeData = new byte[size];
data.readEntityData(localeData, 0, size);
mSettingsHelper.setLocaleData(localeData);
- } else {
+ } else if (KEY_WIFI_CONFIG.equals(key)) {
+ restoreFileData(mWifiConfigFile, data);
+ } else {
data.skipEntityData();
}
}
@@ -162,7 +181,11 @@
try {
int stateVersion = dataInput.readInt();
- if (stateVersion == STATE_VERSION) {
+ if (stateVersion == STATE_VERSION_1) {
+ for (int i = 0; i < STATE_VERSION_1_SIZE; i++) {
+ stateChecksums[i] = dataInput.readLong();
+ }
+ } else if (stateVersion == STATE_VERSION) {
for (int i = 0; i < STATE_SIZE; i++) {
stateChecksums[i] = dataInput.readLong();
}
@@ -353,6 +376,60 @@
return result;
}
+ private byte[] getFileData(String filename) {
+ InputStream is = null;
+ try {
+ File file = new File(filename);
+ is = new FileInputStream(file);
+
+ //Will truncate read on a very long file,
+ //should not happen for a config file
+ byte[] bytes = new byte[(int)file.length()];
+
+ int offset = 0;
+ int numRead = 0;
+ while (offset < bytes.length
+ && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
+ offset += numRead;
+ }
+
+ //read failure
+ if (offset < bytes.length) {
+ Log.w(TAG, "Couldn't backup " + filename);
+ return EMPTY_DATA;
+ }
+ return bytes;
+ } catch (IOException ioe) {
+ Log.w(TAG, "Couldn't backup " + filename);
+ return EMPTY_DATA;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ }
+
+ private void restoreFileData(String filename, BackupDataInput data) {
+ byte[] bytes = new byte[data.getDataSize()];
+ if (bytes.length <= 0) return;
+ try {
+ data.readEntityData(bytes, 0, bytes.length);
+ File file = new File(filename);
+ if (file.exists()) file.delete();
+
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(filename, true));
+ os.write(bytes);
+ os.close();
+ } catch (IOException ioe) {
+ Log.w(TAG, "Couldn't restore " + filename);
+ }
+ }
+
+
private byte[] getWifiSupplicant(String filename) {
BufferedReader br = null;
try {
@@ -455,10 +532,9 @@
}
private int enableWifi(boolean enable) {
- WifiManager wfm = (WifiManager) getSystemService(Context.WIFI_SERVICE);
- if (wfm != null) {
- int state = wfm.getWifiState();
- wfm.setWifiEnabled(enable);
+ if (mWfm != null) {
+ int state = mWfm.getWifiState();
+ mWfm.setWifiEnabled(enable);
return state;
}
return WifiManager.WIFI_STATE_UNKNOWN;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 3c6c427..0000237 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -29,12 +29,12 @@
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.wifi.IWifiManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.SupplicantState;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiStateMachine;
-import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
-import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WpsConfiguration;
import android.net.wifi.WpsResult;
@@ -882,8 +882,6 @@
mWifiStateMachine.clearBlacklist();
}
-
-
/**
* Get a reference to handler. This is used by a client to establish
* an AsyncChannel communication with WifiService
@@ -898,6 +896,14 @@
return new Messenger(mAsyncServiceHandler);
}
+ /**
+ * Get the IP and proxy configuration file
+ */
+ public String getConfigFile() {
+ enforceAccessPermission();
+ return mWifiStateMachine.getConfigFile();
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 1d115b1..16a61db 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -104,5 +104,7 @@
void clearBlacklist();
Messenger getMessenger();
+
+ String getConfigFile();
}
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index e6decc88..6455d84 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -1347,4 +1347,8 @@
}
return sb.toString();
}
+
+ public static String getConfigFile() {
+ return ipConfigFile;
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 5238899..2e49a77 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1176,6 +1176,18 @@
}
/**
+ * Returns the file in which IP and proxy configuration data is stored
+ * @hide
+ */
+ public String getConfigFile() {
+ try {
+ return mService.getConfigFile();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Allows an application to keep the Wi-Fi radio awake.
* Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
* Acquiring a WifiLock will keep the radio on until the lock is released. Multiple
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 717dcf0..4346b327 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -887,6 +887,13 @@
}
/**
+ * Returns the wifi configuration file
+ */
+ public String getConfigFile() {
+ return WifiConfigStore.getConfigFile();
+ }
+
+ /**
* Send a message indicating bluetooth adapter connection state changed
*/
public void sendBluetoothAdapterStateChange(int state) {