summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Pelly <npelly@google.com>2010-10-22 18:18:27 -0700
committerNick Pelly <npelly@google.com>2010-10-22 18:18:27 -0700
commit2f8ac1e6cdeb32569bc6477d53a2d0d5608758b1 (patch)
treea933513f0e1dc01536d32fbdba1f28d0df20211e
parentf348bf5b21c5c39d7b3627327db1e61007d07539 (diff)
downloadpackages_apps_nfc-2f8ac1e6cdeb32569bc6477d53a2d0d5608758b1.zip
packages_apps_nfc-2f8ac1e6cdeb32569bc6477d53a2d0d5608758b1.tar.gz
packages_apps_nfc-2f8ac1e6cdeb32569bc6477d53a2d0d5608758b1.tar.bz2
Start NFC service at Application load time.
- starting at app onCreate() is about 6 seconds before BOOT_COMPLETE - enable hardware immediately, but do not send any intents until BOOT_COMPLETE (using mBootComplete to guard). - add mutex's around some fields that needed it The fields that are still not thread-safe were non-trivial to fix. Change-Id: Id1c2bf535610ac594a33d84fe9a32d01d698a321 Signed-off-by: Nick Pelly <npelly@google.com>
-rwxr-xr-xAndroidManifest.xml14
-rwxr-xr-xsrc/com/android/nfc/NfcReceiver.java34
-rwxr-xr-xsrc/com/android/nfc/NfcService.java169
3 files changed, 92 insertions, 125 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6a817a7..860ded6 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -8,15 +8,9 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <application android:icon="@drawable/icon"
- android:label="@string/app_name"
- android:persistent="true" >
- <service android:name=".NfcService" >
- </service>
- <receiver android:name=".NfcReceiver" >
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
+ <application android:name=".NfcService"
+ android:icon="@drawable/icon"
+ android:label="@string/app_name"
+ android:persistent="true" >
</application>
</manifest>
diff --git a/src/com/android/nfc/NfcReceiver.java b/src/com/android/nfc/NfcReceiver.java
deleted file mode 100755
index 91dcce3..0000000
--- a/src/com/android/nfc/NfcReceiver.java
+++ /dev/null
@@ -1,34 +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 com.android.nfc;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.util.Log;
-
-public class NfcReceiver extends BroadcastReceiver {
- private static final String TAG = "NfcService";
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
- Log.i(TAG, "Starting NFC service");
-
- context.startService(new Intent(context, NfcService.class));
- }
- }
-}
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java
index 3524c18..98be432 100755
--- a/src/com/android/nfc/NfcService.java
+++ b/src/com/android/nfc/NfcService.java
@@ -20,7 +20,7 @@ import java.util.HashMap;
import java.util.LinkedList;
import java.util.ListIterator;
-import android.app.Service;
+import android.app.Application;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -42,13 +42,12 @@ import android.nfc.NdefTag;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
-public class NfcService extends Service {
+public class NfcService extends Application {
static {
System.loadLibrary("nfc_jni");
}
@@ -141,34 +140,24 @@ public class NfcService extends Service {
static final int MSG_LLCP_LINK_DEACTIVATED = 3;
static final int MSG_TARGET_DESELECTED = 4;
-
// TODO: none of these appear to be synchronized but are
// read/written from different threads (notably Binder threads)...
-
- private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
-
- private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
-
private final LinkedList<RegisteredSocket> mRegisteredSocketList = new LinkedList<RegisteredSocket>();
-
private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED;
-
private int mGeneratedSocketHandle = 0;
-
private int mNbSocketCreated = 0;
-
private volatile boolean mIsNfcEnabled = false;
-
private int mSelectedSeId = 0;
-
- private int mTimeout = 0;
-
- private boolean mNfcState;
-
private boolean mNfcSecureElementState;
-
private boolean mOpenPending = false;
+ // fields below are used in multiple threads and protected by synchronized(this)
+ private final HashMap<Integer, Object> mObjectMap = new HashMap<Integer, Object>();
+ private final HashMap<Integer, Object> mSocketMap = new HashMap<Integer, Object>();
+ private int mTimeout = 0;
+ private boolean mBootComplete = false;
+
+ // fields below are final after onCreate()
private Context mContext;
private NativeNfcManager mManager;
private SharedPreferences mPrefs;
@@ -176,6 +165,10 @@ public class NfcService extends Service {
@Override
public void onCreate() {
+ super.onCreate();
+
+ Log.i(TAG, "Starting NFC service");
+
mContext = this;
mManager = new NativeNfcManager(mContext, this);
mManager.initializeNativeStructure();
@@ -189,13 +182,9 @@ public class NfcService extends Service {
IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED);
filter.addAction(NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION);
+ filter.addAction(Intent.ACTION_BOOT_COMPLETED);
mContext.registerReceiver(mReceiver, filter);
- finishStartup();
- }
-
- public void finishStartup() {
- // runs at BOOT_COMPLETE time, can really turn on NFC now
Thread t = new Thread() {
@Override
public void run() {
@@ -209,17 +198,12 @@ public class NfcService extends Service {
}
@Override
- public void onDestroy() {
- // NFC service is persistent, it should not be destroyed by framework
+ public void onTerminate() {
+ super.onTerminate();
+ // NFC application is persistent, it should not be destroyed by framework
Log.wtf(TAG, "NFC service is under attack!");
}
- @Override
- public IBinder onBind(Intent intent) {
- // Applications should not attempt to bindService() to NFC service
- return null;
- }
-
private final INfcAdapter.Stub mNfcAdapter = new INfcAdapter.Stub() {
public boolean enable() throws RemoteException {
mContext.enforceCallingPermission(ADMIN_PERM, ADMIN_PERM_ERROR);
@@ -272,12 +256,13 @@ public class NfcService extends Service {
socket = mManager.doCreateLlcpConnectionlessSocket(sap);
if (socket != null) {
- /* Update the number of socket created */
- mNbSocketCreated++;
-
- /* Add the socket into the socket map */
- mSocketMap.put(sockeHandle, socket);
+ synchronized(NfcService.this) {
+ /* Update the number of socket created */
+ mNbSocketCreated++;
+ /* Add the socket into the socket map */
+ mSocketMap.put(sockeHandle, socket);
+ }
return sockeHandle;
} else {
/*
@@ -306,12 +291,13 @@ public class NfcService extends Service {
NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap);
- /* Add the socket into the socket map */
- mSocketMap.put(sockeHandle, socket);
-
- /* Update the number of socket created */
- mNbSocketCreated++;
+ synchronized(NfcService.this) {
+ /* Add the socket into the socket map */
+ mSocketMap.put(sockeHandle, socket);
+ /* Update the number of socket created */
+ mNbSocketCreated++;
+ }
/* Create new registered socket */
RegisteredSocket registeredSocket = new RegisteredSocket(
LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap);
@@ -349,10 +335,12 @@ public class NfcService extends Service {
socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
if (socket != null) {
- /* Update the number of socket created */
- mNbSocketCreated++;
- /* Add the socket into the socket map */
- mSocketMap.put(sockeHandle, socket);
+ synchronized(NfcService.this) {
+ /* Update the number of socket created */
+ mNbSocketCreated++;
+ /* Add the socket into the socket map */
+ mSocketMap.put(sockeHandle, socket);
+ }
} else {
/* socket creation error - update the socket handle counter */
mGeneratedSocketHandle -= 1;
@@ -387,13 +375,13 @@ public class NfcService extends Service {
}
NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sn);
+ synchronized(NfcService.this) {
+ /* Add the socket into the socket map */
+ mSocketMap.put(sockeHandle, socket);
- /* Add the socket into the socket map */
- mSocketMap.put(sockeHandle, socket);
-
- /* Update the number of socket created */
- mNbSocketCreated++;
-
+ /* Update the number of socket created */
+ mNbSocketCreated++;
+ }
/* Create new registered socket */
RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE,
sockeHandle, sap, sn, miu, rw, linearBufferLength);
@@ -432,10 +420,12 @@ public class NfcService extends Service {
socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
if (socket != null) {
- /* Update the number of socket created */
- mNbSocketCreated++;
- /* Add the socket into the socket map */
- mSocketMap.put(sockeHandle, socket);
+ synchronized(NfcService.this) {
+ /* Update the number of socket created */
+ mNbSocketCreated++;
+ /* Add the socket into the socket map */
+ mSocketMap.put(sockeHandle, socket);
+ }
} else {
/*
* socket creation error - update the socket handle
@@ -468,12 +458,13 @@ public class NfcService extends Service {
}
NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw);
+ synchronized(NfcService.this) {
+ /* Add the socket into the socket map */
+ mSocketMap.put(sockeHandle, socket);
- /* Add the socket into the socket map */
- mSocketMap.put(sockeHandle, socket);
-
- /* Update the number of socket created */
- mNbSocketCreated++;
+ /* Update the number of socket created */
+ mNbSocketCreated++;
+ }
/* Create new registered socket */
RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE,
sockeHandle, sap, miu, rw, linearBufferLength);
@@ -536,7 +527,7 @@ public class NfcService extends Service {
return mNfcTagService;
}
- public int getOpenTimeout() throws RemoteException {
+ public synchronized int getOpenTimeout() throws RemoteException {
mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
return mTimeout;
}
@@ -635,7 +626,7 @@ public class NfcService extends Service {
}
- public void setOpenTimeout(int timeout) throws RemoteException {
+ public synchronized void setOpenTimeout(int timeout) throws RemoteException {
mContext.enforceCallingPermission(NFC_PERM, NFC_PERM_ERROR);
mTimeout = timeout;
}
@@ -1089,8 +1080,10 @@ public class NfcService extends Service {
socket.getRw(), socket.getLinearBufferLength());
if (clientSocket != null) {
/* Add the socket into the socket map */
- mSocketMap.put(clientSocket.getHandle(), clientSocket);
- mNbSocketCreated++;
+ synchronized(this) {
+ mSocketMap.put(clientSocket.getHandle(), clientSocket);
+ mNbSocketCreated++;
+ }
return clientSocket.getHandle();
} else {
return ErrorCodes.ERROR_IO;
@@ -1738,15 +1731,17 @@ public class NfcService extends Service {
mPrefsEditor.putBoolean(PREF_NFC_ON, mIsNfcEnabled);
mPrefsEditor.apply();
- if (oldEnabledState != mIsNfcEnabled) {
- Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
- intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
- mContext.sendBroadcast(intent);
+ synchronized(this) {
+ if (mBootComplete && oldEnabledState != mIsNfcEnabled) {
+ Intent intent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
+ intent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
+ mContext.sendBroadcast(intent);
+ }
}
}
// Reset all internals
- private void reset() {
+ private synchronized void reset() {
// TODO: none of these appear to be synchronized but are
// read/written from different threads (notably Binder threads)...
@@ -1761,11 +1756,10 @@ public class NfcService extends Service {
mIsNfcEnabled = false;
mSelectedSeId = 0;
mTimeout = 0;
- mNfcState = false;
mOpenPending = false;
}
- private Object findObject(int key) {
+ private synchronized Object findObject(int key) {
Object device = null;
device = mObjectMap.get(key);
@@ -1776,15 +1770,15 @@ public class NfcService extends Service {
return device;
}
- void registerTagObject(NativeNfcTag nativeTag) {
+ synchronized void registerTagObject(NativeNfcTag nativeTag) {
mObjectMap.put(nativeTag.getHandle(), nativeTag);
}
- void unregisterObject(int handle) {
+ synchronized void unregisterObject(int handle) {
mObjectMap.remove(handle);
}
- private Object findSocket(int key) {
+ private synchronized Object findSocket(int key) {
Object socket = null;
socket = mSocketMap.get(key);
@@ -1916,7 +1910,9 @@ public class NfcService extends Service {
if (serviceSocket != null) {
/* Add the socket into the socket map */
- mSocketMap.put(registeredSocket.mHandle, serviceSocket);
+ synchronized(NfcService.this) {
+ mSocketMap.put(registeredSocket.mHandle, serviceSocket);
+ }
} else {
/* socket creation error - update the socket
* handle counter */
@@ -1932,7 +1928,9 @@ public class NfcService extends Service {
registeredSocket.mlinearBufferLength);
if (clientSocket != null) {
/* Add the socket into the socket map */
- mSocketMap.put(registeredSocket.mHandle, clientSocket);
+ synchronized(NfcService.this) {
+ mSocketMap.put(registeredSocket.mHandle, clientSocket);
+ }
} else {
/* socket creation error - update the socket
* handle counter */
@@ -1947,7 +1945,9 @@ public class NfcService extends Service {
registeredSocket.mSap);
if (connectionlessSocket != null) {
/* Add the socket into the socket map */
- mSocketMap.put(registeredSocket.mHandle, connectionlessSocket);
+ synchronized(NfcService.this) {
+ mSocketMap.put(registeredSocket.mHandle, connectionlessSocket);
+ }
} else {
/* socket creation error - update the socket
* handle counter */
@@ -2151,9 +2151,16 @@ public class NfcService extends Service {
mManager.enableDiscovery(DISCOVERY_MODE_READER);
} else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
- Log.i(TAG, "Completing NFC service startup");
+ Log.i(TAG, "Boot complete");
- finishStartup();
+ synchronized(this) {
+ mBootComplete = true;
+
+ // now its safe to send the NFC state
+ Intent sendIntent = new Intent(NfcAdapter.ACTION_ADAPTER_STATE_CHANGE);
+ sendIntent.putExtra(NfcAdapter.EXTRA_NEW_BOOLEAN_STATE, mIsNfcEnabled);
+ mContext.sendBroadcast(sendIntent);
+ }
}
}
};