diff options
author | Martijn Coenen <maco@google.com> | 2013-03-07 13:28:18 -0800 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2013-03-07 16:59:41 -0800 |
commit | 7d8987f233985a5ff29226890e11012275d325f5 (patch) | |
tree | c8b8bab60f6988abb23af1ecc8e4d453ebeff1cd | |
parent | 696652d7f9faaffd198073cb75eb86156f7d9af4 (diff) | |
download | android_packages_apps_Nfc-7d8987f233985a5ff29226890e11012275d325f5.tar.gz android_packages_apps_Nfc-7d8987f233985a5ff29226890e11012275d325f5.tar.bz2 android_packages_apps_Nfc-7d8987f233985a5ff29226890e11012275d325f5.zip |
Allow incoming provisioning intents while in setup wizard.
When the device is in setup wizard, the keyguard state
registers as locked, hence in this state NFC was not
enabled.
This change adds some resource settings to enable
NFC in setup wizard, and allow a set of mime-types
to be received while in that mode.
Bug: 8275527
Change-Id: Iab6cd8438fa77764b0cc9c96cbf1a36e95d79524
-rw-r--r-- | res/values/provisioning.xml | 27 | ||||
-rw-r--r-- | src/com/android/nfc/NfcDispatcher.java | 46 | ||||
-rwxr-xr-x | src/com/android/nfc/NfcService.java | 60 | ||||
-rw-r--r-- | src/com/android/nfc/handover/HandoverManager.java | 11 |
4 files changed, 126 insertions, 18 deletions
diff --git a/res/values/provisioning.xml b/res/values/provisioning.xml new file mode 100644 index 00000000..74e44187 --- /dev/null +++ b/res/values/provisioning.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 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. +--> + +<!-- NFC resources that may need to be customized + for different hardware or product builds. --> +<resources> + <!-- Whether the device can receive NFC data in setup wizard --> + <bool name="enable_nfc_provisioning">false</bool> + + <!-- The accepted mime-types when NFC is enabled in setup wizard. + Mime-types must be lower case, wildcards are *not* accepted. --> + <string-array name="provisioning_mime_types"> + </string-array> +</resources> diff --git a/src/com/android/nfc/NfcDispatcher.java b/src/com/android/nfc/NfcDispatcher.java index 1721d1a8..90316ba7 100644 --- a/src/com/android/nfc/NfcDispatcher.java +++ b/src/com/android/nfc/NfcDispatcher.java @@ -33,6 +33,7 @@ import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; +import android.content.res.Resources.NotFoundException; import android.net.Uri; import android.nfc.NdefMessage; import android.nfc.NdefRecord; @@ -63,19 +64,35 @@ public class NfcDispatcher { final RegisteredComponentCache mTechListFilters; final ContentResolver mContentResolver; final HandoverManager mHandoverManager; + final String[] mProvisioningMimes; // Locked on this PendingIntent mOverrideIntent; IntentFilter[] mOverrideFilters; String[][] mOverrideTechLists; + boolean mProvisioningOnly; - public NfcDispatcher(Context context, HandoverManager handoverManager) { + public NfcDispatcher(Context context, HandoverManager handoverManager, boolean provisionOnly) { mContext = context; mIActivityManager = ActivityManagerNative.getDefault(); mTechListFilters = new RegisteredComponentCache(mContext, NfcAdapter.ACTION_TECH_DISCOVERED, NfcAdapter.ACTION_TECH_DISCOVERED); mContentResolver = context.getContentResolver(); mHandoverManager = handoverManager; + synchronized (this) { + mProvisioningOnly = provisionOnly; + } + String[] provisionMimes = null; + if (provisionOnly) { + try { + // Get accepted mime-types + provisionMimes = context.getResources(). + getStringArray(R.array.provisioning_mime_types); + } catch (NotFoundException e) { + provisionMimes = null; + } + } + mProvisioningMimes = provisionMimes; } public synchronized void setForegroundDispatch(PendingIntent intent, @@ -86,6 +103,10 @@ public class NfcDispatcher { mOverrideTechLists = techLists; } + public synchronized void disableProvisioningMode() { + mProvisioningOnly = false; + } + /** * Helper for re-used objects and methods during a single tag dispatch. */ @@ -191,12 +212,14 @@ public class NfcDispatcher { PendingIntent overrideIntent; IntentFilter[] overrideFilters; String[][] overrideTechLists; + boolean provisioningOnly; DispatchInfo dispatch = new DispatchInfo(mContext, tag, message); synchronized (this) { overrideFilters = mOverrideFilters; overrideIntent = mOverrideIntent; overrideTechLists = mOverrideTechLists; + provisioningOnly = mProvisioningOnly; } resumeAppSwitches(); @@ -205,15 +228,20 @@ public class NfcDispatcher { return true; } - if (mHandoverManager.tryHandover(message)) { + if (!provisioningOnly && mHandoverManager.tryHandover(message)) { if (DBG) Log.i(TAG, "matched BT HANDOVER"); return true; } - if (tryNdef(dispatch, message)) { + if (tryNdef(dispatch, message, provisioningOnly)) { return true; } + if (provisioningOnly) { + // We only allow NDEF-based mimeType matching + return false; + } + if (tryTech(dispatch, tag)) { return true; } @@ -304,7 +332,7 @@ public class NfcDispatcher { return false; } - boolean tryNdef(DispatchInfo dispatch, NdefMessage message) { + boolean tryNdef(DispatchInfo dispatch, NdefMessage message, boolean provisioningOnly) { if (message == null) { return false; } @@ -313,6 +341,14 @@ public class NfcDispatcher { // Bail out if the intent does not contain filterable NDEF data if (intent == null) return false; + if (provisioningOnly) { + if (mProvisioningMimes == null || + !(Arrays.asList(mProvisioningMimes).contains(intent.getType()))) { + Log.e(TAG, "Dropping NFC intent in provisioning mode."); + return false; + } + } + // Try to start AAR activity with matching filter List<String> aarPackages = extractAarPackages(message); for (String pkg : aarPackages) { @@ -408,7 +444,7 @@ public class NfcDispatcher { if (DBG) Log.i(TAG, "matched single TECH"); return true; } - dispatch.intent.setClassName((String)null, null); + dispatch.intent.setComponent(null); } else if (matches.size() > 1) { // Multiple matches, show a custom activity chooser dialog Intent intent = new Intent(mContext, TechListChooserActivity.class); diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index 44369274..d2f89b26 100755 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -37,6 +37,7 @@ 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; import android.media.SoundPool; import android.net.Uri; @@ -199,6 +200,7 @@ public class NfcService implements DeviceHostListener { // as SE access is not granted for non-owner users. HashSet<String> mSePackages = new HashSet<String>(); int mScreenState; + boolean mInProvisionMode; // whether we're in setup wizard and enabled NFC provisioning boolean mIsNdefPushEnabled; boolean mNfceeRouteEnabled; // current Device Host state of NFC-EE routing boolean mNfcPollingEnabled; // current Device Host state of NFC-C polling @@ -232,6 +234,8 @@ public class NfcService implements DeviceHostListener { private NfcDispatcher mNfcDispatcher; private PowerManager mPowerManager; private KeyguardManager mKeyguard; + private HandoverManager mHandoverManager; + private ContentResolver mContentResolver; private static NfcService sService; @@ -340,12 +344,27 @@ public class NfcService implements DeviceHostListener { sService = this; mContext = nfcApplication; + mContentResolver = mContext.getContentResolver(); mDeviceHost = new NativeNfcManager(mContext, this); - HandoverManager handoverManager = new HandoverManager(mContext); - mNfcDispatcher = new NfcDispatcher(mContext, handoverManager); + mHandoverManager = new HandoverManager(mContext); + boolean isNfcProvisioningEnabled = false; + try { + isNfcProvisioningEnabled = mContext.getResources().getBoolean( + R.bool.enable_nfc_provisioning); + } catch (NotFoundException e) { + } + + if (isNfcProvisioningEnabled) { + mInProvisionMode = Settings.Secure.getInt(mContentResolver, + Settings.Global.DEVICE_PROVISIONED, 0) == 0; + } else { + mInProvisionMode = false; + } - mP2pLinkManager = new P2pLinkManager(mContext, handoverManager, + mHandoverManager.setEnabled(!mInProvisionMode); + mNfcDispatcher = new NfcDispatcher(mContext, mHandoverManager, mInProvisionMode); + mP2pLinkManager = new P2pLinkManager(mContext, mHandoverManager, mDeviceHost.getDefaultLlcpMiu(), mDeviceHost.getDefaultLlcpRwSize()); mSecureElement = new NativeNfcSecureElement(mContext); @@ -421,16 +440,15 @@ public class NfcService implements DeviceHostListener { } void registerForAirplaneMode(IntentFilter filter) { - final ContentResolver resolver = mContext.getContentResolver(); - final String airplaneModeRadios = Settings.System.getString(resolver, - Settings.System.AIRPLANE_MODE_RADIOS); - final String toggleableRadios = Settings.System.getString(resolver, - Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS); + final String airplaneModeRadios = Settings.System.getString(mContentResolver, + Settings.Global.AIRPLANE_MODE_RADIOS); + final String toggleableRadios = Settings.System.getString(mContentResolver, + Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS); mIsAirplaneSensitive = airplaneModeRadios == null ? true : - airplaneModeRadios.contains(Settings.System.RADIO_NFC); + airplaneModeRadios.contains(Settings.Global.RADIO_NFC); mIsAirplaneToggleable = toggleableRadios == null ? false : - toggleableRadios.contains(Settings.System.RADIO_NFC); + toggleableRadios.contains(Settings.Global.RADIO_NFC); if (mIsAirplaneSensitive) { filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); @@ -1536,7 +1554,16 @@ public class NfcService implements DeviceHostListener { return; } WatchDogThread watchDog = new WatchDogThread("applyRouting", ROUTING_WATCHDOG_MS); - + if (mInProvisionMode) { + mInProvisionMode = Settings.Secure.getInt(mContentResolver, + Settings.Global.DEVICE_PROVISIONED, 0) == 0; + if (!mInProvisionMode) { + // Notify dispatcher it's fine to dispatch to any package now + // and allow handover transfers. + mNfcDispatcher.disableProvisioningMode(); + mHandoverManager.setEnabled(true); + } + } try { watchDog.start(); @@ -1589,6 +1616,13 @@ public class NfcService implements DeviceHostListener { mNfcPollingEnabled = true; mDeviceHost.enableDiscovery(); } + } else if (mInProvisionMode && mScreenState >= SCREEN_STATE_ON_LOCKED) { + // Special case for setup provisioning + if (!mNfcPollingEnabled) { + Log.d(TAG, "NFC-C ON"); + mNfcPollingEnabled = true; + mDeviceHost.enableDiscovery(); + } } else { if (force || mNfcPollingEnabled) { Log.d(TAG, "NFC-C OFF"); @@ -2052,8 +2086,8 @@ public class NfcService implements DeviceHostListener { /** Returns true if airplane mode is currently on */ boolean isAirplaneModeOn() { - return Settings.System.getInt(mContext.getContentResolver(), - Settings.System.AIRPLANE_MODE_ON, 0) == 1; + return Settings.System.getInt(mContentResolver, + Settings.Global.AIRPLANE_MODE_ON, 0) == 1; } /** for debugging only - no i18n */ diff --git a/src/com/android/nfc/handover/HandoverManager.java b/src/com/android/nfc/handover/HandoverManager.java index af684cb5..96283013 100644 --- a/src/com/android/nfc/handover/HandoverManager.java +++ b/src/com/android/nfc/handover/HandoverManager.java @@ -81,6 +81,7 @@ public class HandoverManager { Messenger mService = null; boolean mBound; String mLocalBluetoothAddress; + boolean mEnabled; static class BluetoothHandoverData { public boolean valid = false; @@ -162,6 +163,7 @@ public class HandoverManager { mContext.bindServiceAsUser(new Intent(mContext, HandoverService.class), mConnection, Context.BIND_AUTO_CREATE, UserHandle.CURRENT); + mEnabled = true; } final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -214,6 +216,11 @@ public class HandoverManager { return new NdefRecord(NdefRecord.TNF_MIME_MEDIA, TYPE_BT_OOB, new byte[]{'b'}, payload); } + public void setEnabled(boolean enabled) { + synchronized (mLock) { + mEnabled = enabled; + } + } public boolean isHandoverSupported() { return (mBluetoothAdapter != null); } @@ -293,6 +300,8 @@ public class HandoverManager { // while waiting to receive a picture. boolean bluetoothActivating = !mBluetoothAdapter.isEnabled(); synchronized (mLock) { + if (!mEnabled) return null; + if (!mBound) { Log.e(TAG, "Could not connect to handover service"); return null; @@ -332,6 +341,8 @@ public class HandoverManager { if (!handover.valid) return true; synchronized (mLock) { + if (!mEnabled) return false; + if (mBluetoothAdapter == null) { if (DBG) Log.d(TAG, "BT handover, but BT not available"); return true; |