summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2013-03-07 13:28:18 -0800
committerMartijn Coenen <maco@google.com>2013-03-07 16:59:41 -0800
commit7d8987f233985a5ff29226890e11012275d325f5 (patch)
treec8b8bab60f6988abb23af1ecc8e4d453ebeff1cd
parent696652d7f9faaffd198073cb75eb86156f7d9af4 (diff)
downloadandroid_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.xml27
-rw-r--r--src/com/android/nfc/NfcDispatcher.java46
-rwxr-xr-xsrc/com/android/nfc/NfcService.java60
-rw-r--r--src/com/android/nfc/handover/HandoverManager.java11
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;