blob: c7d4c65d99c0dfbdffd712c8b01cd10195626439 [file] [log] [blame]
Nick Pellyc84c89a2011-08-22 22:27:11 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.nfc;
18
19import android.app.Activity;
Nick Pelly8ce7a272012-03-21 15:14:09 -070020import android.app.Application;
Andres Morales56f299b2014-10-31 08:26:33 -070021import android.content.ContentProvider;
Martijn Coenen7fe9fa12014-01-29 17:28:04 -080022import android.content.Intent;
Nick Pelly1d7e9062012-04-03 17:46:00 -070023import android.net.Uri;
Martijn Coenen5b1e0322013-09-02 20:38:47 -070024import android.nfc.NfcAdapter.ReaderCallback;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -070025import android.os.Binder;
Nick Pelly8ce7a272012-03-21 15:14:09 -070026import android.os.Bundle;
Nick Pellyc84c89a2011-08-22 22:27:11 -070027import android.os.RemoteException;
Andres Morales56f299b2014-10-31 08:26:33 -070028import android.os.UserHandle;
Nick Pellyc84c89a2011-08-22 22:27:11 -070029import android.util.Log;
30
Nick Pelly8ce7a272012-03-21 15:14:09 -070031import java.util.ArrayList;
32import java.util.LinkedList;
33import java.util.List;
Nick Pellyc84c89a2011-08-22 22:27:11 -070034
35/**
36 * Manages NFC API's that are coupled to the life-cycle of an Activity.
37 *
Nick Pelly8ce7a272012-03-21 15:14:09 -070038 * <p>Uses {@link Application#registerActivityLifecycleCallbacks} to hook
39 * into activity life-cycle events such as onPause() and onResume().
Nick Pellyc84c89a2011-08-22 22:27:11 -070040 *
41 * @hide
42 */
Martijn Coenen5b1e0322013-09-02 20:38:47 -070043public final class NfcActivityManager extends IAppCallback.Stub
Nick Pelly8ce7a272012-03-21 15:14:09 -070044 implements Application.ActivityLifecycleCallbacks {
Nick Pellyc84c89a2011-08-22 22:27:11 -070045 static final String TAG = NfcAdapter.TAG;
46 static final Boolean DBG = false;
47
48 final NfcAdapter mAdapter;
Nick Pelly8ce7a272012-03-21 15:14:09 -070049
50 // All objects in the lists are protected by this
51 final List<NfcApplicationState> mApps; // Application(s) that have NFC state. Usually one
52 final List<NfcActivityState> mActivities; // Activities that have NFC state
53
54 /**
55 * NFC State associated with an {@link Application}.
56 */
57 class NfcApplicationState {
58 int refCount = 0;
59 final Application app;
60 public NfcApplicationState(Application app) {
61 this.app = app;
62 }
63 public void register() {
64 refCount++;
65 if (refCount == 1) {
66 this.app.registerActivityLifecycleCallbacks(NfcActivityManager.this);
67 }
68 }
69 public void unregister() {
70 refCount--;
71 if (refCount == 0) {
72 this.app.unregisterActivityLifecycleCallbacks(NfcActivityManager.this);
73 } else if (refCount < 0) {
74 Log.e(TAG, "-ve refcount for " + app);
75 }
76 }
77 }
78
79 NfcApplicationState findAppState(Application app) {
80 for (NfcApplicationState appState : mApps) {
81 if (appState.app == app) {
82 return appState;
83 }
84 }
85 return null;
86 }
87
88 void registerApplication(Application app) {
89 NfcApplicationState appState = findAppState(app);
90 if (appState == null) {
91 appState = new NfcApplicationState(app);
92 mApps.add(appState);
93 }
94 appState.register();
95 }
96
97 void unregisterApplication(Application app) {
98 NfcApplicationState appState = findAppState(app);
99 if (appState == null) {
100 Log.e(TAG, "app was not registered " + app);
101 return;
102 }
103 appState.unregister();
104 }
Nick Pellyc84c89a2011-08-22 22:27:11 -0700105
106 /**
107 * NFC state associated with an {@link Activity}
108 */
109 class NfcActivityState {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700110 boolean resumed = false;
111 Activity activity;
112 NdefMessage ndefMessage = null; // static NDEF message
113 NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
114 NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700115 NfcAdapter.CreateBeamUrisCallback uriCallback = null;
116 Uri[] uris = null;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800117 int flags = 0;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700118 int readerModeFlags = 0;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700119 NfcAdapter.ReaderCallback readerCallback = null;
120 Bundle readerModeExtras = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700121 Binder token;
122
Nick Pelly8ce7a272012-03-21 15:14:09 -0700123 public NfcActivityState(Activity activity) {
124 if (activity.getWindow().isDestroyed()) {
125 throw new IllegalStateException("activity is already destroyed");
126 }
Martijn Coenen20fe5372012-04-05 10:50:05 -0700127 // Check if activity is resumed right now, as we will not
128 // immediately get a callback for that.
129 resumed = activity.isResumed();
130
Nick Pelly8ce7a272012-03-21 15:14:09 -0700131 this.activity = activity;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700132 this.token = new Binder();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700133 registerApplication(activity.getApplication());
134 }
135 public void destroy() {
136 unregisterApplication(activity.getApplication());
137 resumed = false;
138 activity = null;
139 ndefMessage = null;
140 ndefMessageCallback = null;
141 onNdefPushCompleteCallback = null;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700142 uriCallback = null;
143 uris = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700144 readerModeFlags = 0;
145 token = null;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700146 }
Nick Pellyc84c89a2011-08-22 22:27:11 -0700147 @Override
148 public String toString() {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700149 StringBuilder s = new StringBuilder("[").append(" ");
Nick Pellyc84c89a2011-08-22 22:27:11 -0700150 s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700151 s.append(uriCallback).append(" ");
152 if (uris != null) {
153 for (Uri uri : uris) {
154 s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
155 }
156 }
Nick Pellyc84c89a2011-08-22 22:27:11 -0700157 return s.toString();
158 }
159 }
160
Nick Pelly8ce7a272012-03-21 15:14:09 -0700161 /** find activity state from mActivities */
162 synchronized NfcActivityState findActivityState(Activity activity) {
163 for (NfcActivityState state : mActivities) {
164 if (state.activity == activity) {
165 return state;
166 }
167 }
168 return null;
Nick Pellyc84c89a2011-08-22 22:27:11 -0700169 }
170
Nick Pelly8ce7a272012-03-21 15:14:09 -0700171 /** find or create activity state from mActivities */
172 synchronized NfcActivityState getActivityState(Activity activity) {
173 NfcActivityState state = findActivityState(activity);
174 if (state == null) {
175 state = new NfcActivityState(activity);
176 mActivities.add(state);
Nick Pellyc84c89a2011-08-22 22:27:11 -0700177 }
178 return state;
179 }
180
Nick Pelly8ce7a272012-03-21 15:14:09 -0700181 synchronized NfcActivityState findResumedActivityState() {
182 for (NfcActivityState state : mActivities) {
183 if (state.resumed) {
184 return state;
185 }
186 }
187 return null;
188 }
189
190 synchronized void destroyActivityState(Activity activity) {
191 NfcActivityState activityState = findActivityState(activity);
192 if (activityState != null) {
193 activityState.destroy();
194 mActivities.remove(activityState);
195 }
196 }
197
198 public NfcActivityManager(NfcAdapter adapter) {
199 mAdapter = adapter;
200 mActivities = new LinkedList<NfcActivityState>();
201 mApps = new ArrayList<NfcApplicationState>(1); // Android VM usually has 1 app
Nick Pelly8ce7a272012-03-21 15:14:09 -0700202 }
203
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700204 public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
205 Bundle extras) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700206 boolean isResumed;
207 Binder token;
208 synchronized (NfcActivityManager.this) {
209 NfcActivityState state = getActivityState(activity);
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700210 state.readerCallback = callback;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700211 state.readerModeFlags = flags;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700212 state.readerModeExtras = extras;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700213 token = state.token;
214 isResumed = state.resumed;
215 }
216 if (isResumed) {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700217 setReaderMode(token, flags, extras);
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700218 }
219 }
220
221 public void disableReaderMode(Activity activity) {
222 boolean isResumed;
223 Binder token;
224 synchronized (NfcActivityManager.this) {
225 NfcActivityState state = getActivityState(activity);
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700226 state.readerCallback = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700227 state.readerModeFlags = 0;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700228 state.readerModeExtras = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700229 token = state.token;
230 isResumed = state.resumed;
231 }
232 if (isResumed) {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700233 setReaderMode(token, 0, null);
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700234 }
235
236 }
237
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700238 public void setReaderMode(Binder token, int flags, Bundle extras) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700239 if (DBG) Log.d(TAG, "Setting reader mode");
240 try {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700241 NfcAdapter.sService.setReaderMode(token, this, flags, extras);
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700242 } catch (RemoteException e) {
243 mAdapter.attemptDeadServiceRecovery(e);
244 }
245 }
246
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700247 public void setNdefPushContentUri(Activity activity, Uri[] uris) {
Nick Pelly1d7e9062012-04-03 17:46:00 -0700248 boolean isResumed;
249 synchronized (NfcActivityManager.this) {
250 NfcActivityState state = getActivityState(activity);
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700251 state.uris = uris;
252 isResumed = state.resumed;
253 }
254 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800255 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800256 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800257 } else {
258 // Crash API calls early in case NFC permission is missing
259 verifyNfcPermission();
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700260 }
261 }
262
263
264 public void setNdefPushContentUriCallback(Activity activity,
265 NfcAdapter.CreateBeamUrisCallback callback) {
266 boolean isResumed;
267 synchronized (NfcActivityManager.this) {
268 NfcActivityState state = getActivityState(activity);
269 state.uriCallback = callback;
Nick Pelly1d7e9062012-04-03 17:46:00 -0700270 isResumed = state.resumed;
271 }
272 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800273 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800274 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800275 } else {
276 // Crash API calls early in case NFC permission is missing
277 verifyNfcPermission();
Nick Pelly1d7e9062012-04-03 17:46:00 -0700278 }
279 }
280
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800281 public void setNdefPushMessage(Activity activity, NdefMessage message, int flags) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700282 boolean isResumed;
283 synchronized (NfcActivityManager.this) {
284 NfcActivityState state = getActivityState(activity);
285 state.ndefMessage = message;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800286 state.flags = flags;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700287 isResumed = state.resumed;
288 }
289 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800290 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800291 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800292 } else {
293 // Crash API calls early in case NFC permission is missing
294 verifyNfcPermission();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700295 }
296 }
297
298 public void setNdefPushMessageCallback(Activity activity,
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800299 NfcAdapter.CreateNdefMessageCallback callback, int flags) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700300 boolean isResumed;
301 synchronized (NfcActivityManager.this) {
302 NfcActivityState state = getActivityState(activity);
303 state.ndefMessageCallback = callback;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800304 state.flags = flags;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700305 isResumed = state.resumed;
306 }
307 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800308 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800309 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800310 } else {
311 // Crash API calls early in case NFC permission is missing
312 verifyNfcPermission();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700313 }
314 }
315
316 public void setOnNdefPushCompleteCallback(Activity activity,
317 NfcAdapter.OnNdefPushCompleteCallback callback) {
318 boolean isResumed;
319 synchronized (NfcActivityManager.this) {
320 NfcActivityState state = getActivityState(activity);
321 state.onNdefPushCompleteCallback = callback;
322 isResumed = state.resumed;
323 }
324 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800325 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800326 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800327 } else {
328 // Crash API calls early in case NFC permission is missing
329 verifyNfcPermission();
Nick Pellyc84c89a2011-08-22 22:27:11 -0700330 }
331 }
332
333 /**
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700334 * Request or unrequest NFC service callbacks.
Nick Pelly8ce7a272012-03-21 15:14:09 -0700335 * Makes IPC call - do not hold lock.
Nick Pellyc84c89a2011-08-22 22:27:11 -0700336 */
Martijn Coenen1360c552013-01-07 16:34:20 -0800337 void requestNfcServiceCallback() {
Nick Pellyc84c89a2011-08-22 22:27:11 -0700338 try {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700339 NfcAdapter.sService.setAppCallback(this);
Nick Pellyc84c89a2011-08-22 22:27:11 -0700340 } catch (RemoteException e) {
341 mAdapter.attemptDeadServiceRecovery(e);
342 }
343 }
344
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800345 void verifyNfcPermission() {
346 try {
347 NfcAdapter.sService.verifyNfcPermission();
348 } catch (RemoteException e) {
349 mAdapter.attemptDeadServiceRecovery(e);
350 }
351 }
352
Nick Pelly8ce7a272012-03-21 15:14:09 -0700353 /** Callback from NFC service, usually on binder thread */
Nick Pellyc84c89a2011-08-22 22:27:11 -0700354 @Override
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200355 public BeamShareData createBeamShareData(byte peerLlcpVersion) {
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800356 NfcAdapter.CreateNdefMessageCallback ndefCallback;
357 NfcAdapter.CreateBeamUrisCallback urisCallback;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700358 NdefMessage message;
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800359 Activity activity;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700360 Uri[] uris;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800361 int flags;
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200362 NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
Nick Pelly1d7e9062012-04-03 17:46:00 -0700363 synchronized (NfcActivityManager.this) {
364 NfcActivityState state = findResumedActivityState();
365 if (state == null) return null;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800366
367 ndefCallback = state.ndefMessageCallback;
368 urisCallback = state.uriCallback;
369 message = state.ndefMessage;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700370 uris = state.uris;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800371 flags = state.flags;
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800372 activity = state.activity;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700373 }
Martijn Coenen24584f02015-12-21 11:29:45 +0100374 final long ident = Binder.clearCallingIdentity();
375 try {
376 // Make callbacks without lock
377 if (ndefCallback != null) {
378 message = ndefCallback.createNdefMessage(event);
379 }
380 if (urisCallback != null) {
381 uris = urisCallback.createBeamUris(event);
382 if (uris != null) {
383 ArrayList<Uri> validUris = new ArrayList<Uri>();
384 for (Uri uri : uris) {
385 if (uri == null) {
386 Log.e(TAG, "Uri not allowed to be null.");
387 continue;
388 }
389 String scheme = uri.getScheme();
390 if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
391 !scheme.equalsIgnoreCase("content"))) {
392 Log.e(TAG, "Uri needs to have " +
393 "either scheme file or scheme content");
394 continue;
395 }
396 uri = ContentProvider.maybeAddUserId(uri, UserHandle.myUserId());
397 validUris.add(uri);
398 }
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800399
Martijn Coenen24584f02015-12-21 11:29:45 +0100400 uris = validUris.toArray(new Uri[validUris.size()]);
Martijn Coenen2c103112012-05-15 10:32:15 -0700401 }
402 }
Martijn Coenen24584f02015-12-21 11:29:45 +0100403 if (uris != null && uris.length > 0) {
404 for (Uri uri : uris) {
405 // Grant the NFC process permission to read these URIs
406 activity.grantUriPermission("com.android.nfc", uri,
407 Intent.FLAG_GRANT_READ_URI_PERMISSION);
408 }
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800409 }
Martijn Coenen24584f02015-12-21 11:29:45 +0100410 } finally {
411 Binder.restoreCallingIdentity(ident);
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800412 }
Nicolas Prevot81b7b102015-07-01 12:25:43 +0100413 return new BeamShareData(message, uris, new UserHandle(UserHandle.myUserId()), flags);
Nick Pelly1d7e9062012-04-03 17:46:00 -0700414 }
Nick Pelly1d7e9062012-04-03 17:46:00 -0700415
Nick Pelly1d7e9062012-04-03 17:46:00 -0700416 /** Callback from NFC service, usually on binder thread */
417 @Override
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200418 public void onNdefPushComplete(byte peerLlcpVersion) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700419 NfcAdapter.OnNdefPushCompleteCallback callback;
Nick Pellyc84c89a2011-08-22 22:27:11 -0700420 synchronized (NfcActivityManager.this) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700421 NfcActivityState state = findResumedActivityState();
422 if (state == null) return;
423
424 callback = state.onNdefPushCompleteCallback;
Nick Pellyc84c89a2011-08-22 22:27:11 -0700425 }
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200426 NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
Nick Pelly8ce7a272012-03-21 15:14:09 -0700427 // Make callback without lock
Nick Pellyc84c89a2011-08-22 22:27:11 -0700428 if (callback != null) {
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200429 callback.onNdefPushComplete(event);
Nick Pellyc84c89a2011-08-22 22:27:11 -0700430 }
431 }
Martijn Coenen3433a8a2011-09-01 19:18:02 -0700432
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700433 @Override
434 public void onTagDiscovered(Tag tag) throws RemoteException {
435 NfcAdapter.ReaderCallback callback;
436 synchronized (NfcActivityManager.this) {
437 NfcActivityState state = findResumedActivityState();
438 if (state == null) return;
439
440 callback = state.readerCallback;
441 }
442
443 // Make callback without lock
444 if (callback != null) {
445 callback.onTagDiscovered(tag);
446 }
447
448 }
Nick Pelly8ce7a272012-03-21 15:14:09 -0700449 /** Callback from Activity life-cycle, on main thread */
450 @Override
451 public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
452
453 /** Callback from Activity life-cycle, on main thread */
454 @Override
455 public void onActivityStarted(Activity activity) { /* NO-OP */ }
456
457 /** Callback from Activity life-cycle, on main thread */
458 @Override
459 public void onActivityResumed(Activity activity) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700460 int readerModeFlags = 0;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700461 Bundle readerModeExtras = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700462 Binder token;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700463 synchronized (NfcActivityManager.this) {
464 NfcActivityState state = findActivityState(activity);
465 if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
466 if (state == null) return;
467 state.resumed = true;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700468 token = state.token;
469 readerModeFlags = state.readerModeFlags;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700470 readerModeExtras = state.readerModeExtras;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700471 }
472 if (readerModeFlags != 0) {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700473 setReaderMode(token, readerModeFlags, readerModeExtras);
Nick Pelly8ce7a272012-03-21 15:14:09 -0700474 }
Martijn Coenen1360c552013-01-07 16:34:20 -0800475 requestNfcServiceCallback();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700476 }
477
478 /** Callback from Activity life-cycle, on main thread */
479 @Override
480 public void onActivityPaused(Activity activity) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700481 boolean readerModeFlagsSet;
482 Binder token;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700483 synchronized (NfcActivityManager.this) {
484 NfcActivityState state = findActivityState(activity);
485 if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
486 if (state == null) return;
487 state.resumed = false;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700488 token = state.token;
489 readerModeFlagsSet = state.readerModeFlags != 0;
490 }
491 if (readerModeFlagsSet) {
492 // Restore default p2p modes
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700493 setReaderMode(token, 0, null);
Nick Pelly8ce7a272012-03-21 15:14:09 -0700494 }
Nick Pelly8ce7a272012-03-21 15:14:09 -0700495 }
496
497 /** Callback from Activity life-cycle, on main thread */
498 @Override
499 public void onActivityStopped(Activity activity) { /* NO-OP */ }
500
501 /** Callback from Activity life-cycle, on main thread */
502 @Override
503 public void onActivitySaveInstanceState(Activity activity, Bundle outState) { /* NO-OP */ }
504
505 /** Callback from Activity life-cycle, on main thread */
506 @Override
507 public void onActivityDestroyed(Activity activity) {
508 synchronized (NfcActivityManager.this) {
509 NfcActivityState state = findActivityState(activity);
510 if (DBG) Log.d(TAG, "onDestroy() for " + activity + " " + state);
511 if (state != null) {
512 // release all associated references
513 destroyActivityState(activity);
514 }
515 }
516 }
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700517
Nick Pellyc84c89a2011-08-22 22:27:11 -0700518}