blob: abfa133a2f395f45b86372cc016b064100ffdf30 [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
Mathew Inwood1961e1e2018-07-31 16:04:15 +010019import android.annotation.UnsupportedAppUsage;
Nick Pellyc84c89a2011-08-22 22:27:11 -070020import android.app.Activity;
Nick Pelly8ce7a272012-03-21 15:14:09 -070021import android.app.Application;
Andres Morales56f299b2014-10-31 08:26:33 -070022import android.content.ContentProvider;
Martijn Coenen7fe9fa12014-01-29 17:28:04 -080023import android.content.Intent;
Nick Pelly1d7e9062012-04-03 17:46:00 -070024import android.net.Uri;
Martijn Coenen5b1e0322013-09-02 20:38:47 -070025import android.nfc.NfcAdapter.ReaderCallback;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -070026import android.os.Binder;
Nick Pelly8ce7a272012-03-21 15:14:09 -070027import android.os.Bundle;
Nick Pellyc84c89a2011-08-22 22:27:11 -070028import android.os.RemoteException;
Andres Morales56f299b2014-10-31 08:26:33 -070029import android.os.UserHandle;
Nick Pellyc84c89a2011-08-22 22:27:11 -070030import android.util.Log;
31
Nick Pelly8ce7a272012-03-21 15:14:09 -070032import java.util.ArrayList;
33import java.util.LinkedList;
34import java.util.List;
Nick Pellyc84c89a2011-08-22 22:27:11 -070035
36/**
37 * Manages NFC API's that are coupled to the life-cycle of an Activity.
38 *
Nick Pelly8ce7a272012-03-21 15:14:09 -070039 * <p>Uses {@link Application#registerActivityLifecycleCallbacks} to hook
40 * into activity life-cycle events such as onPause() and onResume().
Nick Pellyc84c89a2011-08-22 22:27:11 -070041 *
42 * @hide
43 */
Martijn Coenen5b1e0322013-09-02 20:38:47 -070044public final class NfcActivityManager extends IAppCallback.Stub
Nick Pelly8ce7a272012-03-21 15:14:09 -070045 implements Application.ActivityLifecycleCallbacks {
Nick Pellyc84c89a2011-08-22 22:27:11 -070046 static final String TAG = NfcAdapter.TAG;
47 static final Boolean DBG = false;
48
Mathew Inwood1961e1e2018-07-31 16:04:15 +010049 @UnsupportedAppUsage
Nick Pellyc84c89a2011-08-22 22:27:11 -070050 final NfcAdapter mAdapter;
Nick Pelly8ce7a272012-03-21 15:14:09 -070051
52 // All objects in the lists are protected by this
53 final List<NfcApplicationState> mApps; // Application(s) that have NFC state. Usually one
54 final List<NfcActivityState> mActivities; // Activities that have NFC state
55
56 /**
57 * NFC State associated with an {@link Application}.
58 */
59 class NfcApplicationState {
60 int refCount = 0;
61 final Application app;
62 public NfcApplicationState(Application app) {
63 this.app = app;
64 }
65 public void register() {
66 refCount++;
67 if (refCount == 1) {
68 this.app.registerActivityLifecycleCallbacks(NfcActivityManager.this);
69 }
70 }
71 public void unregister() {
72 refCount--;
73 if (refCount == 0) {
74 this.app.unregisterActivityLifecycleCallbacks(NfcActivityManager.this);
75 } else if (refCount < 0) {
76 Log.e(TAG, "-ve refcount for " + app);
77 }
78 }
79 }
80
81 NfcApplicationState findAppState(Application app) {
82 for (NfcApplicationState appState : mApps) {
83 if (appState.app == app) {
84 return appState;
85 }
86 }
87 return null;
88 }
89
90 void registerApplication(Application app) {
91 NfcApplicationState appState = findAppState(app);
92 if (appState == null) {
93 appState = new NfcApplicationState(app);
94 mApps.add(appState);
95 }
96 appState.register();
97 }
98
99 void unregisterApplication(Application app) {
100 NfcApplicationState appState = findAppState(app);
101 if (appState == null) {
102 Log.e(TAG, "app was not registered " + app);
103 return;
104 }
105 appState.unregister();
106 }
Nick Pellyc84c89a2011-08-22 22:27:11 -0700107
108 /**
109 * NFC state associated with an {@link Activity}
110 */
111 class NfcActivityState {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700112 boolean resumed = false;
113 Activity activity;
114 NdefMessage ndefMessage = null; // static NDEF message
115 NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
116 NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700117 NfcAdapter.CreateBeamUrisCallback uriCallback = null;
118 Uri[] uris = null;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800119 int flags = 0;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700120 int readerModeFlags = 0;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700121 NfcAdapter.ReaderCallback readerCallback = null;
122 Bundle readerModeExtras = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700123 Binder token;
124
Nick Pelly8ce7a272012-03-21 15:14:09 -0700125 public NfcActivityState(Activity activity) {
126 if (activity.getWindow().isDestroyed()) {
127 throw new IllegalStateException("activity is already destroyed");
128 }
Martijn Coenen20fe5372012-04-05 10:50:05 -0700129 // Check if activity is resumed right now, as we will not
130 // immediately get a callback for that.
131 resumed = activity.isResumed();
132
Nick Pelly8ce7a272012-03-21 15:14:09 -0700133 this.activity = activity;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700134 this.token = new Binder();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700135 registerApplication(activity.getApplication());
136 }
137 public void destroy() {
138 unregisterApplication(activity.getApplication());
139 resumed = false;
140 activity = null;
141 ndefMessage = null;
142 ndefMessageCallback = null;
143 onNdefPushCompleteCallback = null;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700144 uriCallback = null;
145 uris = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700146 readerModeFlags = 0;
147 token = null;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700148 }
Nick Pellyc84c89a2011-08-22 22:27:11 -0700149 @Override
150 public String toString() {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700151 StringBuilder s = new StringBuilder("[").append(" ");
Nick Pellyc84c89a2011-08-22 22:27:11 -0700152 s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700153 s.append(uriCallback).append(" ");
154 if (uris != null) {
155 for (Uri uri : uris) {
156 s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
157 }
158 }
Nick Pellyc84c89a2011-08-22 22:27:11 -0700159 return s.toString();
160 }
161 }
162
Nick Pelly8ce7a272012-03-21 15:14:09 -0700163 /** find activity state from mActivities */
164 synchronized NfcActivityState findActivityState(Activity activity) {
165 for (NfcActivityState state : mActivities) {
166 if (state.activity == activity) {
167 return state;
168 }
169 }
170 return null;
Nick Pellyc84c89a2011-08-22 22:27:11 -0700171 }
172
Nick Pelly8ce7a272012-03-21 15:14:09 -0700173 /** find or create activity state from mActivities */
174 synchronized NfcActivityState getActivityState(Activity activity) {
175 NfcActivityState state = findActivityState(activity);
176 if (state == null) {
177 state = new NfcActivityState(activity);
178 mActivities.add(state);
Nick Pellyc84c89a2011-08-22 22:27:11 -0700179 }
180 return state;
181 }
182
Nick Pelly8ce7a272012-03-21 15:14:09 -0700183 synchronized NfcActivityState findResumedActivityState() {
184 for (NfcActivityState state : mActivities) {
185 if (state.resumed) {
186 return state;
187 }
188 }
189 return null;
190 }
191
192 synchronized void destroyActivityState(Activity activity) {
193 NfcActivityState activityState = findActivityState(activity);
194 if (activityState != null) {
195 activityState.destroy();
196 mActivities.remove(activityState);
197 }
198 }
199
200 public NfcActivityManager(NfcAdapter adapter) {
201 mAdapter = adapter;
202 mActivities = new LinkedList<NfcActivityState>();
203 mApps = new ArrayList<NfcApplicationState>(1); // Android VM usually has 1 app
Nick Pelly8ce7a272012-03-21 15:14:09 -0700204 }
205
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700206 public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
207 Bundle extras) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700208 boolean isResumed;
209 Binder token;
210 synchronized (NfcActivityManager.this) {
211 NfcActivityState state = getActivityState(activity);
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700212 state.readerCallback = callback;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700213 state.readerModeFlags = flags;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700214 state.readerModeExtras = extras;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700215 token = state.token;
216 isResumed = state.resumed;
217 }
218 if (isResumed) {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700219 setReaderMode(token, flags, extras);
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700220 }
221 }
222
223 public void disableReaderMode(Activity activity) {
224 boolean isResumed;
225 Binder token;
226 synchronized (NfcActivityManager.this) {
227 NfcActivityState state = getActivityState(activity);
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700228 state.readerCallback = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700229 state.readerModeFlags = 0;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700230 state.readerModeExtras = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700231 token = state.token;
232 isResumed = state.resumed;
233 }
234 if (isResumed) {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700235 setReaderMode(token, 0, null);
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700236 }
237
238 }
239
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700240 public void setReaderMode(Binder token, int flags, Bundle extras) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700241 if (DBG) Log.d(TAG, "Setting reader mode");
242 try {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700243 NfcAdapter.sService.setReaderMode(token, this, flags, extras);
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700244 } catch (RemoteException e) {
245 mAdapter.attemptDeadServiceRecovery(e);
246 }
247 }
248
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700249 public void setNdefPushContentUri(Activity activity, Uri[] uris) {
Nick Pelly1d7e9062012-04-03 17:46:00 -0700250 boolean isResumed;
251 synchronized (NfcActivityManager.this) {
252 NfcActivityState state = getActivityState(activity);
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700253 state.uris = uris;
254 isResumed = state.resumed;
255 }
256 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800257 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800258 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800259 } else {
260 // Crash API calls early in case NFC permission is missing
261 verifyNfcPermission();
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700262 }
263 }
264
265
266 public void setNdefPushContentUriCallback(Activity activity,
267 NfcAdapter.CreateBeamUrisCallback callback) {
268 boolean isResumed;
269 synchronized (NfcActivityManager.this) {
270 NfcActivityState state = getActivityState(activity);
271 state.uriCallback = callback;
Nick Pelly1d7e9062012-04-03 17:46:00 -0700272 isResumed = state.resumed;
273 }
274 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800275 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800276 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800277 } else {
278 // Crash API calls early in case NFC permission is missing
279 verifyNfcPermission();
Nick Pelly1d7e9062012-04-03 17:46:00 -0700280 }
281 }
282
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800283 public void setNdefPushMessage(Activity activity, NdefMessage message, int flags) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700284 boolean isResumed;
285 synchronized (NfcActivityManager.this) {
286 NfcActivityState state = getActivityState(activity);
287 state.ndefMessage = message;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800288 state.flags = flags;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700289 isResumed = state.resumed;
290 }
291 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800292 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800293 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800294 } else {
295 // Crash API calls early in case NFC permission is missing
296 verifyNfcPermission();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700297 }
298 }
299
300 public void setNdefPushMessageCallback(Activity activity,
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800301 NfcAdapter.CreateNdefMessageCallback callback, int flags) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700302 boolean isResumed;
303 synchronized (NfcActivityManager.this) {
304 NfcActivityState state = getActivityState(activity);
305 state.ndefMessageCallback = callback;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800306 state.flags = flags;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700307 isResumed = state.resumed;
308 }
309 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800310 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800311 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800312 } else {
313 // Crash API calls early in case NFC permission is missing
314 verifyNfcPermission();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700315 }
316 }
317
318 public void setOnNdefPushCompleteCallback(Activity activity,
319 NfcAdapter.OnNdefPushCompleteCallback callback) {
320 boolean isResumed;
321 synchronized (NfcActivityManager.this) {
322 NfcActivityState state = getActivityState(activity);
323 state.onNdefPushCompleteCallback = callback;
324 isResumed = state.resumed;
325 }
326 if (isResumed) {
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800327 // requestNfcServiceCallback() verifies permission also
Martijn Coenen1360c552013-01-07 16:34:20 -0800328 requestNfcServiceCallback();
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800329 } else {
330 // Crash API calls early in case NFC permission is missing
331 verifyNfcPermission();
Nick Pellyc84c89a2011-08-22 22:27:11 -0700332 }
333 }
334
335 /**
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700336 * Request or unrequest NFC service callbacks.
Nick Pelly8ce7a272012-03-21 15:14:09 -0700337 * Makes IPC call - do not hold lock.
Nick Pellyc84c89a2011-08-22 22:27:11 -0700338 */
Martijn Coenen1360c552013-01-07 16:34:20 -0800339 void requestNfcServiceCallback() {
Nick Pellyc84c89a2011-08-22 22:27:11 -0700340 try {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700341 NfcAdapter.sService.setAppCallback(this);
Nick Pellyc84c89a2011-08-22 22:27:11 -0700342 } catch (RemoteException e) {
343 mAdapter.attemptDeadServiceRecovery(e);
344 }
345 }
346
Martijn Coenend8bcfba2014-11-13 15:00:56 -0800347 void verifyNfcPermission() {
348 try {
349 NfcAdapter.sService.verifyNfcPermission();
350 } catch (RemoteException e) {
351 mAdapter.attemptDeadServiceRecovery(e);
352 }
353 }
354
Nick Pelly8ce7a272012-03-21 15:14:09 -0700355 /** Callback from NFC service, usually on binder thread */
Nick Pellyc84c89a2011-08-22 22:27:11 -0700356 @Override
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200357 public BeamShareData createBeamShareData(byte peerLlcpVersion) {
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800358 NfcAdapter.CreateNdefMessageCallback ndefCallback;
359 NfcAdapter.CreateBeamUrisCallback urisCallback;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700360 NdefMessage message;
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800361 Activity activity;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700362 Uri[] uris;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800363 int flags;
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200364 NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
Nick Pelly1d7e9062012-04-03 17:46:00 -0700365 synchronized (NfcActivityManager.this) {
366 NfcActivityState state = findResumedActivityState();
367 if (state == null) return null;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800368
369 ndefCallback = state.ndefMessageCallback;
370 urisCallback = state.uriCallback;
371 message = state.ndefMessage;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700372 uris = state.uris;
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800373 flags = state.flags;
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800374 activity = state.activity;
Martijn Coenen20e8dd92012-04-12 16:37:18 -0700375 }
Martijn Coenen24584f02015-12-21 11:29:45 +0100376 final long ident = Binder.clearCallingIdentity();
377 try {
378 // Make callbacks without lock
379 if (ndefCallback != null) {
380 message = ndefCallback.createNdefMessage(event);
381 }
382 if (urisCallback != null) {
383 uris = urisCallback.createBeamUris(event);
384 if (uris != null) {
385 ArrayList<Uri> validUris = new ArrayList<Uri>();
386 for (Uri uri : uris) {
387 if (uri == null) {
388 Log.e(TAG, "Uri not allowed to be null.");
389 continue;
390 }
391 String scheme = uri.getScheme();
392 if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
393 !scheme.equalsIgnoreCase("content"))) {
394 Log.e(TAG, "Uri needs to have " +
395 "either scheme file or scheme content");
396 continue;
397 }
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700398 uri = ContentProvider.maybeAddUserId(uri, activity.getUserId());
Martijn Coenen24584f02015-12-21 11:29:45 +0100399 validUris.add(uri);
400 }
Martijn Coenen1fa2aff2013-02-27 09:21:22 -0800401
Martijn Coenen24584f02015-12-21 11:29:45 +0100402 uris = validUris.toArray(new Uri[validUris.size()]);
Martijn Coenen2c103112012-05-15 10:32:15 -0700403 }
404 }
Martijn Coenen24584f02015-12-21 11:29:45 +0100405 if (uris != null && uris.length > 0) {
406 for (Uri uri : uris) {
407 // Grant the NFC process permission to read these URIs
408 activity.grantUriPermission("com.android.nfc", uri,
409 Intent.FLAG_GRANT_READ_URI_PERMISSION);
410 }
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800411 }
Martijn Coenen24584f02015-12-21 11:29:45 +0100412 } finally {
413 Binder.restoreCallingIdentity(ident);
Martijn Coenen7fe9fa12014-01-29 17:28:04 -0800414 }
Jeff Sharkeyad357d12018-02-02 13:25:31 -0700415 return new BeamShareData(message, uris, activity.getUser(), flags);
Nick Pelly1d7e9062012-04-03 17:46:00 -0700416 }
Nick Pelly1d7e9062012-04-03 17:46:00 -0700417
Nick Pelly1d7e9062012-04-03 17:46:00 -0700418 /** Callback from NFC service, usually on binder thread */
419 @Override
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200420 public void onNdefPushComplete(byte peerLlcpVersion) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700421 NfcAdapter.OnNdefPushCompleteCallback callback;
Nick Pellyc84c89a2011-08-22 22:27:11 -0700422 synchronized (NfcActivityManager.this) {
Nick Pelly8ce7a272012-03-21 15:14:09 -0700423 NfcActivityState state = findResumedActivityState();
424 if (state == null) return;
425
426 callback = state.onNdefPushCompleteCallback;
Nick Pellyc84c89a2011-08-22 22:27:11 -0700427 }
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200428 NfcEvent event = new NfcEvent(mAdapter, peerLlcpVersion);
Nick Pelly8ce7a272012-03-21 15:14:09 -0700429 // Make callback without lock
Nick Pellyc84c89a2011-08-22 22:27:11 -0700430 if (callback != null) {
Martijn Coenenfd70bb12015-04-14 11:38:21 +0200431 callback.onNdefPushComplete(event);
Nick Pellyc84c89a2011-08-22 22:27:11 -0700432 }
433 }
Martijn Coenen3433a8a2011-09-01 19:18:02 -0700434
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700435 @Override
436 public void onTagDiscovered(Tag tag) throws RemoteException {
437 NfcAdapter.ReaderCallback callback;
438 synchronized (NfcActivityManager.this) {
439 NfcActivityState state = findResumedActivityState();
440 if (state == null) return;
441
442 callback = state.readerCallback;
443 }
444
445 // Make callback without lock
446 if (callback != null) {
447 callback.onTagDiscovered(tag);
448 }
449
450 }
Nick Pelly8ce7a272012-03-21 15:14:09 -0700451 /** Callback from Activity life-cycle, on main thread */
452 @Override
453 public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
454
455 /** Callback from Activity life-cycle, on main thread */
456 @Override
457 public void onActivityStarted(Activity activity) { /* NO-OP */ }
458
459 /** Callback from Activity life-cycle, on main thread */
460 @Override
461 public void onActivityResumed(Activity activity) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700462 int readerModeFlags = 0;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700463 Bundle readerModeExtras = null;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700464 Binder token;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700465 synchronized (NfcActivityManager.this) {
466 NfcActivityState state = findActivityState(activity);
467 if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
468 if (state == null) return;
469 state.resumed = true;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700470 token = state.token;
471 readerModeFlags = state.readerModeFlags;
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700472 readerModeExtras = state.readerModeExtras;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700473 }
474 if (readerModeFlags != 0) {
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700475 setReaderMode(token, readerModeFlags, readerModeExtras);
Nick Pelly8ce7a272012-03-21 15:14:09 -0700476 }
Martijn Coenen1360c552013-01-07 16:34:20 -0800477 requestNfcServiceCallback();
Nick Pelly8ce7a272012-03-21 15:14:09 -0700478 }
479
480 /** Callback from Activity life-cycle, on main thread */
481 @Override
482 public void onActivityPaused(Activity activity) {
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700483 boolean readerModeFlagsSet;
484 Binder token;
Nick Pelly8ce7a272012-03-21 15:14:09 -0700485 synchronized (NfcActivityManager.this) {
486 NfcActivityState state = findActivityState(activity);
487 if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
488 if (state == null) return;
489 state.resumed = false;
Martijn Coenenc20ed2f2013-08-27 14:32:53 -0700490 token = state.token;
491 readerModeFlagsSet = state.readerModeFlags != 0;
492 }
493 if (readerModeFlagsSet) {
494 // Restore default p2p modes
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700495 setReaderMode(token, 0, null);
Nick Pelly8ce7a272012-03-21 15:14:09 -0700496 }
Nick Pelly8ce7a272012-03-21 15:14:09 -0700497 }
498
499 /** Callback from Activity life-cycle, on main thread */
500 @Override
501 public void onActivityStopped(Activity activity) { /* NO-OP */ }
502
503 /** Callback from Activity life-cycle, on main thread */
504 @Override
505 public void onActivitySaveInstanceState(Activity activity, Bundle outState) { /* NO-OP */ }
506
507 /** Callback from Activity life-cycle, on main thread */
508 @Override
509 public void onActivityDestroyed(Activity activity) {
510 synchronized (NfcActivityManager.this) {
511 NfcActivityState state = findActivityState(activity);
512 if (DBG) Log.d(TAG, "onDestroy() for " + activity + " " + state);
513 if (state != null) {
514 // release all associated references
515 destroyActivityState(activity);
516 }
517 }
518 }
Martijn Coenen5b1e0322013-09-02 20:38:47 -0700519
Nick Pellyc84c89a2011-08-22 22:27:11 -0700520}