NfcActivityManager.java revision d8bcfbadf7037dd2574312a3bfa04dd70d967166
14a10645c70199c8d8567fbc46312158c419720abChris Lattner/*
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman * Copyright (C) 2011 The Android Open Source Project
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell *
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell * Licensed under the Apache License, Version 2.0 (the "License");
521c62da287237d39d0d95004881ea4baae3be6daChris Lattner * you may not use this file except in compliance with the License.
621c62da287237d39d0d95004881ea4baae3be6daChris Lattner * You may obtain a copy of the License at
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman *
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell *      http://www.apache.org/licenses/LICENSE-2.0
94a10645c70199c8d8567fbc46312158c419720abChris Lattner *
104a10645c70199c8d8567fbc46312158c419720abChris Lattner * Unless required by applicable law or agreed to in writing, software
118ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif * distributed under the License is distributed on an "AS IS" BASIS,
124a10645c70199c8d8567fbc46312158c419720abChris Lattner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134a10645c70199c8d8567fbc46312158c419720abChris Lattner * See the License for the specific language governing permissions and
144a10645c70199c8d8567fbc46312158c419720abChris Lattner * limitations under the License.
154a10645c70199c8d8567fbc46312158c419720abChris Lattner */
16f1b20d8620b05abaa52f40ac6d21f839b265fb00Chris Lattner
17551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencerpackage android.nfc;
18551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer
19551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencerimport android.app.Activity;
20551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencerimport android.app.Application;
2174382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattnerimport android.content.Intent;
224a10645c70199c8d8567fbc46312158c419720abChris Lattnerimport android.net.Uri;
2351ab5c8862466bbddcd5c4369779c472978ed309Reid Spencerimport android.nfc.NfcAdapter.ReaderCallback;
24d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeimport android.os.Binder;
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeimport android.os.Bundle;
264a10645c70199c8d8567fbc46312158c419720abChris Lattnerimport android.os.RemoteException;
274a10645c70199c8d8567fbc46312158c419720abChris Lattnerimport android.util.Log;
284a10645c70199c8d8567fbc46312158c419720abChris Lattner
294a10645c70199c8d8567fbc46312158c419720abChris Lattnerimport java.util.ArrayList;
304a10645c70199c8d8567fbc46312158c419720abChris Lattnerimport java.util.LinkedList;
31f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trickimport java.util.List;
32f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick
334a10645c70199c8d8567fbc46312158c419720abChris Lattner/**
344148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman * Manages NFC API's that are coupled to the life-cycle of an Activity.
35a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner *
36a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner * <p>Uses {@link Application#registerActivityLifecycleCallbacks} to hook
37a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner * into activity life-cycle events such as onPause() and onResume().
38a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner *
39a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner * @hide
40a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner */
41a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattnerpublic final class NfcActivityManager extends IAppCallback.Stub
424a10645c70199c8d8567fbc46312158c419720abChris Lattner        implements Application.ActivityLifecycleCallbacks {
4370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    static final String TAG = NfcAdapter.TAG;
44b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke    static final Boolean DBG = false;
45b687d82b029ba448b978e2c9ed424ee5d1f9f093Misha Brukman
46b687d82b029ba448b978e2c9ed424ee5d1f9f093Misha Brukman    final NfcAdapter mAdapter;
475073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    final NfcEvent mDefaultEvent;  // cached NfcEvent (its currently always the same)
485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
4950010429a7c3285dab15ede68acae7231fade367Chris Lattner    // All objects in the lists are protected by this
5050010429a7c3285dab15ede68acae7231fade367Chris Lattner    final List<NfcApplicationState> mApps;  // Application(s) that have NFC state. Usually one
515073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    final List<NfcActivityState> mActivities;  // Activities that have NFC state
52c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner
53cd6f46e2ac4c1d64067237c0b28eccfae22bd9f4Chris Lattner    /**
54f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick     * NFC State associated with an {@link Application}.
55f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick     */
56f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick    class NfcApplicationState {
579ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov        int refCount = 0;
589ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov        final Application app;
599ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov        public NfcApplicationState(Application app) {
604d143ee01988e1b52e106ffccbb313937ca5e886Chris Lattner            this.app = app;
61b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        }
623c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner        public void register() {
6370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            refCount++;
6470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            if (refCount == 1) {
6549419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng                this.app.registerActivityLifecycleCallbacks(NfcActivityManager.this);
6649419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng            }
6749419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng        }
6849419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng        public void unregister() {
6949419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng            refCount--;
7049419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng            if (refCount == 0) {
7149419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng                this.app.unregisterActivityLifecycleCallbacks(NfcActivityManager.this);
7270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            } else if (refCount < 0) {
7370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman                Log.e(TAG, "-ve refcount for " + app);
7470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            }
7570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
7649419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng    }
7749419e28fe400509363cecf63a3a824002c1d9e0Evan Cheng
7870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    NfcApplicationState findAppState(Application app) {
79c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke        for (NfcApplicationState appState : mApps) {
805e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer            if (appState.app == app) {
815e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer                return appState;
825e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer            }
835e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer        }
843c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner        return null;
853c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner    }
863c053a0a98e19f5ac8905011ad4c8238b08d6aeaChris Lattner
877dac658792425c10274594782d6fcf10208a16f0Chris Lattner    void registerApplication(Application app) {
887dac658792425c10274594782d6fcf10208a16f0Chris Lattner        NfcApplicationState appState = findAppState(app);
897dac658792425c10274594782d6fcf10208a16f0Chris Lattner        if (appState == null) {
907dac658792425c10274594782d6fcf10208a16f0Chris Lattner            appState = new NfcApplicationState(app);
917dac658792425c10274594782d6fcf10208a16f0Chris Lattner            mApps.add(appState);
927d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner        }
9351ab5c8862466bbddcd5c4369779c472978ed309Reid Spencer        appState.register();
94de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick    }
9551ab5c8862466bbddcd5c4369779c472978ed309Reid Spencer
969ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov    void unregisterApplication(Application app) {
979ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov        NfcApplicationState appState = findAppState(app);
98f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick        if (appState == null) {
99f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick            Log.e(TAG, "app was not registered " + app);
100f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick            return;
101f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick        }
102f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick        appState.unregister();
1039ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov    }
1049ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov
1059ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov    /**
1064a10645c70199c8d8567fbc46312158c419720abChris Lattner     * NFC state associated with an {@link Activity}
1074a10645c70199c8d8567fbc46312158c419720abChris Lattner     */
108d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke    class NfcActivityState {
109fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        boolean resumed = false;
110fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        Activity activity;
111fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        NdefMessage ndefMessage = null;  // static NDEF message
112fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
11360083e2fc0f1165b7511757449f1ee3852b7229cChris Lattner        NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
11468ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar        NfcAdapter.CreateBeamUrisCallback uriCallback = null;
11568ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar        Uri[] uris = null;
11668ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar        int flags = 0;
11768ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar        int readerModeFlags = 0;
11870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        NfcAdapter.ReaderCallback readerCallback = null;
119636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke        Bundle readerModeExtras = null;
12070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        Binder token;
121636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke
122636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke        public NfcActivityState(Activity activity) {
12360083e2fc0f1165b7511757449f1ee3852b7229cChris Lattner            if (activity.getWindow().isDestroyed()) {
12470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman                throw new IllegalStateException("activity is already destroyed");
12570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            }
12670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            // Check if activity is resumed right now, as we will not
12770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            // immediately get a callback for that.
12870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            resumed = activity.isResumed();
12938efa38c864f6d29892d92102c0232b234b526edBill Wendling
130faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila            this.activity = activity;
131de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick            this.token = new Binder();
132faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila            registerApplication(activity.getApplication());
133faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila        }
13438efa38c864f6d29892d92102c0232b234b526edBill Wendling        public void destroy() {
13538efa38c864f6d29892d92102c0232b234b526edBill Wendling            unregisterApplication(activity.getApplication());
13638efa38c864f6d29892d92102c0232b234b526edBill Wendling            resumed = false;
13738efa38c864f6d29892d92102c0232b234b526edBill Wendling            activity = null;
138fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner            ndefMessage = null;
1399d679cbc6cb5c7dc8cca87a1e1548c480fb056b8Misha Brukman            ndefMessageCallback = null;
1404a10645c70199c8d8567fbc46312158c419720abChris Lattner            onNdefPushCompleteCallback = null;
1414a10645c70199c8d8567fbc46312158c419720abChris Lattner            uriCallback = null;
1424a10645c70199c8d8567fbc46312158c419720abChris Lattner            uris = null;
1434a10645c70199c8d8567fbc46312158c419720abChris Lattner            readerModeFlags = 0;
1444a10645c70199c8d8567fbc46312158c419720abChris Lattner            token = null;
1454a10645c70199c8d8567fbc46312158c419720abChris Lattner        }
1464a10645c70199c8d8567fbc46312158c419720abChris Lattner        @Override
1474a10645c70199c8d8567fbc46312158c419720abChris Lattner        public String toString() {
148ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman            StringBuilder s = new StringBuilder("[").append(" ");
1494a10645c70199c8d8567fbc46312158c419720abChris Lattner            s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
1504148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman            s.append(uriCallback).append(" ");
1514148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman            if (uris != null) {
15270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman                for (Uri uri : uris) {
1534a10645c70199c8d8567fbc46312158c419720abChris Lattner                    s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
154636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke                }
155cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner            }
156b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke            return s.toString();
157b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        }
15870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    }
159faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila
160faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila    /** find activity state from mActivities */
161b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke    synchronized NfcActivityState findActivityState(Activity activity) {
162b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        for (NfcActivityState state : mActivities) {
163636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke            if (state.activity == activity) {
164636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke                return state;
165b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke            }
166b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        }
167b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        return null;
168636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke    }
169de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick
170faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila    /** find or create activity state from mActivities */
171b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke    synchronized NfcActivityState getActivityState(Activity activity) {
172b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        NfcActivityState state = findActivityState(activity);
173b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        if (state == null) {
174636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke            state = new NfcActivityState(activity);
175636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke            mActivities.add(state);
176b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        }
177b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        return state;
178b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke    }
179b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke
180b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke    synchronized NfcActivityState findResumedActivityState() {
181b5ee509be2ce78badc11fd649dda90ec78394d1aBrian Gaeke        for (NfcActivityState state : mActivities) {
182769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner            if (state.resumed) {
183636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke                return state;
184636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke            }
185769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner        }
186769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner        return null;
18750010429a7c3285dab15ede68acae7231fade367Chris Lattner    }
18870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
189636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke    synchronized void destroyActivityState(Activity activity) {
190de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick        NfcActivityState activityState = findActivityState(activity);
191faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila        if (activityState != null) {
19250010429a7c3285dab15ede68acae7231fade367Chris Lattner            activityState.destroy();
193769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner            mActivities.remove(activityState);
194769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner        }
195636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke    }
196636df3d7ec51a8c6fd759a98853ff709ae54d64eBrian Gaeke
197769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner    public NfcActivityManager(NfcAdapter adapter) {
198769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner        mAdapter = adapter;
199c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner        mActivities = new LinkedList<NfcActivityState>();
200c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner        mApps = new ArrayList<NfcApplicationState>(1);  // Android VM usually has 1 app
201de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick        mDefaultEvent = new NfcEvent(mAdapter);
202faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila    }
203769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner
204f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick    public void enableReaderMode(Activity activity, ReaderCallback callback, int flags,
205f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick            Bundle extras) {
206f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick        boolean isResumed;
207f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick        Binder token;
2089ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov        synchronized (NfcActivityManager.this) {
209f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick            NfcActivityState state = getActivityState(activity);
210f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick            state.readerCallback = callback;
2119ef7425a4d44ff129495da2357c98c67162fbeffAnton Korobeynikov            state.readerModeFlags = flags;
212cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner            state.readerModeExtras = extras;
2134148556a9c767fdf3047ae8e004a759356b893ddMisha Brukman            token = state.token;
214cc876a7421f6dbcca98446058d5f0637092c6e1aChris Lattner            isResumed = state.resumed;
2154a10645c70199c8d8567fbc46312158c419720abChris Lattner        }
216ad6996d74f60340d6139af8f345d93735661fbbaMatthijs Kooijman        if (isResumed) {
21765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman            setReaderMode(token, flags, extras);
218ad6996d74f60340d6139af8f345d93735661fbbaMatthijs Kooijman        }
219ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    }
2204a10645c70199c8d8567fbc46312158c419720abChris Lattner
22170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    public void disableReaderMode(Activity activity) {
22270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        boolean isResumed;
22370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        Binder token;
22470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        synchronized (NfcActivityManager.this) {
22570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            NfcActivityState state = getActivityState(activity);
22670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            state.readerCallback = null;
22770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            state.readerModeFlags = 0;
22870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            state.readerModeExtras = null;
22970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            token = state.token;
23070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            isResumed = state.resumed;
23170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
232197f728d49fa0cc0baa5aadb2b905fbd8c22a81eDan Gohman        if (isResumed) {
233de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick            setReaderMode(token, 0, null);
23438efa38c864f6d29892d92102c0232b234b526edBill Wendling        }
23538efa38c864f6d29892d92102c0232b234b526edBill Wendling
23670ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    }
23770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
23870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    public void setReaderMode(Binder token, int flags, Bundle extras) {
23970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        if (DBG) Log.d(TAG, "Setting reader mode");
24070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        try {
24170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            NfcAdapter.sService.setReaderMode(token, this, flags, extras);
24270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        } catch (RemoteException e) {
243197f728d49fa0cc0baa5aadb2b905fbd8c22a81eDan Gohman            mAdapter.attemptDeadServiceRecovery(e);
244de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick        }
24538efa38c864f6d29892d92102c0232b234b526edBill Wendling    }
24638efa38c864f6d29892d92102c0232b234b526edBill Wendling
24770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    public void setNdefPushContentUri(Activity activity, Uri[] uris) {
24870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        boolean isResumed;
24970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        synchronized (NfcActivityManager.this) {
25070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            NfcActivityState state = getActivityState(activity);
25170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            state.uris = uris;
25270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            isResumed = state.resumed;
25370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
25470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        if (isResumed) {
255197f728d49fa0cc0baa5aadb2b905fbd8c22a81eDan Gohman            // requestNfcServiceCallback() verifies permission also
256faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila            requestNfcServiceCallback();
25738efa38c864f6d29892d92102c0232b234b526edBill Wendling        } else {
25838efa38c864f6d29892d92102c0232b234b526edBill Wendling            // Crash API calls early in case NFC permission is missing
25970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            verifyNfcPermission();
26070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
26170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    }
26270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
26370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
26470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman    public void setNdefPushContentUriCallback(Activity activity,
265197f728d49fa0cc0baa5aadb2b905fbd8c22a81eDan Gohman            NfcAdapter.CreateBeamUrisCallback callback) {
266de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick        boolean isResumed;
26738efa38c864f6d29892d92102c0232b234b526edBill Wendling        synchronized (NfcActivityManager.this) {
26838efa38c864f6d29892d92102c0232b234b526edBill Wendling            NfcActivityState state = getActivityState(activity);
26970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            state.uriCallback = callback;
27070ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            isResumed = state.resumed;
27170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
27270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        if (isResumed) {
27370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            // requestNfcServiceCallback() verifies permission also
27470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            requestNfcServiceCallback();
27570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        } else {
27650010429a7c3285dab15ede68acae7231fade367Chris Lattner            // Crash API calls early in case NFC permission is missing
27770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            verifyNfcPermission();
278197f728d49fa0cc0baa5aadb2b905fbd8c22a81eDan Gohman        }
279faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila    }
28050010429a7c3285dab15ede68acae7231fade367Chris Lattner
28150010429a7c3285dab15ede68acae7231fade367Chris Lattner    public void setNdefPushMessage(Activity activity, NdefMessage message, int flags) {
28270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        boolean isResumed;
28370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        synchronized (NfcActivityManager.this) {
284197f728d49fa0cc0baa5aadb2b905fbd8c22a81eDan Gohman            NfcActivityState state = getActivityState(activity);
285faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila            state.ndefMessage = message;
28638efa38c864f6d29892d92102c0232b234b526edBill Wendling            state.flags = flags;
28770ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            isResumed = state.resumed;
28870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
289f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick        if (isResumed) {
290f73311bb646bf970806ba7caba220e6bffff7b49Andrew Trick            // requestNfcServiceCallback() verifies permission also
29170ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            requestNfcServiceCallback();
29270ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        } else {
29370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            // Crash API calls early in case NFC permission is missing
29470ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            verifyNfcPermission();
29570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
2967bb11547e497d7b8fc87f61c1089eee808e3a1eeChris Lattner    }
297ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman
298de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick    public void setNdefPushMessageCallback(Activity activity,
299faa95763ebb081769bf6ac35e170394c9d477813Kalle Raiskila            NfcAdapter.CreateNdefMessageCallback callback, int flags) {
300ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman        boolean isResumed;
301a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman        synchronized (NfcActivityManager.this) {
3024a10645c70199c8d8567fbc46312158c419720abChris Lattner            NfcActivityState state = getActivityState(activity);
3034a10645c70199c8d8567fbc46312158c419720abChris Lattner            state.ndefMessageCallback = callback;
3044a10645c70199c8d8567fbc46312158c419720abChris Lattner            state.flags = flags;
3054a10645c70199c8d8567fbc46312158c419720abChris Lattner            isResumed = state.resumed;
30622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        }
30722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        if (isResumed) {
30822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            // requestNfcServiceCallback() verifies permission also
309ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner            requestNfcServiceCallback();
310248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola        } else {
3118ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif            // Crash API calls early in case NFC permission is missing
31268ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar            verifyNfcPermission();
31351c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer        }
31422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    }
315de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick
31665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    public void setOnNdefPushCompleteCallback(Activity activity,
31751c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer            NfcAdapter.OnNdefPushCompleteCallback callback) {
31851c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer        boolean isResumed;
31974382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner        synchronized (NfcActivityManager.this) {
32065f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman            NfcActivityState state = getActivityState(activity);
32174382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner            state.onNdefPushCompleteCallback = callback;
322ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner            isResumed = state.resumed;
323ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner        }
324ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner        if (isResumed) {
32522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            // requestNfcServiceCallback() verifies permission also
326c9c08fb3a7fb5e8ea3e1477a88507704c7a70ba1Michael J. Spencer            requestNfcServiceCallback();
327ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner        } else {
328ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner            // Crash API calls early in case NFC permission is missing
32941396302126c24f1d5231e191852ebf2ff37fe23Duncan Sands            verifyNfcPermission();
330ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner        }
331ea9212ca964ff6587227016f86a44160e586a4c8Chris Lattner    }
3324a10645c70199c8d8567fbc46312158c419720abChris Lattner
3334a10645c70199c8d8567fbc46312158c419720abChris Lattner    /**
3344a10645c70199c8d8567fbc46312158c419720abChris Lattner     * Request or unrequest NFC service callbacks.
3354a10645c70199c8d8567fbc46312158c419720abChris Lattner     * Makes IPC call - do not hold lock.
3364a10645c70199c8d8567fbc46312158c419720abChris Lattner     */
33710757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola    void requestNfcServiceCallback() {
33810757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola        try {
3398ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif            NfcAdapter.sService.setAppCallback(this);
340769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner        } catch (RemoteException e) {
34122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            mAdapter.attemptDeadServiceRecovery(e);
34213793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola        }
343769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner    }
344769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner
3458ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif    void verifyNfcPermission() {
34651c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer        try {
3478ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif            NfcAdapter.sService.verifyNfcPermission();
3488ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif        } catch (RemoteException e) {
34968ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar            mAdapter.attemptDeadServiceRecovery(e);
35051c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer        }
35165f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    }
35265f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman
35351c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer    /** Callback from NFC service, usually on binder thread */
35451c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer    @Override
35574382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner    public BeamShareData createBeamShareData() {
3564a10645c70199c8d8567fbc46312158c419720abChris Lattner        NfcAdapter.CreateNdefMessageCallback ndefCallback;
3578ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif        NfcAdapter.CreateBeamUrisCallback urisCallback;
35865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman        NdefMessage message;
35965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman        Activity activity;
3604a10645c70199c8d8567fbc46312158c419720abChris Lattner        Uri[] uris;
3614a10645c70199c8d8567fbc46312158c419720abChris Lattner        int flags;
3628ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif        synchronized (NfcActivityManager.this) {
3634a10645c70199c8d8567fbc46312158c419720abChris Lattner            NfcActivityState state = findResumedActivityState();
3644a10645c70199c8d8567fbc46312158c419720abChris Lattner            if (state == null) return null;
3658ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
36616350f8d00fc3a4a8d2da8a746a29979505af9a8Nick Lewycky            ndefCallback = state.ndefMessageCallback;
367c9c08fb3a7fb5e8ea3e1477a88507704c7a70ba1Michael J. Spencer            urisCallback = state.uriCallback;
368c9c08fb3a7fb5e8ea3e1477a88507704c7a70ba1Michael J. Spencer            message = state.ndefMessage;
3699709272675feaca030cce14d0f5eb7f342b3fc1dChris Lattner            uris = state.uris;
37068ccdaa84909108c42417a8091c771598e26456eDaniel Dunbar            flags = state.flags;
3715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman            activity = state.activity;
3724a10645c70199c8d8567fbc46312158c419720abChris Lattner        }
37397182985d530dbef488696c95a39c14fe56c995bReid Spencer
37451c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer        // Make callbacks without lock
37565f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman        if (ndefCallback != null) {
37665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman            message  = ndefCallback.createNdefMessage(mDefaultEvent);
37751c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer        }
37851c5a286bae5ad27ddc49602f44b7ea7253a4cc9Reid Spencer        if (urisCallback != null) {
37974382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner            uris = urisCallback.createBeamUris(mDefaultEvent);
3804a10645c70199c8d8567fbc46312158c419720abChris Lattner            if (uris != null) {
381769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner                for (Uri uri : uris) {
3827dac658792425c10274594782d6fcf10208a16f0Chris Lattner                    if (uri == null) {
383769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner                        Log.e(TAG, "Uri not allowed to be null.");
384769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner                        return null;
385769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner                    }
38622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                    String scheme = uri.getScheme();
38722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                    if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
38870ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman                            !scheme.equalsIgnoreCase("content"))) {
38922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                        Log.e(TAG, "Uri needs to have " +
39022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                                "either scheme file or scheme content");
3917d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner                        return null;
3927d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner                    }
39365f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman                }
3947d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner            }
3957d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner        }
396ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman        if (uris != null && uris.length > 0) {
3977d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner            for (Uri uri : uris) {
3987d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner                // Grant the NFC process permission to read these URIs
3997d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner                activity.grantUriPermission("com.android.nfc", uri,
4007d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
4017d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner            }
4027d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner        }
4037d91e49ff7bcc0fd10a54d45a6185bb05adf3d20Chris Lattner        return new BeamShareData(message, uris, flags);
404769f1fe6728ffb5627ae0cedc392576d6e701a5aChris Lattner    }
4055e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer
4065e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    /** Callback from NFC service, usually on binder thread */
4075e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    @Override
4085e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer    public void onNdefPushComplete() {
4095e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer        NfcAdapter.OnNdefPushCompleteCallback callback;
4105e1452c856a8bcf39ab7a67a5af946c8162f942dReid Spencer        synchronized (NfcActivityManager.this) {
4114a10645c70199c8d8567fbc46312158c419720abChris Lattner            NfcActivityState state = findResumedActivityState();
4124a10645c70199c8d8567fbc46312158c419720abChris Lattner            if (state == null) return;
4134a10645c70199c8d8567fbc46312158c419720abChris Lattner
4144a10645c70199c8d8567fbc46312158c419720abChris Lattner            callback = state.onNdefPushCompleteCallback;
41570ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman        }
416c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke
417c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke        // Make callback without lock
41810757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola        if (callback != null) {
41910757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola            callback.onNdefPushComplete(mDefaultEvent);
42013793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola        }
42110757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola    }
422c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke
4235073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    @Override
42422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    public void onTagDiscovered(Tag tag) throws RemoteException {
42522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        NfcAdapter.ReaderCallback callback;
4265073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman        synchronized (NfcActivityManager.this) {
427c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner            NfcActivityState state = findResumedActivityState();
4285073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman            if (state == null) return;
42970ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman
43022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            callback = state.readerCallback;
43122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        }
43222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky
43322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        // Make callback without lock
4345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman        if (callback != null) {
435a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner            callback.onTagDiscovered(tag);
43622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        }
43722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky
43822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    }
43922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    /** Callback from Activity life-cycle, on main thread */
44022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    @Override
441a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { /* NO-OP */ }
4425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman
4435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    /** Callback from Activity life-cycle, on main thread */
444c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner    @Override
4455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    public void onActivityStarted(Activity activity) { /* NO-OP */ }
4466ebe44d22f6dd1ab9f7aa1f3cfd02be52145d535Chris Lattner
4475073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    /** Callback from Activity life-cycle, on main thread */
4485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman    @Override
4496a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    public void onActivityResumed(Activity activity) {
450de86cbdc57f30621d3692da7a36613bb623d13b5Andrew Trick        int readerModeFlags = 0;
4516a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins        Bundle readerModeExtras = null;
4526a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins        Binder token;
4536a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins        synchronized (NfcActivityManager.this) {
454c600f3c337f18c62116ac58b701e4f7ae6d2fb1aChris Lattner            NfcActivityState state = findActivityState(activity);
45522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
45622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            if (state == null) return;
45722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            state.resumed = true;
4586a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins            token = state.token;
45922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            readerModeFlags = state.readerModeFlags;
46010757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola            readerModeExtras = state.readerModeExtras;
46122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        }
46222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        if (readerModeFlags != 0) {
46370ef449741da8b1ef035e04a55958652a0200ba1Dan Gohman            setReaderMode(token, readerModeFlags, readerModeExtras);
46465f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman        }
46565f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman        requestNfcServiceCallback();
46665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    }
46765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman
4686a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    /** Callback from Activity life-cycle, on main thread */
4696a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    @Override
4706a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins    public void onActivityPaused(Activity activity) {
47122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky        boolean readerModeFlagsSet;
4726a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins        Binder token;
4736a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins        synchronized (NfcActivityManager.this) {
4745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman            NfcActivityState state = findActivityState(activity);
4756a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins            if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
4766a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkins            if (state == null) return;
47722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            state.resumed = false;
47822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            token = state.token;
4794a10645c70199c8d8567fbc46312158c419720abChris Lattner            readerModeFlagsSet = state.readerModeFlags != 0;
48010757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola        }
48110757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola        if (readerModeFlagsSet) {
4825073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman            // Restore default p2p modes
48322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            setReaderMode(token, 0, null);
48413793264e7cbf58e3b7b0cff3baac8e0b7a11a9dRafael Espindola        }
4854a10645c70199c8d8567fbc46312158c419720abChris Lattner    }
48610757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola
48710757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola    /** Callback from Activity life-cycle, on main thread */
48822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    @Override
48922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    public void onActivityStopped(Activity activity) { /* NO-OP */ }
490c5cad211d6ec50fe90a0a716dee701c6c4721385Brian Gaeke
49165f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner    /** Callback from Activity life-cycle, on main thread */
4924a10645c70199c8d8567fbc46312158c419720abChris Lattner    @Override
493a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner    public void onActivitySaveInstanceState(Activity activity, Bundle outState) { /* NO-OP */ }
49474382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner
495a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner    /** Callback from Activity life-cycle, on main thread */
496a328c51bb99666ee0c045a57ea6d6ce2b0198f9bChris Lattner    @Override
49765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    public void onActivityDestroyed(Activity activity) {
49865f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner        synchronized (NfcActivityManager.this) {
49965f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner            NfcActivityState state = findActivityState(activity);
50065f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner            if (DBG) Log.d(TAG, "onDestroy() for " + activity + " " + state);
50165f62790d6e3e7f7ceb9cd12a7a51a66d95a3b03Chris Lattner            if (state != null) {
50280becf194d56524e8c75618ac57a34520f87a684David Goodwin                // release all associated references
50380becf194d56524e8c75618ac57a34520f87a684David Goodwin                destroyActivityState(activity);
50480becf194d56524e8c75618ac57a34520f87a684David Goodwin            }
50580becf194d56524e8c75618ac57a34520f87a684David Goodwin        }
5064a10645c70199c8d8567fbc46312158c419720abChris Lattner    }
5078ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif
5088ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif}
5098ff70c2635bfd4e02c0140a5dc9ca909fffba35aGabor Greif