Merge "Remove path to the apk from the permittedPath"
diff --git a/Android.mk b/Android.mk
index f564459..a94414d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -202,6 +202,7 @@
core/java/android/nfc/INfcAdapterExtras.aidl \
core/java/android/nfc/INfcTag.aidl \
core/java/android/nfc/INfcCardEmulation.aidl \
+ core/java/android/nfc/INfcFCardEmulation.aidl \
core/java/android/nfc/INfcUnlockHandler.aidl \
core/java/android/os/IBatteryPropertiesListener.aidl \
core/java/android/os/IBatteryPropertiesRegistrar.aidl \
diff --git a/api/current.txt b/api/current.txt
index 5493666..927b588 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9336,6 +9336,7 @@
field public static final java.lang.String FEATURE_MIDI = "android.software.midi";
field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+ field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
field public static final java.lang.String FEATURE_OPENGLES_EXTENSION_PACK = "android.hardware.opengles.aep";
field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";
@@ -23866,6 +23867,28 @@
field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
}
+ public abstract class HostNfcFService extends android.app.Service {
+ ctor public HostNfcFService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onDeactivated(int);
+ method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
+ method public final void sendResponsePacket(byte[]);
+ field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
+ field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
+ field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
+ }
+
+ public final class NfcFCardEmulation {
+ method public boolean disableNfcFForegroundService(android.app.Activity);
+ method public boolean enableNfcFForegroundService(android.app.Activity, android.content.ComponentName);
+ method public static synchronized android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
+ method public java.lang.String getNfcid2ForService(android.content.ComponentName);
+ method public java.lang.String getSystemCodeForService(android.content.ComponentName);
+ method public boolean registerSystemCodeForService(android.content.ComponentName, java.lang.String);
+ method public boolean removeSystemCodeForService(android.content.ComponentName);
+ method public boolean setNfcid2ForService(android.content.ComponentName, java.lang.String);
+ }
+
public abstract class OffHostApduService extends android.app.Service {
ctor public OffHostApduService();
method public abstract android.os.IBinder onBind(android.content.Intent);
diff --git a/api/system-current.txt b/api/system-current.txt
index d6d4f5d..9ff969f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9630,6 +9630,7 @@
field public static final java.lang.String FEATURE_MIDI = "android.software.midi";
field public static final java.lang.String FEATURE_NFC = "android.hardware.nfc";
field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION = "android.hardware.nfc.hce";
+ field public static final java.lang.String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
field public static final java.lang.String FEATURE_OPENGLES_EXTENSION_PACK = "android.hardware.opengles.aep";
field public static final java.lang.String FEATURE_PRINTING = "android.software.print";
field public static final java.lang.String FEATURE_SCREEN_LANDSCAPE = "android.hardware.screen.landscape";
@@ -25811,6 +25812,28 @@
field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_apdu_service";
}
+ public abstract class HostNfcFService extends android.app.Service {
+ ctor public HostNfcFService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onDeactivated(int);
+ method public abstract byte[] processNfcFPacket(byte[], android.os.Bundle);
+ method public final void sendResponsePacket(byte[]);
+ field public static final int DEACTIVATION_LINK_LOSS = 0; // 0x0
+ field public static final java.lang.String SERVICE_INTERFACE = "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
+ field public static final java.lang.String SERVICE_META_DATA = "android.nfc.cardemulation.host_nfcf_service";
+ }
+
+ public final class NfcFCardEmulation {
+ method public boolean disableNfcFForegroundService(android.app.Activity);
+ method public boolean enableNfcFForegroundService(android.app.Activity, android.content.ComponentName);
+ method public static synchronized android.nfc.cardemulation.NfcFCardEmulation getInstance(android.nfc.NfcAdapter);
+ method public java.lang.String getNfcid2ForService(android.content.ComponentName);
+ method public java.lang.String getSystemCodeForService(android.content.ComponentName);
+ method public boolean registerSystemCodeForService(android.content.ComponentName, java.lang.String);
+ method public boolean removeSystemCodeForService(android.content.ComponentName);
+ method public boolean setNfcid2ForService(android.content.ComponentName, java.lang.String);
+ }
+
public abstract class OffHostApduService extends android.app.Service {
ctor public OffHostApduService();
method public abstract android.os.IBinder onBind(android.content.Intent);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 054dafe..3029b11 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1295,6 +1295,14 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports host-
+ * based NFC-F card emulation.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_NFC_HOST_CARD_EMULATION_NFCF = "android.hardware.nfc.hcef";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports the OpenGL ES
* <a href="http://www.khronos.org/registry/gles/extensions/ANDROID/ANDROID_extension_pack_es31a.txt">
* Android Extension Pack</a>.
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 961a3f4..940565f 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -26,6 +26,7 @@
import android.nfc.INfcAdapterExtras;
import android.nfc.INfcTag;
import android.nfc.INfcCardEmulation;
+import android.nfc.INfcFCardEmulation;
import android.nfc.INfcUnlockHandler;
import android.os.Bundle;
@@ -36,6 +37,7 @@
{
INfcTag getNfcTagInterface();
INfcCardEmulation getNfcCardEmulationInterface();
+ INfcFCardEmulation getNfcFCardEmulationInterface();
INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
int getState();
diff --git a/core/java/android/nfc/INfcFCardEmulation.aidl b/core/java/android/nfc/INfcFCardEmulation.aidl
new file mode 100644
index 0000000..124bfac
--- /dev/null
+++ b/core/java/android/nfc/INfcFCardEmulation.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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.content.ComponentName;
+import android.nfc.cardemulation.NfcFServiceInfo;
+
+/**
+ * @hide
+ */
+interface INfcFCardEmulation
+{
+ String getSystemCodeForService(int userHandle, in ComponentName service);
+ boolean registerSystemCodeForService(int userHandle, in ComponentName service, String systemCode);
+ boolean removeSystemCodeForService(int userHandle, in ComponentName service);
+ String getNfcid2ForService(int userHandle, in ComponentName service);
+ boolean setNfcid2ForService(int userHandle, in ComponentName service, String nfcid2);
+ boolean enableNfcFForegroundService(in ComponentName service);
+ boolean disableNfcFForegroundService();
+ List<NfcFServiceInfo> getNfcFServices(int userHandle);
+ int getMaxNumOfRegisterableSystemCodes();
+}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index ff6eb40..acd780d 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -294,6 +294,7 @@
static INfcAdapter sService;
static INfcTag sTagService;
static INfcCardEmulation sCardEmulationService;
+ static INfcFCardEmulation sNfcFCardEmulationService;
/**
* The NfcAdapter object for each application context.
@@ -452,6 +453,13 @@
throw new UnsupportedOperationException();
}
+ try {
+ sNfcFCardEmulationService = sService.getNfcFCardEmulationInterface();
+ } catch (RemoteException e) {
+ Log.e(TAG, "could not retrieve NFC-F card emulation service");
+ throw new UnsupportedOperationException();
+ }
+
sIsInitialized = true;
}
if (context == null) {
@@ -571,6 +579,15 @@
}
/**
+ * Returns the binder interface to the NFC-F card emulation service.
+ * @hide
+ */
+ public INfcFCardEmulation getNfcFCardEmulationService() {
+ isEnabled();
+ return sNfcFCardEmulationService;
+ }
+
+ /**
* NFC service dead - attempt best effort recovery
* @hide
*/
@@ -601,6 +618,12 @@
Log.e(TAG, "could not retrieve NFC card emulation service during service recovery");
}
+ try {
+ sNfcFCardEmulationService = service.getNfcFCardEmulationInterface();
+ } catch (RemoteException ee) {
+ Log.e(TAG, "could not retrieve NFC-F card emulation service during service recovery");
+ }
+
return;
}
diff --git a/core/java/android/nfc/cardemulation/HostNfcFService.java b/core/java/android/nfc/cardemulation/HostNfcFService.java
new file mode 100644
index 0000000..273ddeb
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/HostNfcFService.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2015 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.cardemulation;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * <p>HostNfcFService is a convenience {@link Service} class that can be
+ * extended to emulate an NFC-F card inside an Android service component.
+ */
+public abstract class HostNfcFService extends Service {
+ /**
+ * The {@link Intent} action that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE =
+ "android.nfc.cardemulation.action.HOST_NFCF_SERVICE";
+
+ /**
+ * The name of the meta-data element that contains
+ * more information about this service.
+ */
+ public static final String SERVICE_META_DATA =
+ "android.nfc.cardemulation.host_nfcf_service";
+
+ /**
+ * Reason for {@link #onDeactivated(int)}.
+ * Indicates deactivation was due to the NFC link
+ * being lost.
+ */
+ public static final int DEACTIVATION_LINK_LOSS = 0;
+
+ static final String TAG = "NfcFService";
+
+ /**
+ * MSG_COMMAND_PACKET is sent by NfcService when
+ * a NFC-F command packet has been received.
+ *
+ * @hide
+ */
+ public static final int MSG_COMMAND_PACKET = 0;
+
+ /**
+ * MSG_RESPONSE_PACKET is sent to NfcService to send
+ * a response packet back to the remote device.
+ *
+ * @hide
+ */
+ public static final int MSG_RESPONSE_PACKET = 1;
+
+ /**
+ * MSG_DEACTIVATED is sent by NfcService when
+ * the current session is finished; because
+ * the NFC link was deactivated.
+ *
+ * @hide
+ */
+ public static final int MSG_DEACTIVATED = 2;
+
+ /**
+ * @hide
+ */
+ public static final String KEY_DATA = "data";
+
+ /**
+ * @hide
+ */
+ public static final String KEY_MESSENGER = "messenger";
+
+ /**
+ * Messenger interface to NfcService for sending responses.
+ * Only accessed on main thread by the message handler.
+ *
+ * @hide
+ */
+ Messenger mNfcService = null;
+
+ final Messenger mMessenger = new Messenger(new MsgHandler());
+
+ final class MsgHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_COMMAND_PACKET:
+ Bundle dataBundle = msg.getData();
+ if (dataBundle == null) {
+ return;
+ }
+ if (mNfcService == null) mNfcService = msg.replyTo;
+
+ byte[] packet = dataBundle.getByteArray(KEY_DATA);
+ if (packet != null) {
+ byte[] responsePacket = processNfcFPacket(packet, null);
+ if (responsePacket != null) {
+ if (mNfcService == null) {
+ Log.e(TAG, "Response not sent; service was deactivated.");
+ return;
+ }
+ Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
+ Bundle responseBundle = new Bundle();
+ responseBundle.putByteArray(KEY_DATA, responsePacket);
+ responseMsg.setData(responseBundle);
+ responseMsg.replyTo = mMessenger;
+ try {
+ mNfcService.send(responseMsg);
+ } catch (RemoteException e) {
+ Log.e("TAG", "Response not sent; RemoteException calling into " +
+ "NfcService.");
+ }
+ }
+ } else {
+ Log.e(TAG, "Received MSG_COMMAND_PACKET without data.");
+ }
+ break;
+ case MSG_RESPONSE_PACKET:
+ if (mNfcService == null) {
+ Log.e(TAG, "Response not sent; service was deactivated.");
+ return;
+ }
+ try {
+ msg.replyTo = mMessenger;
+ mNfcService.send(msg);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException calling into NfcService.");
+ }
+ break;
+ case MSG_DEACTIVATED:
+ // Make sure we won't call into NfcService again
+ mNfcService = null;
+ onDeactivated(msg.arg1);
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ }
+
+ @Override
+ public final IBinder onBind(Intent intent) {
+ return mMessenger.getBinder();
+ }
+
+ /**
+ * Sends a response packet back to the remote device.
+ *
+ * <p>Note: this method may be called from any thread and will not block.
+ * @param responsePacket A byte-array containing the response packet.
+ */
+ public final void sendResponsePacket(byte[] responsePacket) {
+ Message responseMsg = Message.obtain(null, MSG_RESPONSE_PACKET);
+ Bundle dataBundle = new Bundle();
+ dataBundle.putByteArray(KEY_DATA, responsePacket);
+ responseMsg.setData(dataBundle);
+ try {
+ mMessenger.send(responseMsg);
+ } catch (RemoteException e) {
+ Log.e("TAG", "Local messenger has died.");
+ }
+ }
+
+ /**
+ * <p>This method will be called when a NFC-F packet has been received
+ * from a remote device. A response packet can be provided directly
+ * by returning a byte-array in this method. Note that in general
+ * response packets must be sent as quickly as possible, given the fact
+ * that the user is likely holding his device over an NFC reader
+ * when this method is called.
+ *
+ * <p class="note">This method is running on the main thread of your application.
+ * If you cannot return a response packet immediately, return null
+ * and use the {@link #sendResponsePacket(byte[])} method later.
+ *
+ * @param commandPacket The NFC-F packet that was received from the remote device
+ * @param extras A bundle containing extra data. May be null.
+ * @return a byte-array containing the response packet, or null if no
+ * response packet can be sent at this point.
+ */
+ public abstract byte[] processNfcFPacket(byte[] commandPacket, Bundle extras);
+
+ /**
+ * This method will be called in following possible scenarios:
+ * <li>The NFC link has been lost
+ * @param reason {@link #DEACTIVATION_LINK_LOSS}
+ */
+ public abstract void onDeactivated(int reason);
+}
diff --git a/core/java/android/nfc/cardemulation/NfcFCardEmulation.java b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
new file mode 100644
index 0000000..d61ac02
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/NfcFCardEmulation.java
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2015 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.cardemulation;
+
+import android.app.Activity;
+import android.app.ActivityThread;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.nfc.INfcFCardEmulation;
+import android.nfc.NfcAdapter;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * This class can be used to query the state of
+ * NFC-F card emulation services.
+ *
+ * For a general introduction into NFC card emulation,
+ * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
+ * NFC card emulation developer guide</a>.</p>
+ *
+ * <p class="note">Use of this class requires the
+ * {@link PackageManager#FEATURE_NFC_HOST_CARD_EMULATION_NFCF}
+ * to be present on the device.
+ */
+public final class NfcFCardEmulation {
+ static final String TAG = "NfcFCardEmulation";
+
+ static boolean sIsInitialized = false;
+ static HashMap<Context, NfcFCardEmulation> sCardEmus = new HashMap<Context, NfcFCardEmulation>();
+ static INfcFCardEmulation sService;
+
+ final Context mContext;
+
+ private NfcFCardEmulation(Context context, INfcFCardEmulation service) {
+ mContext = context.getApplicationContext();
+ sService = service;
+ }
+
+ /**
+ * Helper to get an instance of this class.
+ *
+ * @param adapter A reference to an NfcAdapter object.
+ * @return
+ */
+ public static synchronized NfcFCardEmulation getInstance(NfcAdapter adapter) {
+ if (adapter == null) throw new NullPointerException("NfcAdapter is null");
+ Context context = adapter.getContext();
+ if (context == null) {
+ Log.e(TAG, "NfcAdapter context is null.");
+ throw new UnsupportedOperationException();
+ }
+ if (!sIsInitialized) {
+ IPackageManager pm = ActivityThread.getPackageManager();
+ if (pm == null) {
+ Log.e(TAG, "Cannot get PackageManager");
+ throw new UnsupportedOperationException();
+ }
+ try {
+ if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+ Log.e(TAG, "This device does not support NFC-F card emulation");
+ throw new UnsupportedOperationException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "PackageManager query failed.");
+ throw new UnsupportedOperationException();
+ }
+ sIsInitialized = true;
+ }
+ NfcFCardEmulation manager = sCardEmus.get(context);
+ if (manager == null) {
+ // Get card emu service
+ INfcFCardEmulation service = adapter.getNfcFCardEmulationService();
+ if (service == null) {
+ Log.e(TAG, "This device does not implement the INfcFCardEmulation interface.");
+ throw new UnsupportedOperationException();
+ }
+ manager = new NfcFCardEmulation(context, service);
+ sCardEmus.put(context, manager);
+ }
+ return manager;
+ }
+
+ /**
+ * Retrieves the current System Code for the specified service.
+ *
+ * <p>Before calling {@link #registerSystemCodeForService(ComponentName, String)},
+ * the System Code contained in the Manifest file is returned. After calling
+ * {@link #registerSystemCodeForService(ComponentName, String)}, the System Code
+ * registered there is returned. After calling
+ * {@link #removeSystemCodeForService(ComponentName)}, "null" is returned.
+ *
+ * @param service The component name of the service
+ * @return the current System Code
+ */
+ public String getSystemCodeForService(ComponentName service) {
+ if (service == null) {
+ throw new NullPointerException("service is null");
+ }
+ try {
+ return sService.getSystemCodeForService(UserHandle.myUserId(), service);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ return sService.getSystemCodeForService(UserHandle.myUserId(), service);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Registers a System Code for the specified service.
+ *
+ * <p>The System Code must be in range from "4000" to "4FFF" (excluding "4*FF").
+ *
+ * <p>If a System Code was previously registered for this service
+ * (either statically through the manifest, or dynamically by using this API),
+ * it will be replaced with this one.
+ *
+ * <p>Even if the same System Code is already registered for another service,
+ * this method succeeds in registering the System Code.
+ *
+ * <p>Note that you can only register a System Code for a service that
+ * is running under the same UID as the caller of this API. Typically
+ * this means you need to call this from the same
+ * package as the service itself, though UIDs can also
+ * be shared between packages using shared UIDs.
+ *
+ * @param service The component name of the service
+ * @param systemCode The System Code to be registered
+ * @return whether the registration was successful.
+ */
+ public boolean registerSystemCodeForService(ComponentName service, String systemCode) {
+ if (service == null || systemCode == null) {
+ throw new NullPointerException("service or systemCode is null");
+ }
+ try {
+ return sService.registerSystemCodeForService(UserHandle.myUserId(),
+ service, systemCode);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.registerSystemCodeForService(UserHandle.myUserId(),
+ service, systemCode);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Removes a registered System Code for the specified service.
+ *
+ * @param service The component name of the service
+ * @return whether the System Code was successfully removed.
+ */
+ public boolean removeSystemCodeForService(ComponentName service) {
+ if (service == null) {
+ throw new NullPointerException("service is null");
+ }
+ try {
+ return sService.removeSystemCodeForService(UserHandle.myUserId(), service);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.removeSystemCodeForService(UserHandle.myUserId(), service);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Retrieves the current NFCID2 for the specified service.
+ *
+ * <p>Before calling {@link #setNfcid2ForService(ComponentName, String)},
+ * the NFCID2 contained in the Manifest file is returned. If "random" is specified
+ * in the Manifest file, a random number assigned by the system at installation time
+ * is returned. After setting an NFCID2
+ * with {@link #setNfcid2ForService(ComponentName, String)}, this NFCID2 is returned.
+ *
+ * @param service The component name of the service
+ * @return the current NFCID2
+ */
+ public String getNfcid2ForService(ComponentName service) {
+ if (service == null) {
+ throw new NullPointerException("service is null");
+ }
+ try {
+ return sService.getNfcid2ForService(UserHandle.myUserId(), service);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ return sService.getNfcid2ForService(UserHandle.myUserId(), service);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Set a NFCID2 for the specified service.
+ *
+ * <p>The NFCID2 must be in range from "02FE000000000000" to "02FEFFFFFFFFFFFF".
+ *
+ * <p>If a NFCID2 was previously set for this service
+ * (either statically through the manifest, or dynamically by using this API),
+ * it will be replaced.
+ *
+ * <p>Note that you can only set the NFCID2 for a service that
+ * is running under the same UID as the caller of this API. Typically
+ * this means you need to call this from the same
+ * package as the service itself, though UIDs can also
+ * be shared between packages using shared UIDs.
+ *
+ * @param service The component name of the service
+ * @param nfcid2 The NFCID2 to be registered
+ * @return whether the setting was successful.
+ */
+ public boolean setNfcid2ForService(ComponentName service, String nfcid2) {
+ if (service == null || nfcid2 == null) {
+ throw new NullPointerException("service or nfcid2 is null");
+ }
+ try {
+ return sService.setNfcid2ForService(UserHandle.myUserId(),
+ service, nfcid2);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.setNfcid2ForService(UserHandle.myUserId(),
+ service, nfcid2);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Allows a foreground application to specify which card emulation service
+ * should be enabled while a specific Activity is in the foreground.
+ *
+ * <p>The specified HCE-F service is only enabled when the corresponding application is
+ * in the foreground and this method has been called. When the application is moved to
+ * the background, {@link #disableNfcFForegroundService(Activity)} is called, or
+ * NFCID2 or System Code is replaced, the HCE-F service is disabled.
+ *
+ * <p>The specified Activity must currently be in resumed state. A good
+ * paradigm is to call this method in your {@link Activity#onResume}, and to call
+ * {@link #disableNfcFForegroundService(Activity)} in your {@link Activity#onPause}.
+ *
+ * <p>Note that this preference is not persisted by the OS, and hence must be
+ * called every time the Activity is resumed.
+ *
+ * @param activity The activity which prefers this service to be invoked
+ * @param service The service to be preferred while this activity is in the foreground
+ * @return whether the registration was successful
+ */
+ public boolean enableNfcFForegroundService(Activity activity, ComponentName service) {
+ if (activity == null || service == null) {
+ throw new NullPointerException("activity or service is null");
+ }
+ // Verify the activity is in the foreground before calling into NfcService
+ if (!activity.isResumed()) {
+ throw new IllegalArgumentException("Activity must be resumed.");
+ }
+ try {
+ return sService.enableNfcFForegroundService(service);
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.enableNfcFForegroundService(service);
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Disables the service for the specified Activity.
+ *
+ * <p>Note that the specified Activity must still be in resumed
+ * state at the time of this call. A good place to call this method
+ * is in your {@link Activity#onPause} implementation.
+ *
+ * @param activity The activity which the service was registered for
+ * @return true when successful
+ */
+ public boolean disableNfcFForegroundService(Activity activity) {
+ if (activity == null) {
+ throw new NullPointerException("activity is null");
+ }
+ if (!activity.isResumed()) {
+ throw new IllegalArgumentException("Activity must be resumed.");
+ }
+ try {
+ return sService.disableNfcFForegroundService();
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return false;
+ }
+ try {
+ return sService.disableNfcFForegroundService();
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return false;
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public List<NfcFServiceInfo> getNfcFServices() {
+ try {
+ return sService.getNfcFServices(UserHandle.myUserId());
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return null;
+ }
+ try {
+ return sService.getNfcFServices(UserHandle.myUserId());
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return null;
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public int getMaxNumOfRegisterableSystemCodes() {
+ try {
+ return sService.getMaxNumOfRegisterableSystemCodes();
+ } catch (RemoteException e) {
+ // Try one more time
+ recoverService();
+ if (sService == null) {
+ Log.e(TAG, "Failed to recover CardEmulationService.");
+ return -1;
+ }
+ try {
+ return sService.getMaxNumOfRegisterableSystemCodes();
+ } catch (RemoteException ee) {
+ Log.e(TAG, "Failed to reach CardEmulationService.");
+ return -1;
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static boolean isValidSystemCode(String systemCode) {
+ if (systemCode == null) {
+ return false;
+ }
+ if (systemCode.length() != 4) {
+ Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
+ return false;
+ }
+ // check if the value is between "4000" and "4FFF" (excluding "4*FF")
+ if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) {
+ Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
+ return false;
+ }
+ try {
+ Integer.valueOf(systemCode, 16);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "System Code " + systemCode + " is not a valid System Code.");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * @hide
+ */
+ public static boolean isValidNfcid2(String nfcid2) {
+ if (nfcid2 == null) {
+ return false;
+ }
+ if (nfcid2.length() != 16) {
+ Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
+ return false;
+ }
+ // check if the the value starts with "02FE"
+ if (!nfcid2.toUpperCase().startsWith("02FE")) {
+ Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
+ return false;
+ }
+ try {
+ Long.valueOf(nfcid2, 16);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2.");
+ return false;
+ }
+ return true;
+ }
+
+ void recoverService() {
+ NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
+ sService = adapter.getNfcFCardEmulationService();
+ }
+
+}
+
diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl b/core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
new file mode 100644
index 0000000..56b98eb
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 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.cardemulation;
+
+parcelable NfcFServiceInfo;
diff --git a/core/java/android/nfc/cardemulation/NfcFServiceInfo.java b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
new file mode 100644
index 0000000..b93eec1
--- /dev/null
+++ b/core/java/android/nfc/cardemulation/NfcFServiceInfo.java
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2015 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.cardemulation;
+
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @hide
+ */
+public final class NfcFServiceInfo implements Parcelable {
+ static final String TAG = "NfcFServiceInfo";
+
+ /**
+ * The service that implements this
+ */
+ final ResolveInfo mService;
+
+ /**
+ * Description of the service
+ */
+ final String mDescription;
+
+ /**
+ * System Code of the service
+ */
+ final String mSystemCode;
+
+ /**
+ * System Code of the service registered by API
+ */
+ String mDynamicSystemCode;
+
+ /**
+ * NFCID2 of the service
+ */
+ final String mNfcid2;
+
+ /**
+ * NFCID2 of the service registered by API
+ */
+ String mDynamicNfcid2;
+
+ /**
+ * The uid of the package the service belongs to
+ */
+ final int mUid;
+
+ /**
+ * @hide
+ */
+ public NfcFServiceInfo(ResolveInfo info, String description,
+ String systemCode, String dynamicSystemCode, String nfcid2, String dynamicNfcid2,
+ int uid) {
+ this.mService = info;
+ this.mDescription = description;
+ this.mSystemCode = systemCode;
+ this.mDynamicSystemCode = dynamicSystemCode;
+ this.mNfcid2 = nfcid2;
+ this.mDynamicNfcid2 = dynamicNfcid2;
+ this.mUid = uid;
+ }
+
+ public NfcFServiceInfo(PackageManager pm, ResolveInfo info)
+ throws XmlPullParserException, IOException {
+ ServiceInfo si = info.serviceInfo;
+ XmlResourceParser parser = null;
+ try {
+ parser = si.loadXmlMetaData(pm, HostNfcFService.SERVICE_META_DATA);
+ if (parser == null) {
+ throw new XmlPullParserException("No " + HostNfcFService.SERVICE_META_DATA +
+ " meta-data");
+ }
+
+ int eventType = parser.getEventType();
+ while (eventType != XmlPullParser.START_TAG &&
+ eventType != XmlPullParser.END_DOCUMENT) {
+ eventType = parser.next();
+ }
+
+ String tagName = parser.getName();
+ if (!"host-nfcf-service".equals(tagName)) {
+ throw new XmlPullParserException(
+ "Meta-data does not start with <host-nfcf-service> tag");
+ }
+
+ Resources res = pm.getResourcesForApplication(si.applicationInfo);
+ AttributeSet attrs = Xml.asAttributeSet(parser);
+ TypedArray sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.HostNfcFService);
+ mService = info;
+ mDescription = sa.getString(
+ com.android.internal.R.styleable.HostNfcFService_description);
+ mDynamicSystemCode = null;
+ mDynamicNfcid2 = null;
+ sa.recycle();
+
+ String systemCode = null;
+ String nfcid2 = null;
+ final int depth = parser.getDepth();
+
+ while (((eventType = parser.next()) != XmlPullParser.END_TAG ||
+ parser.getDepth() > depth) && eventType != XmlPullParser.END_DOCUMENT) {
+ tagName = parser.getName();
+ if (eventType == XmlPullParser.START_TAG &&
+ "system-code-filter".equals(tagName) && systemCode == null) {
+ final TypedArray a = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.SystemCodeFilter);
+ systemCode = a.getString(
+ com.android.internal.R.styleable.SystemCodeFilter_name).toUpperCase();
+ if (!NfcFCardEmulation.isValidSystemCode(systemCode) &&
+ !systemCode.equalsIgnoreCase("NULL")) {
+ Log.e(TAG, "Invalid System Code: " + systemCode);
+ systemCode = null;
+ }
+ a.recycle();
+ } else if (eventType == XmlPullParser.START_TAG &&
+ "nfcid2-filter".equals(tagName) && nfcid2 == null) {
+ final TypedArray a = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.Nfcid2Filter);
+ nfcid2 = a.getString(
+ com.android.internal.R.styleable.Nfcid2Filter_name).toUpperCase();
+ if (!nfcid2.equalsIgnoreCase("RANDOM") &&
+ !nfcid2.equalsIgnoreCase("NULL") &&
+ !NfcFCardEmulation.isValidNfcid2(nfcid2)) {
+ Log.e(TAG, "Invalid NFCID2: " + nfcid2);
+ nfcid2 = null;
+ }
+ a.recycle();
+ }
+ }
+ mSystemCode = (systemCode == null ? "NULL" : systemCode);
+ mNfcid2 = (nfcid2 == null ? "NULL" : nfcid2);
+ } catch (NameNotFoundException e) {
+ throw new XmlPullParserException("Unable to create context for: " + si.packageName);
+ } finally {
+ if (parser != null) parser.close();
+ }
+ // Set uid
+ mUid = si.applicationInfo.uid;
+ }
+
+ public ComponentName getComponent() {
+ return new ComponentName(mService.serviceInfo.packageName,
+ mService.serviceInfo.name);
+ }
+
+ public String getSystemCode() {
+ return (mDynamicSystemCode == null ? mSystemCode : mDynamicSystemCode);
+ }
+
+ public void setOrReplaceDynamicSystemCode(String systemCode) {
+ mDynamicSystemCode = systemCode;
+ }
+
+ public String getNfcid2() {
+ return (mDynamicNfcid2 == null ? mNfcid2 : mDynamicNfcid2);
+ }
+
+ public void setOrReplaceDynamicNfcid2(String nfcid2) {
+ mDynamicNfcid2 = nfcid2;
+ }
+
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public int getUid() {
+ return mUid;
+ }
+
+ public CharSequence loadLabel(PackageManager pm) {
+ return mService.loadLabel(pm);
+ }
+
+ public Drawable loadIcon(PackageManager pm) {
+ return mService.loadIcon(pm);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder out = new StringBuilder("NfcFService: ");
+ out.append(getComponent());
+ out.append(", description: " + mDescription);
+ out.append(", System Code: " + mSystemCode);
+ if (mDynamicSystemCode != null) {
+ out.append(", dynamic System Code: " + mDynamicSystemCode);
+ }
+ out.append(", NFCID2: " + mNfcid2);
+ if (mDynamicNfcid2 != null) {
+ out.append(", dynamic NFCID2: " + mDynamicNfcid2);
+ }
+ return out.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof NfcFServiceInfo)) return false;
+ NfcFServiceInfo thatService = (NfcFServiceInfo) o;
+
+ if (!thatService.getComponent().equals(this.getComponent())) return false;
+ if (!thatService.mSystemCode.equalsIgnoreCase(this.mSystemCode)) return false;
+ if (!thatService.mNfcid2.equalsIgnoreCase(this.mNfcid2)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return getComponent().hashCode();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ mService.writeToParcel(dest, flags);
+ dest.writeString(mDescription);
+ dest.writeString(mSystemCode);
+ dest.writeInt(mDynamicSystemCode != null ? 1 : 0);
+ if (mDynamicSystemCode != null) {
+ dest.writeString(mDynamicSystemCode);
+ }
+ dest.writeString(mNfcid2);
+ dest.writeInt(mDynamicNfcid2 != null ? 1 : 0);
+ if (mDynamicNfcid2 != null) {
+ dest.writeString(mDynamicNfcid2);
+ }
+ dest.writeInt(mUid);
+ };
+
+ public static final Parcelable.Creator<NfcFServiceInfo> CREATOR =
+ new Parcelable.Creator<NfcFServiceInfo>() {
+ @Override
+ public NfcFServiceInfo createFromParcel(Parcel source) {
+ ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source);
+ String description = source.readString();
+ String systemCode = source.readString();
+ String dynamicSystemCode = null;
+ if (source.readInt() != 0) {
+ dynamicSystemCode = source.readString();
+ }
+ String nfcid2 = source.readString();
+ String dynamicNfcid2 = null;
+ if (source.readInt() != 0) {
+ dynamicNfcid2 = source.readString();
+ }
+ int uid = source.readInt();
+ NfcFServiceInfo service = new NfcFServiceInfo(info, description,
+ systemCode, dynamicSystemCode, nfcid2, dynamicNfcid2, uid);
+ return service;
+ }
+
+ @Override
+ public NfcFServiceInfo[] newArray(int size) {
+ return new NfcFServiceInfo[size];
+ }
+ };
+
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println(" " + getComponent() +
+ " (Description: " + getDescription() + ")");
+ pw.println(" System Code: " + getSystemCode());
+ pw.println(" NFCID2: " + getNfcid2());
+ }
+}
+
diff --git a/core/java/android/security/NetworkSecurityPolicy.java b/core/java/android/security/NetworkSecurityPolicy.java
index 46aa1af..83c4e4a 100644
--- a/core/java/android/security/NetworkSecurityPolicy.java
+++ b/core/java/android/security/NetworkSecurityPolicy.java
@@ -16,6 +16,11 @@
package android.security;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.security.net.config.ApplicationConfig;
+import android.security.net.config.ManifestConfigSource;
+
/**
* Network security policy.
*
@@ -87,4 +92,17 @@
FrameworkNetworkSecurityPolicy policy = new FrameworkNetworkSecurityPolicy(permitted);
libcore.net.NetworkSecurityPolicy.setInstance(policy);
}
+
+
+ /**
+ * Returns an {@link ApplicationConfig} based on the configuration for {@code packageName}.
+ *
+ * @hide
+ */
+ public static ApplicationConfig getApplicationConfigForPackage(Context context,
+ String packageName) throws PackageManager.NameNotFoundException {
+ Context appContext = context.createPackageContext(packageName, 0);
+ ManifestConfigSource source = new ManifestConfigSource(appContext);
+ return new ApplicationConfig(source);
+ }
}
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
index 463eb5b..8393f7e 100644
--- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -58,6 +58,10 @@
}
public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
+ if (si == null) {
+ mParseError = "Service not available";
+ return;
+ }
if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
mParseError = "Service does not require permission "
+ Manifest.permission.BIND_VOICE_INTERACTION;
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2828d21..5a08169 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3315,6 +3315,32 @@
<attr name="name" />
</declare-styleable>
+ <!-- Use <code>host-nfcf-service</code> as the root tag of the XML resource that
+ describes an {@link android.nfc.cardemulation.HostNfcFService} service, which
+ is referenced from its {@link android.nfc.cardemulation.HostNfcFService#SERVICE_META_DATA}
+ entry. -->
+ <declare-styleable name="HostNfcFService">
+ <!-- Short description of the functionality the service implements. This attribute
+ is mandatory.-->
+ <attr name="description" />
+ </declare-styleable>
+
+ <!-- Specify one or more <code>system-code-filter</code> elements inside a
+ <code>host-nfcf-service</code> element to specify a System Code
+ your service can handle. -->
+ <declare-styleable name="SystemCodeFilter">
+ <!-- The System Code. This attribute is mandatory. -->
+ <attr name="name" />
+ </declare-styleable>
+
+ <!-- Specify one or more <code>nfcid2-filter</code> elements inside a
+ <code>host-nfcf-service</code> element to specify a NFCID2
+ your service can handle. -->
+ <declare-styleable name="Nfcid2Filter">
+ <!-- The NFCID2. This attribute is mandatory. -->
+ <attr name="name" />
+ </declare-styleable>
+
<declare-styleable name="ActionMenuItemView">
<attr name="minWidth" />
</declare-styleable>
diff --git a/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java b/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java
deleted file mode 100644
index f29c5c0..0000000
--- a/tools/layoutlib/bridge/src/libcore/util/ZoneInfo_WallTime_Delegate.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2014 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 libcore.util;
-
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-
-import java.util.GregorianCalendar;
-
-/**
- * Delegate used to provide alternate implementation of select methods in {@link ZoneInfo.WallTime}
- */
-public class ZoneInfo_WallTime_Delegate {
-
- @LayoutlibDelegate
- static GregorianCalendar createGregorianCalendar() {
- return new GregorianCalendar();
- }
-}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index c9bc62e..7c838e9 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -200,7 +200,6 @@
"libcore.io.MemoryMappedFile#mmapRO",
"libcore.io.MemoryMappedFile#close",
"libcore.io.MemoryMappedFile#bigEndianIterator",
- "libcore.util.ZoneInfo$WallTime#createGregorianCalendar",
};
/**