1c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly/*
2c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Copyright (C) 2011 The Android Open Source Project
3c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly *
4c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
5c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * you may not use this file except in compliance with the License.
6c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * You may obtain a copy of the License at
7c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly *
8c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
9c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly *
10c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Unless required by applicable law or agreed to in writing, software
11c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
12c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * See the License for the specific language governing permissions and
14c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * limitations under the License.
15c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */
16c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
17c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pellypackage android.nfc;
18c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
19c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pellyimport android.app.Activity;
208ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pellyimport android.app.Application;
211d7e9062330a5a02247752de32a68ecbeba82783Nick Pellyimport android.net.Uri;
225b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenenimport android.nfc.NfcAdapter.ReaderCallback;
23c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenenimport android.os.Binder;
248ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pellyimport android.os.Bundle;
25c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pellyimport android.os.RemoteException;
26c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pellyimport android.util.Log;
27c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
288ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pellyimport java.util.ArrayList;
298ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pellyimport java.util.LinkedList;
308ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pellyimport java.util.List;
31c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
32c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly/**
33c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * Manages NFC API's that are coupled to the life-cycle of an Activity.
34c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly *
358ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * <p>Uses {@link Application#registerActivityLifecycleCallbacks} to hook
368ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly * into activity life-cycle events such as onPause() and onResume().
37c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly *
38c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly * @hide
39c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly */
405b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenenpublic final class NfcActivityManager extends IAppCallback.Stub
418ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        implements Application.ActivityLifecycleCallbacks {
42c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    static final String TAG = NfcAdapter.TAG;
43c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    static final Boolean DBG = false;
44c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
45c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    final NfcAdapter mAdapter;
468ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    final NfcEvent mDefaultEvent;  // cached NfcEvent (its currently always the same)
478ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
488ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    // All objects in the lists are protected by this
498ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    final List<NfcApplicationState> mApps;  // Application(s) that have NFC state. Usually one
508ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    final List<NfcActivityState> mActivities;  // Activities that have NFC state
51c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
52c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    /**
538ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly     * NFC State associated with an {@link Application}.
54c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly     */
558ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    class NfcApplicationState {
568ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        int refCount = 0;
578ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        final Application app;
588ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        public NfcApplicationState(Application app) {
598ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            this.app = app;
608ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
618ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        public void register() {
628ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            refCount++;
638ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (refCount == 1) {
648ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                this.app.registerActivityLifecycleCallbacks(NfcActivityManager.this);
658ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            }
668ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
678ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        public void unregister() {
688ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            refCount--;
698ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (refCount == 0) {
708ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                this.app.unregisterActivityLifecycleCallbacks(NfcActivityManager.this);
718ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            } else if (refCount < 0) {
728ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                Log.e(TAG, "-ve refcount for " + app);
738ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            }
74c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
75c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
76c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
778ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    NfcApplicationState findAppState(Application app) {
788ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        for (NfcApplicationState appState : mApps) {
798ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (appState.app == app) {
808ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                return appState;
818ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            }
828ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
838ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        return null;
84c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
85c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
868ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    void registerApplication(Application app) {
878ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NfcApplicationState appState = findAppState(app);
888ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        if (appState == null) {
898ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            appState = new NfcApplicationState(app);
908ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            mApps.add(appState);
91c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
928ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        appState.register();
93c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
94c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
958ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    void unregisterApplication(Application app) {
968ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NfcApplicationState appState = findAppState(app);
978ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        if (appState == null) {
988ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            Log.e(TAG, "app was not registered " + app);
998ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            return;
100c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
1018ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        appState.unregister();
102c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
103c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
1043433a8ae5abf7c518277e2e00c141e1dec83600cMartijn Coenen    /**
1058ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly     * NFC state associated with an {@link Activity}
1063433a8ae5abf7c518277e2e00c141e1dec83600cMartijn Coenen     */
1078ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    class NfcActivityState {
1088ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        boolean resumed = false;
1098ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        Activity activity;
1108ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NdefMessage ndefMessage = null;  // static NDEF message
1118ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
1128ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
11320e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen        NfcAdapter.CreateBeamUrisCallback uriCallback = null;
11420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen        Uri[] uris = null;
1151fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        int flags = 0;
116c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        int readerModeFlags = 0;
1175b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        NfcAdapter.ReaderCallback readerCallback = null;
1185b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        Bundle readerModeExtras = null;
119c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        Binder token;
120c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen
1218ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        public NfcActivityState(Activity activity) {
1228ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (activity.getWindow().isDestroyed()) {
1238ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                throw new IllegalStateException("activity is already destroyed");
1248ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            }
12520fe5378d73a1c01f8d5a6d3c53c2b4802a0a680Martijn Coenen            // Check if activity is resumed right now, as we will not
12620fe5378d73a1c01f8d5a6d3c53c2b4802a0a680Martijn Coenen            // immediately get a callback for that.
12720fe5378d73a1c01f8d5a6d3c53c2b4802a0a680Martijn Coenen            resumed = activity.isResumed();
12820fe5378d73a1c01f8d5a6d3c53c2b4802a0a680Martijn Coenen
1298ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            this.activity = activity;
130c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            this.token = new Binder();
1318ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            registerApplication(activity.getApplication());
132c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
1338ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        public void destroy() {
1348ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            unregisterApplication(activity.getApplication());
1358ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            resumed = false;
1368ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            activity = null;
1378ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            ndefMessage = null;
1388ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            ndefMessageCallback = null;
1398ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            onNdefPushCompleteCallback = null;
14020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            uriCallback = null;
14120e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            uris = null;
142c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            readerModeFlags = 0;
143c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            token = null;
144c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
1458ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        @Override
1468ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        public String toString() {
1478ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            StringBuilder s = new StringBuilder("[").append(" ");
1488ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
14920e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            s.append(uriCallback).append(" ");
15020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            if (uris != null) {
15120e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen                for (Uri uri : uris) {
15220e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen                    s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
15320e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen                }
15420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            }
1558ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            return s.toString();
156c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
157c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
158c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
1598ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** find activity state from mActivities */
1608ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    synchronized NfcActivityState findActivityState(Activity activity) {
1618ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        for (NfcActivityState state : mActivities) {
1628ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (state.activity == activity) {
1638ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                return state;
1648ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            }
165c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
1668ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        return null;
1678ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    }
1688ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
1698ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** find or create activity state from mActivities */
1708ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    synchronized NfcActivityState getActivityState(Activity activity) {
1718ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NfcActivityState state = findActivityState(activity);
1728ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        if (state == null) {
1738ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            state = new NfcActivityState(activity);
1748ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            mActivities.add(state);
175c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
1768ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        return state;
1778ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    }
1788ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
1798ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    synchronized NfcActivityState findResumedActivityState() {
1808ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        for (NfcActivityState state : mActivities) {
1818ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (state.resumed) {
1828ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                return state;
1838ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            }
184c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
1858ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        return null;
186c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
187c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
1888ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    synchronized void destroyActivityState(Activity activity) {
1898ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NfcActivityState activityState = findActivityState(activity);
1908ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        if (activityState != null) {
1918ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            activityState.destroy();
1928ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            mActivities.remove(activityState);
193c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
1948ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    }
1958ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
1968ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public NfcActivityManager(NfcAdapter adapter) {
1978ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        mAdapter = adapter;
1988ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        mActivities = new LinkedList<NfcActivityState>();
1998ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        mApps = new ArrayList<NfcApplicationState>(1);  // Android VM usually has 1 app
2008ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        mDefaultEvent = new NfcEvent(mAdapter);
2018ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    }
2028ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
2035b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
2045b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            Bundle extras) {
205c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        boolean isResumed;
206c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        Binder token;
207c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        synchronized (NfcActivityManager.this) {
208c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            NfcActivityState state = getActivityState(activity);
2095b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            state.readerCallback = callback;
210c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            state.readerModeFlags = flags;
2115b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            state.readerModeExtras = extras;
212c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            token = state.token;
213c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            isResumed = state.resumed;
214c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        }
215c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        if (isResumed) {
2165b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            setReaderMode(token, flags, extras);
217c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        }
218c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen    }
219c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen
220c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen    public void disableReaderMode(Activity activity) {
221c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        boolean isResumed;
222c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        Binder token;
223c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        synchronized (NfcActivityManager.this) {
224c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            NfcActivityState state = getActivityState(activity);
2255b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            state.readerCallback = null;
226c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            state.readerModeFlags = 0;
2275b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            state.readerModeExtras = null;
228c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            token = state.token;
229c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            isResumed = state.resumed;
230c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        }
231c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        if (isResumed) {
2325b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            setReaderMode(token, 0, null);
233c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        }
234c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen
235c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen    }
236c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen
2375b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen    public void setReaderMode(Binder token, int flags, Bundle extras) {
238c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        if (DBG) Log.d(TAG, "Setting reader mode");
239c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        try {
2405b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            NfcAdapter.sService.setReaderMode(token, this, flags, extras);
241c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        } catch (RemoteException e) {
242c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            mAdapter.attemptDeadServiceRecovery(e);
243c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        }
244c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen    }
245c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen
24620e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen    public void setNdefPushContentUri(Activity activity, Uri[] uris) {
24720e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen        boolean isResumed;
24820e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen        synchronized (NfcActivityManager.this) {
24920e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            NfcActivityState state = getActivityState(activity);
25020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            state.uris = uris;
25120e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            isResumed = state.resumed;
25220e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen        }
25320e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen        if (isResumed) {
2541360c555a4e060be30a7a6a7916449441c1bf646Martijn Coenen            requestNfcServiceCallback();
25520e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen        }
25620e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen    }
25720e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen
25820e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen
25920e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen    public void setNdefPushContentUriCallback(Activity activity,
26020e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            NfcAdapter.CreateBeamUrisCallback callback) {
2611d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly        boolean isResumed;
2621d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly        synchronized (NfcActivityManager.this) {
2631d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly            NfcActivityState state = getActivityState(activity);
26420e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen            state.uriCallback = callback;
2651d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly            isResumed = state.resumed;
2661d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly        }
2671d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly        if (isResumed) {
2681360c555a4e060be30a7a6a7916449441c1bf646Martijn Coenen            requestNfcServiceCallback();
2691d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly        }
2701d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly    }
2711d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly
2721fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen    public void setNdefPushMessage(Activity activity, NdefMessage message, int flags) {
2738ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        boolean isResumed;
2748ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        synchronized (NfcActivityManager.this) {
2758ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = getActivityState(activity);
2768ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            state.ndefMessage = message;
2771fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            state.flags = flags;
2788ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            isResumed = state.resumed;
279c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
2808ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        if (isResumed) {
2811360c555a4e060be30a7a6a7916449441c1bf646Martijn Coenen            requestNfcServiceCallback();
282c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
283c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
284c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
2858ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void setNdefPushMessageCallback(Activity activity,
2861fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            NfcAdapter.CreateNdefMessageCallback callback, int flags) {
2878ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        boolean isResumed;
2888ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        synchronized (NfcActivityManager.this) {
2898ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = getActivityState(activity);
2908ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            state.ndefMessageCallback = callback;
2911fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            state.flags = flags;
2928ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            isResumed = state.resumed;
2938ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
2948ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        if (isResumed) {
2951360c555a4e060be30a7a6a7916449441c1bf646Martijn Coenen            requestNfcServiceCallback();
296c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
297c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
298c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
2998ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void setOnNdefPushCompleteCallback(Activity activity,
3008ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcAdapter.OnNdefPushCompleteCallback callback) {
3018ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        boolean isResumed;
3028ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        synchronized (NfcActivityManager.this) {
3038ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = getActivityState(activity);
3048ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            state.onNdefPushCompleteCallback = callback;
3058ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            isResumed = state.resumed;
3068ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
3078ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        if (isResumed) {
3081360c555a4e060be30a7a6a7916449441c1bf646Martijn Coenen            requestNfcServiceCallback();
309c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
310c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
311c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
312c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    /**
3135b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen     * Request or unrequest NFC service callbacks.
3148ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly     * Makes IPC call - do not hold lock.
315c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly     */
3161360c555a4e060be30a7a6a7916449441c1bf646Martijn Coenen    void requestNfcServiceCallback() {
317c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        try {
3185b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            NfcAdapter.sService.setAppCallback(this);
319c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        } catch (RemoteException e) {
320c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly            mAdapter.attemptDeadServiceRecovery(e);
321c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
322c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
323c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
3248ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from NFC service, usually on binder thread */
325c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    @Override
3261fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen    public BeamShareData createBeamShareData() {
3271fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        NfcAdapter.CreateNdefMessageCallback ndefCallback;
3281fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        NfcAdapter.CreateBeamUrisCallback urisCallback;
3298ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NdefMessage message;
3301fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        Uri[] uris;
3311fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        int flags;
332c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        synchronized (NfcActivityManager.this) {
3338ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = findResumedActivityState();
3348ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (state == null) return null;
3358ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
3361fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            ndefCallback = state.ndefMessageCallback;
3371fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            urisCallback = state.uriCallback;
3388ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            message = state.ndefMessage;
3391fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            uris = state.uris;
3401fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            flags = state.flags;
341c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
342c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
3431fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        // Make callbacks without lock
3441fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        if (ndefCallback != null) {
3451fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            message  = ndefCallback.createNdefMessage(mDefaultEvent);
3461d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly        }
3471fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        if (urisCallback != null) {
3481fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen            uris = urisCallback.createBeamUris(mDefaultEvent);
3492c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen            if (uris != null) {
3502c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                for (Uri uri : uris) {
3512c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                    if (uri == null) {
3522c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                        Log.e(TAG, "Uri not allowed to be null.");
3532c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                        return null;
3542c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                    }
3552c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                    String scheme = uri.getScheme();
3562c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                    if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
3572c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                            !scheme.equalsIgnoreCase("content"))) {
3582c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                        Log.e(TAG, "Uri needs to have " +
3592c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                                "either scheme file or scheme content");
3602c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                        return null;
3612c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                    }
3622c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen                }
3632c10311a01a9414a8efcedb267a45289a1617888Martijn Coenen            }
3641d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly        }
3651fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen
3661fa2aff21bc4cb89a141828c2661530e6aa655ddMartijn Coenen        return new BeamShareData(message, uris, flags);
3671d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly    }
36820e8dd9f9e7cff63c83e36a1761538a04c224cc1Martijn Coenen
3691d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly    /** Callback from NFC service, usually on binder thread */
3701d7e9062330a5a02247752de32a68ecbeba82783Nick Pelly    @Override
371c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    public void onNdefPushComplete() {
3728ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        NfcAdapter.OnNdefPushCompleteCallback callback;
373c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        synchronized (NfcActivityManager.this) {
3748ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = findResumedActivityState();
3758ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (state == null) return;
3768ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
3778ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            callback = state.onNdefPushCompleteCallback;
378c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
379c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly
3808ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        // Make callback without lock
381c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        if (callback != null) {
382c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly            callback.onNdefPushComplete(mDefaultEvent);
383c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly        }
384c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly    }
3853433a8ae5abf7c518277e2e00c141e1dec83600cMartijn Coenen
3865b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen    @Override
3875b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen    public void onTagDiscovered(Tag tag) throws RemoteException {
3885b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        NfcAdapter.ReaderCallback callback;
3895b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        synchronized (NfcActivityManager.this) {
3905b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            NfcActivityState state = findResumedActivityState();
3915b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            if (state == null) return;
3925b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen
3935b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            callback = state.readerCallback;
3945b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        }
3955b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen
3965b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        // Make callback without lock
3975b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        if (callback != null) {
3985b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            callback.onTagDiscovered(tag);
3995b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        }
4005b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen
4015b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen    }
4028ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from Activity life-cycle, on main thread */
4038ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    @Override
4048ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
4058ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
4068ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from Activity life-cycle, on main thread */
4078ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    @Override
4088ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void onActivityStarted(Activity activity) { /* NO-OP */ }
4098ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
4108ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from Activity life-cycle, on main thread */
4118ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    @Override
4128ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void onActivityResumed(Activity activity) {
413c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        int readerModeFlags = 0;
4145b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen        Bundle readerModeExtras = null;
415c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        Binder token;
4168ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        synchronized (NfcActivityManager.this) {
4178ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = findActivityState(activity);
4188ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
4198ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (state == null) return;
4208ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            state.resumed = true;
421c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            token = state.token;
422c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            readerModeFlags = state.readerModeFlags;
4235b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            readerModeExtras = state.readerModeExtras;
424c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        }
425c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        if (readerModeFlags != 0) {
4265b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            setReaderMode(token, readerModeFlags, readerModeExtras);
4278ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
4281360c555a4e060be30a7a6a7916449441c1bf646Martijn Coenen        requestNfcServiceCallback();
4298ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    }
4308ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
4318ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from Activity life-cycle, on main thread */
4328ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    @Override
4338ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void onActivityPaused(Activity activity) {
434c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        boolean readerModeFlagsSet;
435c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        Binder token;
4368ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        synchronized (NfcActivityManager.this) {
4378ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = findActivityState(activity);
4388ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
4398ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (state == null) return;
4408ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            state.resumed = false;
441c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            token = state.token;
442c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            readerModeFlagsSet = state.readerModeFlags != 0;
443c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        }
444c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen        if (readerModeFlagsSet) {
445c20ed2ff125fd23bed25df8172bf24db84c5a352Martijn Coenen            // Restore default p2p modes
4465b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen            setReaderMode(token, 0, null);
4478ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
4488ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    }
4498ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
4508ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from Activity life-cycle, on main thread */
4518ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    @Override
4528ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void onActivityStopped(Activity activity) { /* NO-OP */ }
4538ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
4548ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from Activity life-cycle, on main thread */
4558ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    @Override
4568ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void onActivitySaveInstanceState(Activity activity, Bundle outState) { /* NO-OP */ }
4578ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly
4588ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    /** Callback from Activity life-cycle, on main thread */
4598ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    @Override
4608ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    public void onActivityDestroyed(Activity activity) {
4618ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        synchronized (NfcActivityManager.this) {
4628ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            NfcActivityState state = findActivityState(activity);
4638ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (DBG) Log.d(TAG, "onDestroy() for " + activity + " " + state);
4648ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            if (state != null) {
4658ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                // release all associated references
4668ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly                destroyActivityState(activity);
4678ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly            }
4688ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly        }
4698ce7a27770735791b5c38e4128f4ab9cee86bc43Nick Pelly    }
4705b1e032ea7c06ab11d778264dd950009fcb93cc5Martijn Coenen
471c84c89a6cacaf16c1ba41f57cc1aecdb150e85f9Nick Pelly}
472