diff options
Diffstat (limited to 'src/com/android/nfc/NfcService.java')
-rwxr-xr-x | src/com/android/nfc/NfcService.java | 105 |
1 files changed, 97 insertions, 8 deletions
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index a646c246..0b110c77 100755 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Resources.NotFoundException; import android.media.AudioManager; @@ -78,6 +79,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -98,14 +100,16 @@ public class NfcService implements DeviceHostListener { static final String PREF_AIRPLANE_OVERRIDE = "airplane_override"; static final int MSG_NDEF_TAG = 0; - static final int MSG_LLCP_LINK_ACTIVATION = 2; - static final int MSG_LLCP_LINK_DEACTIVATED = 3; - static final int MSG_MOCK_NDEF = 7; - static final int MSG_LLCP_LINK_FIRST_PACKET = 15; - static final int MSG_ROUTE_AID = 16; - static final int MSG_UNROUTE_AID = 17; - static final int MSG_COMMIT_ROUTING = 18; - static final int MSG_INVOKE_BEAM = 19; + static final int MSG_LLCP_LINK_ACTIVATION = 1; + static final int MSG_LLCP_LINK_DEACTIVATED = 2; + static final int MSG_MOCK_NDEF = 3; + static final int MSG_LLCP_LINK_FIRST_PACKET = 4; + static final int MSG_ROUTE_AID = 5; + static final int MSG_UNROUTE_AID = 6; + static final int MSG_COMMIT_ROUTING = 7; + static final int MSG_INVOKE_BEAM = 8; + static final int MSG_RF_FIELD_ACTIVATED = 9; + static final int MSG_RF_FIELD_DEACTIVATED = 10; static final int TASK_ENABLE = 1; static final int TASK_DISABLE = 2; @@ -138,6 +142,12 @@ public class NfcService implements DeviceHostListener { // the Beam animation when called through the share menu. static final int INVOKE_BEAM_DELAY_MS = 1000; + // RF field events as defined in NFC extras + public static final String ACTION_RF_FIELD_ON_DETECTED = + "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED"; + public static final String ACTION_RF_FIELD_OFF_DETECTED = + "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED"; + // for use with playSound() public static final int SOUND_START = 0; public static final int SOUND_END = 1; @@ -157,6 +167,10 @@ public class NfcService implements DeviceHostListener { new ReaderModeDeathRecipient(); private final NfcUnlockManager mNfcUnlockManager; + private final NfceeAccessControl mNfceeAccessControl; + + List<PackageInfo> mInstalledPackages; // cached version of installed packages + // fields below are used in multiple threads and protected by synchronized(this) final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>(); int mScreenState; @@ -260,6 +274,15 @@ public class NfcService implements DeviceHostListener { sendMessage(NfcService.MSG_LLCP_LINK_FIRST_PACKET, device); } + @Override + public void onRemoteFieldActivated() { + sendMessage(NfcService.MSG_RF_FIELD_ACTIVATED, null); + } + + public void onRemoteFieldDeactivated() { + sendMessage(NfcService.MSG_RF_FIELD_DEACTIVATED, null); + } + final class ReaderModeParams { public int flags; public IAppCallback callback; @@ -305,6 +328,8 @@ public class NfcService implements DeviceHostListener { mPrefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); mPrefsEditor = mPrefs.edit(); + mNfceeAccessControl = new NfceeAccessControl(mContext); + mState = NfcAdapter.STATE_OFF; mIsNdefPushEnabled = mPrefs.getBoolean(PREF_NDEF_PUSH_ON, NDEF_PUSH_ON_DEFAULT); setBeamShareActivityState(mIsNdefPushEnabled); @@ -331,6 +356,18 @@ public class NfcService implements DeviceHostListener { registerForAirplaneMode(filter); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); + IntentFilter ownerFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); + ownerFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); + mContext.registerReceiver(mOwnerReceiver, ownerFilter); + + ownerFilter = new IntentFilter(); + ownerFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + ownerFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + ownerFilter.addDataScheme("package"); + mContext.registerReceiver(mOwnerReceiver, ownerFilter); + + updatePackageCache(); + PackageManager pm = mContext.getPackageManager(); mIsHceCapable = pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION); if (mIsHceCapable) { @@ -376,6 +413,14 @@ public class NfcService implements DeviceHostListener { } } + void updatePackageCache() { + PackageManager pm = mContext.getPackageManager(); + List<PackageInfo> packages = pm.getInstalledPackages(0, UserHandle.USER_OWNER); + synchronized (this) { + mInstalledPackages = packages; + } + } + /** * Manages tasks that involve turning on/off the NFC controller. * <p/> @@ -1664,12 +1709,37 @@ public class NfcService implements DeviceHostListener { case MSG_LLCP_LINK_FIRST_PACKET: mP2pLinkManager.onLlcpFirstPacketReceived(); break; + case MSG_RF_FIELD_ACTIVATED: + Intent fieldOnIntent = new Intent(ACTION_RF_FIELD_ON_DETECTED); + sendNfcEeAccessProtectedBroadcast(fieldOnIntent); + break; + case MSG_RF_FIELD_DEACTIVATED: + Intent fieldOffIntent = new Intent(ACTION_RF_FIELD_OFF_DETECTED); + sendNfcEeAccessProtectedBroadcast(fieldOffIntent); + break; default: Log.e(TAG, "Unknown message received"); break; } } + private void sendNfcEeAccessProtectedBroadcast(Intent intent) { + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + // Resume app switches so the receivers can start activites without delay + mNfcDispatcher.resumeAppSwitches(); + + synchronized (this) { + for (PackageInfo pkg : mInstalledPackages) { + if (pkg != null && pkg.applicationInfo != null) { + if (mNfceeAccessControl.check(pkg.applicationInfo)) { + intent.setPackage(pkg.packageName); + mContext.sendBroadcast(intent); + } + } + } + } + } + private boolean llcpActivated(NfcDepEndpoint device) { Log.d(TAG, "LLCP Activation message"); @@ -1832,6 +1902,25 @@ public class NfcService implements DeviceHostListener { } }; + private final BroadcastReceiver mOwnerReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || + action.equals(Intent.ACTION_PACKAGE_ADDED) || + action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE) || + action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { + updatePackageCache(); + + if (action.equals(Intent.ACTION_PACKAGE_REMOVED)) { + // Clear the NFCEE access cache in case a UID gets recycled + mNfceeAccessControl.invalidateCache(); + } + } + } + }; + + /** * Returns true if airplane mode is currently on */ |