177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly/* 277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Copyright (C) 2011 The Android Open Source Project 377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * 477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * you may not use this file except in compliance with the License. 677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * You may obtain a copy of the License at 777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * 877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * 1077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Unless required by applicable law or agreed to in writing, software 1177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 1277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * See the License for the specific language governing permissions and 1477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * limitations under the License. 1577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 1677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 1777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellypackage com.android.nfc; 1877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 19b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport android.content.Intent; 20b42756d47f39774a07654f68af27bf3cc2c41511Andres Moralesimport android.content.pm.UserInfo; 21b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 22b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport com.android.nfc.beam.BeamManager; 23b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport com.android.nfc.beam.BeamSendService; 24b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport com.android.nfc.beam.BeamTransferRecord; 25b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 265c452dad7b24f28223414ce5e953bfcab782570eAndres Moralesimport android.os.UserManager; 276f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenenimport com.android.nfc.echoserver.EchoServer; 28f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenenimport com.android.nfc.handover.HandoverClient; 29b82d80d891077ccd74729e4143925a66eb89eef2Andres Moralesimport com.android.nfc.handover.HandoverDataParser; 30f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenenimport com.android.nfc.handover.HandoverServer; 3177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport com.android.nfc.ndefpush.NdefPushClient; 3277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport com.android.nfc.ndefpush.NdefPushServer; 3377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport com.android.nfc.snep.SnepClient; 3477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport com.android.nfc.snep.SnepMessage; 3577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport com.android.nfc.snep.SnepServer; 3677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 3777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.content.Context; 38416e2fc507d696486a127f932105b3b95519d0cbJeff Hamiltonimport android.content.SharedPreferences; 3977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.content.pm.ApplicationInfo; 4077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.content.pm.PackageManager; 4177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.content.pm.PackageManager.NameNotFoundException; 4277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.net.Uri; 43cbe27470ef7e67324b9e8cbc32c25088d82e2a86Martijn Coenenimport android.nfc.BeamShareData; 4431f39aee25964dad1038b7a9cc335d5a386113c8Martijn Coenenimport android.nfc.IAppCallback; 4577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.nfc.NdefMessage; 4677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.nfc.NdefRecord; 47cbe27470ef7e67324b9e8cbc32c25088d82e2a86Martijn Coenenimport android.nfc.NfcAdapter; 4877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.os.AsyncTask; 4977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.os.Handler; 5077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.os.Message; 51416e2fc507d696486a127f932105b3b95519d0cbJeff Hamiltonimport android.os.SystemClock; 523859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenenimport android.os.UserHandle; 5377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport android.util.Log; 5477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport java.io.FileDescriptor; 5577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport java.io.IOException; 5677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyimport java.io.PrintWriter; 57893bc90a71883f8d2bfc82818abbf21c9745efdaElliott Hughesimport java.nio.charset.StandardCharsets; 58416e2fc507d696486a127f932105b3b95519d0cbJeff Hamiltonimport java.util.Arrays; 59c4ff3393f54403064b237349277cbf65f3277285Martijn Coenenimport java.util.List; 6077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 6177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly/** 6277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Interface to listen for P2P events. 6377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * All callbacks are made from the UI thread. 6477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 6577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pellyinterface P2pEventListener { 6677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 679340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen * Indicates the user has expressed an intent to share 689340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen * over NFC, but a remote device has not come into range 699340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen * yet. Prompt the user to NFC tap. 709340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen */ 719340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen public void onP2pNfcTapRequested(); 729340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 739340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen /** 749340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen * Indicates the user has expressed an intent to share over 759340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen * NFC, but the link hasn't come up yet and we no longer 769340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen * want to wait for it 779340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen */ 789340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen public void onP2pTimeoutWaitingForLink(); 799340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 809340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen /** 8177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Indicates a P2P device is in range. 8277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * <p>onP2pInRange() and onP2pOutOfRange() will always be called 8377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * alternately. 8477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 8577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void onP2pInRange(); 8677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 8777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 8877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Called when a NDEF payload is prepared to send, and confirmation is 8977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * required. Call Callback.onP2pSendConfirmed() to make the confirmation. 9077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 9177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void onP2pSendConfirmationRequested(); 9277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 9377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 948a558ba19be56e71e6c2015dea862d150e6d07cbNick Pelly * Called to indicate a send was successful. 9577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 968a558ba19be56e71e6c2015dea862d150e6d07cbNick Pelly public void onP2pSendComplete(); 9777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 9877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 991a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen * 1001a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen * Called to indicate the link has broken while we were trying to send 1011a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen * a message. We'll start a debounce timer for the user to get the devices 1021a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen * back together. UI may show a hint to achieve that 1031a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen */ 1041a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen public void onP2pSendDebounce(); 1051a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen 1061a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen /** 1071a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen * Called to indicate a link has come back up after being temporarily 1081a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen * broken, and sending is resuming 1091a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen */ 1101a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen public void onP2pResumeSend(); 1111a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen 1121a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen /** 113a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen * Called to indicate the remote device does not support connection handover 114a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen */ 115a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen public void onP2pHandoverNotSupported(); 116a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen 117a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen /** 118aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales * Called to indicate the device is busy with another handover transfer 119aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales */ 120aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales public void onP2pHandoverBusy(); 121aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales 122aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales /** 12377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Called to indicate a receive was successful. 12477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 125d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen public void onP2pReceiveComplete(boolean playSound); 12677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 12777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 12877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Indicates the P2P device went out of range. 12977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 13077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void onP2pOutOfRange(); 13177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 13277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public interface Callback { 13377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void onP2pSendConfirmed(); 1349340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen public void onP2pCanceled(); 13577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 13677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly} 13777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 13877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly/** 13977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Manages sending and receiving NDEF message over LLCP link. 14077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Does simple debouncing of the LLCP link - so that even if the link 14177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * drops and returns the user does not know. 14277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 143d2604c0544f7bc26e5b2407f0215cccfffedae2cAndres Moralesclass P2pLinkManager implements Handler.Callback, P2pEventListener.Callback { 14477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final String TAG = "NfcP2pLinkManager"; 14577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final boolean DBG = true; 14677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 147eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen /** Include this constant as a meta-data entry in the manifest 148eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen * of an application to disable beaming the market/AAR link, like this: 149eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen * <pre>{@code 150eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen * <application ...> 151eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen * <meta-data android:name="android.nfc.disable_beam_default" 152eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen * android:value="true" /> 153eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen * </application> 154eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen * }</pre> 155eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen */ 156eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen static final String DISABLE_BEAM_DEFAULT = "android.nfc.disable_beam_default"; 157eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen 1586f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen /** Enables the LLCP EchoServer, which can be used to test the android 1596f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen * LLCP stack against nfcpy. 1606f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen */ 1616f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen static final boolean ECHOSERVER_ENABLED = false; 1626f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen 16377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly // TODO dynamically assign SAP values 16477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final int NDEFPUSH_SAP = 0x10; 165f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen static final int HANDOVER_SAP = 0x14; 16677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 1671a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen static final int LINK_SEND_PENDING_DEBOUNCE_MS = 3000; 1681a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen static final int LINK_SEND_CONFIRMED_DEBOUNCE_MS = 5000; 169ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen static final int LINK_SEND_COMPLETE_DEBOUNCE_MS = 500; 1709340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen static final int LINK_SEND_CANCELED_DEBOUNCE_MS = 250; 1719340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 1729340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // The amount of time we wait for the link to come up 1739340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // after a user has manually invoked Beam. 1749340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen static final int WAIT_FOR_LINK_TIMEOUT_MS = 10000; 1759340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 17677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final int MSG_DEBOUNCE_TIMEOUT = 1; 17777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final int MSG_RECEIVE_COMPLETE = 2; 178d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen static final int MSG_RECEIVE_HANDOVER = 3; 179d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen static final int MSG_SEND_COMPLETE = 4; 180d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen static final int MSG_START_ECHOSERVER = 5; 181d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen static final int MSG_STOP_ECHOSERVER = 6; 182a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen static final int MSG_HANDOVER_NOT_SUPPORTED = 7; 18357a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen static final int MSG_SHOW_CONFIRMATION_UI = 8; 1849340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen static final int MSG_WAIT_FOR_LINK_TIMEOUT = 9; 185aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales static final int MSG_HANDOVER_BUSY = 10; 18677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 18777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly // values for mLinkState 18877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final int LINK_STATE_DOWN = 1; 189ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen static final int LINK_STATE_UP = 2; 190ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen static final int LINK_STATE_DEBOUNCE = 3; 19177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 19277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly // values for mSendState 19377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final int SEND_STATE_NOTHING_TO_SEND = 1; 19477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static final int SEND_STATE_NEED_CONFIRMATION = 2; 1959340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen static final int SEND_STATE_PENDING = 3; 1969340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen static final int SEND_STATE_SENDING = 4; 1979340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen static final int SEND_STATE_COMPLETE = 5; 1989340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen static final int SEND_STATE_CANCELED = 6; 19977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 200a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen // return values for doSnepProtocol 201a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen static final int SNEP_SUCCESS = 0; 202a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen static final int SNEP_FAILURE = 1; 2033329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 2043329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // return values for doHandover 2053329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen static final int HANDOVER_SUCCESS = 0; 2063329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen static final int HANDOVER_FAILURE = 1; 2073329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen static final int HANDOVER_UNSUPPORTED = 2; 208aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales static final int HANDOVER_BUSY = 3; 20977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 21077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final NdefPushServer mNdefPushServer; 21177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final SnepServer mDefaultSnepServer; 212f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen final HandoverServer mHandoverServer; 2136f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen final EchoServer mEchoServer; 21477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final Context mContext; 21577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final P2pEventListener mEventListener; 21677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final Handler mHandler; 217b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales final HandoverDataParser mHandoverDataParser; 21834322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen final ForegroundUtils mForegroundUtils; 21977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 220525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project final int mDefaultMiu; 221525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project final int mDefaultRwSize; 222525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project 22377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly // Locked on NdefP2pManager.this 2243859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen PackageManager mPackageManager; 22577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly int mLinkState; 22677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly int mSendState; // valid during LINK_STATE_UP or LINK_STATE_DEBOUNCE 22777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly boolean mIsSendEnabled; 22877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly boolean mIsReceiveEnabled; 2293329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen NdefMessage mMessageToSend; // not valid in SEND_STATE_NOTHING_TO_SEND 2303329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen Uri[] mUrisToSend; // not valid in SEND_STATE_NOTHING_TO_SEND 231b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales UserHandle mUserHandle; // not valid in SEND_STATE_NOTHING_TO_SEND 232cbe27470ef7e67324b9e8cbc32c25088d82e2a86Martijn Coenen int mSendFlags; // not valid in SEND_STATE_NOTHING_TO_SEND 23331f39aee25964dad1038b7a9cc335d5a386113c8Martijn Coenen IAppCallback mCallbackNdef; 23434322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen int mNdefCallbackUid; 23577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly SendTask mSendTask; 236416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton SharedPreferences mPrefs; 2373329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen SnepClient mSnepClient; 2383329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen HandoverClient mHandoverClient; 2393329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen NdefPushClient mNdefPushClient; 2403329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen ConnectTask mConnectTask; 2413329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen boolean mLlcpServicesConnected; 24257a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen long mLastLlcpActivationTime; 2432daeeee63456a515693980372908234e1fa14ba5Martijn Coenen byte mPeerLlcpVersion; 24477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 245b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales public P2pLinkManager(Context context, HandoverDataParser handoverDataParser, int defaultMiu, 246525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project int defaultRwSize) { 24777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mNdefPushServer = new NdefPushServer(NDEFPUSH_SAP, mNppCallback); 248525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project mDefaultSnepServer = new SnepServer(mDefaultSnepCallback, defaultMiu, defaultRwSize); 249b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mHandoverServer = new HandoverServer(context, HANDOVER_SAP, handoverDataParser, mHandoverCallback); 250f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen 2516f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen if (ECHOSERVER_ENABLED) { 2526f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mEchoServer = new EchoServer(); 2536f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } else { 2546f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mEchoServer = null; 2556f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } 25677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mPackageManager = context.getPackageManager(); 25777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mContext = context; 25877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mEventListener = new P2pEventManager(context, this); 25977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mHandler = new Handler(this); 26077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mLinkState = LINK_STATE_DOWN; 26177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendState = SEND_STATE_NOTHING_TO_SEND; 26277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mIsSendEnabled = false; 26377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mIsReceiveEnabled = false; 264416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton mPrefs = context.getSharedPreferences(NfcService.PREF, Context.MODE_PRIVATE); 265b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mHandoverDataParser = handoverDataParser; 266525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project mDefaultMiu = defaultMiu; 267525c260303268a83da4c3413b953d13c9084e834The Android Open Source Project mDefaultRwSize = defaultRwSize; 2683329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mLlcpServicesConnected = false; 26934322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mNdefCallbackUid = -1; 27034322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mForegroundUtils = ForegroundUtils.getInstance(); 27177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 27277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 27377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 27477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * May be called from any thread. 27577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Assumes that NFC is already on if any parameter is true. 27677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 27777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void enableDisable(boolean sendEnable, boolean receiveEnable) { 27877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 27977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (!mIsReceiveEnabled && receiveEnable) { 28077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mDefaultSnepServer.start(); 28177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mNdefPushServer.start(); 282f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen mHandoverServer.start(); 2836f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen if (mEchoServer != null) { 2846f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mHandler.sendEmptyMessage(MSG_START_ECHOSERVER); 2856f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } 28677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } else if (mIsReceiveEnabled && !receiveEnable) { 287a8aa07142ea0078d3ae4ae486e094e2f2f4ff732Evan Chu if (DBG) Log.d(TAG, "enableDisable: llcp deactivate"); 288a8aa07142ea0078d3ae4ae486e094e2f2f4ff732Evan Chu onLlcpDeactivated (); 28977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mDefaultSnepServer.stop(); 29077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mNdefPushServer.stop(); 291f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen mHandoverServer.stop(); 2926f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen if (mEchoServer != null) { 2936f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mHandler.sendEmptyMessage(MSG_STOP_ECHOSERVER); 2946f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } 29577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 29677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mIsSendEnabled = sendEnable; 29777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mIsReceiveEnabled = receiveEnable; 29877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 29977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 30077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 30177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 3027a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen * May be called from any thread. 3037a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen * @return whether the LLCP link is in an active or debounce state 3047a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen */ 3057a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen public boolean isLlcpActive() { 3067a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen synchronized (this) { 3077a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen return mLinkState != LINK_STATE_DOWN; 3087a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen } 3097a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen } 3107a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen 3117a499e775021bafefbe890d079e2a43f4a54482cMartijn Coenen /** 312c96f982f8c0fa061701143a27395acf3b24dfb54Nick Pelly * Set NDEF callback for sending. 31377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * May be called from any thread. 314c96f982f8c0fa061701143a27395acf3b24dfb54Nick Pelly * NDEF callbacks may be set at any time (even if NFC is 31577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * currently off or P2P send is currently off). They will become 31677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * active as soon as P2P send is enabled. 31777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 31831f39aee25964dad1038b7a9cc335d5a386113c8Martijn Coenen public void setNdefCallback(IAppCallback callbackNdef, int callingUid) { 31977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 32077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mCallbackNdef = callbackNdef; 32134322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mNdefCallbackUid = callingUid; 32277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 32377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 32477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 3259340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 3269340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen public void onManualBeamInvoke(BeamShareData shareData) { 3279340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen synchronized (P2pLinkManager.this) { 3289340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if (mLinkState != LINK_STATE_DOWN) { 3299340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen return; 3309340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 331c4ff3393f54403064b237349277cbf65f3277285Martijn Coenen if (mForegroundUtils.getForegroundUids().contains(mNdefCallbackUid)) { 33234322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen // Try to get data from the registered NDEF callback 33334322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen prepareMessageToSend(false); 334794585174b5812f47c4fbc3cc34184f4379bdbb8Alex Chau } else { 335794585174b5812f47c4fbc3cc34184f4379bdbb8Alex Chau mMessageToSend = null; 336794585174b5812f47c4fbc3cc34184f4379bdbb8Alex Chau mUrisToSend = null; 33734322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen } 3389340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if (mMessageToSend == null && mUrisToSend == null && shareData != null) { 33934322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen // No data from the NDEF callback, get data from ShareData 3409340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if (shareData.uris != null) { 3419340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mUrisToSend = shareData.uris; 3429340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } else if (shareData.ndefMessage != null) { 3439340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mMessageToSend = shareData.ndefMessage; 3449340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 34595302c119feba7f50a5193861619346908a96164Andres Morales 34695302c119feba7f50a5193861619346908a96164Andres Morales mUserHandle = shareData.userHandle; 3479340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 3489340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if (mMessageToSend != null || 349b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales (mUrisToSend != null && mHandoverDataParser.isHandoverSupported())) { 3509340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_PENDING; 3519340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mEventListener.onP2pNfcTapRequested(); 3529340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen scheduleTimeoutLocked(MSG_WAIT_FOR_LINK_TIMEOUT, WAIT_FOR_LINK_TIMEOUT_MS); 3539340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 3549340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 3559340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 3569340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 35777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 35877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Must be called on UI Thread. 35977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 3602daeeee63456a515693980372908234e1fa14ba5Martijn Coenen public void onLlcpActivated(byte peerLlcpVersion) { 36177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly Log.i(TAG, "LLCP activated"); 36277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (P2pLinkManager.this) { 3636f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen if (mEchoServer != null) { 3646f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mEchoServer.onLlcpActivated(); 3656f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } 36657a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen mLastLlcpActivationTime = SystemClock.elapsedRealtime(); 3672daeeee63456a515693980372908234e1fa14ba5Martijn Coenen mPeerLlcpVersion = peerLlcpVersion; 36877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly switch (mLinkState) { 36977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_DOWN: 37077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (DBG) Log.d(TAG, "onP2pInRange()"); 371ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // Start taking a screenshot 37277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mEventListener.onP2pInRange(); 373ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen mLinkState = LINK_STATE_UP; 374ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // If we had a pending send (manual Beam invoke), 375ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // mark it as sending 3769340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if (mSendState == SEND_STATE_PENDING) { 3779340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_SENDING; 378ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen mHandler.removeMessages(MSG_WAIT_FOR_LINK_TIMEOUT); 379ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // Immediately try to connect LLCP services 380ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen connectLlcpServices(); 3819340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } else { 3829340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_NOTHING_TO_SEND; 3839340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen prepareMessageToSend(true); 3849340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if (mMessageToSend != null || 385b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales (mUrisToSend != null && mHandoverDataParser.isHandoverSupported())) { 386ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // We have data to send, connect LLCP services 387ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen connectLlcpServices(); 3889340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if ((mSendFlags & NfcAdapter.FLAG_NDEF_PUSH_NO_CONFIRM) != 0) { 3899340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_SENDING; 3909340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } else { 3919340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_NEED_CONFIRMATION; 3929340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 393cbe27470ef7e67324b9e8cbc32c25088d82e2a86Martijn Coenen } 39477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 39577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 39677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_UP: 39777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (DBG) Log.d(TAG, "Duplicate onLlcpActivated()"); 39877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return; 39977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_DEBOUNCE: 400ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // Immediately connect and try to send again 401ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen mLinkState = LINK_STATE_UP; 402ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen if (mSendState == SEND_STATE_SENDING || 403ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen mSendState == SEND_STATE_NEED_CONFIRMATION) { 404ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // If we have something to send still, connect LLCP 40557a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen connectLlcpServices(); 40657a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen } 40777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mHandler.removeMessages(MSG_DEBOUNCE_TIMEOUT); 40857a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen break; 40957a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen } 41057a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen } 41157a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen } 41257a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen 41357a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen /** 41457a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen * Must be called on UI Thread. 41557a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen */ 41657a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen public void onLlcpFirstPacketReceived() { 41757a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen synchronized (P2pLinkManager.this) { 41857a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen long totalTime = SystemClock.elapsedRealtime() - mLastLlcpActivationTime; 41957a44d07a3de327e8cdbbcd622118aa517313dbeMartijn Coenen if (DBG) Log.d(TAG, "Took " + Long.toString(totalTime) + " to get first LLCP PDU"); 42077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 42177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 42277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 423d2604c0544f7bc26e5b2407f0215cccfffedae2cAndres Morales public void onUserSwitched(int userId) { 4243859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen // Update the cached package manager in case of user switch 4253859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen synchronized (P2pLinkManager.this) { 4263859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen try { 4273859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen mPackageManager = mContext.createPackageContextAsUser("android", 0, 428d2604c0544f7bc26e5b2407f0215cccfffedae2cAndres Morales new UserHandle(userId)).getPackageManager(); 4293859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen } catch (NameNotFoundException e) { 4303859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen Log.e(TAG, "Failed to retrieve PackageManager for user"); 4313859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen } 4323859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen } 4333859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen } 4343859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen 4359340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen void prepareMessageToSend(boolean generatePlayLink) { 43677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (P2pLinkManager.this) { 43734322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mMessageToSend = null; 43834322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mUrisToSend = null; 43977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (!mIsSendEnabled) { 44077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return; 44177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 44277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 443c4ff3393f54403064b237349277cbf65f3277285Martijn Coenen List<Integer> foregroundUids = mForegroundUtils.getForegroundUids(); 444c4ff3393f54403064b237349277cbf65f3277285Martijn Coenen if (foregroundUids.isEmpty()) { 44534322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen Log.e(TAG, "Could not determine foreground UID."); 4463859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen return; 4473859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen } 4483859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen 4495697d20844cf52e71aa9125ac1fbfc9436bd8ed5Alex Chau if (isBeamDisabled(foregroundUids.get(0))) { 4505697d20844cf52e71aa9125ac1fbfc9436bd8ed5Alex Chau if (DBG) Log.d(TAG, "Beam is disabled by policy."); 4515697d20844cf52e71aa9125ac1fbfc9436bd8ed5Alex Chau return; 4525697d20844cf52e71aa9125ac1fbfc9436bd8ed5Alex Chau } 4535697d20844cf52e71aa9125ac1fbfc9436bd8ed5Alex Chau 454fb42b9f2d905015730f2e12772ed9a2a610a3957Isaac Levy if (mCallbackNdef != null) { 455c4ff3393f54403064b237349277cbf65f3277285Martijn Coenen if (foregroundUids.contains(mNdefCallbackUid)) { 4563859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen try { 4572daeeee63456a515693980372908234e1fa14ba5Martijn Coenen BeamShareData shareData = mCallbackNdef.createBeamShareData(mPeerLlcpVersion); 458cbe27470ef7e67324b9e8cbc32c25088d82e2a86Martijn Coenen mMessageToSend = shareData.ndefMessage; 459cbe27470ef7e67324b9e8cbc32c25088d82e2a86Martijn Coenen mUrisToSend = shareData.uris; 460b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mUserHandle = shareData.userHandle; 461cbe27470ef7e67324b9e8cbc32c25088d82e2a86Martijn Coenen mSendFlags = shareData.flags; 4623859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen return; 4635bacd361e693472b7d54d31fe0d23b9d22851988Martijn Coenen } catch (Exception e) { 46495302c119feba7f50a5193861619346908a96164Andres Morales Log.e(TAG, "Failed NDEF callback: ", e); 4653859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen } 466eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen } else { 4673859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen // This is not necessarily an error - we no longer unset callbacks from 4683859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen // the app process itself (to prevent IPC calls on every pause). 4693859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen // Hence it may simply be a stale callback. 4703859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen if (DBG) Log.d(TAG, "Last registered callback is not running in the foreground."); 471eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen } 4723859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen } 4733859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen 4743859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen // fall back to default NDEF for the foreground activity, unless the 4753859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen // application disabled this explicitly in their manifest. 476c4ff3393f54403064b237349277cbf65f3277285Martijn Coenen String[] pkgs = mPackageManager.getPackagesForUid(foregroundUids.get(0)); 47734322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen if (pkgs != null && pkgs.length >= 1) { 4785697d20844cf52e71aa9125ac1fbfc9436bd8ed5Alex Chau if (!generatePlayLink || beamDefaultDisabled(pkgs[0])) { 47934322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen if (DBG) Log.d(TAG, "Disabling default Beam behavior"); 48034322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mMessageToSend = null; 48134322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mUrisToSend = null; 48234322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen } else { 48334322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mMessageToSend = createDefaultNdef(pkgs[0]); 48434322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen mUrisToSend = null; 485e15820b67fea55fbe84103ab38e2adc22fab99d8Peng Sun mSendFlags = 0; 48634322b73c1e09907cb007e86bae77c744b338cd7Martijn Coenen } 487eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen } 4883859c5cccb202c20882fb3887cfa87babb1d85a3Martijn Coenen 48943f2fa7ad4c72ef4849f2d2b78a963c1925c63a3Nick Pelly if (DBG) Log.d(TAG, "mMessageToSend = " + mMessageToSend); 49083558889207858d7ce8500f9fce8a707a86b495eMartijn Coenen if (DBG) Log.d(TAG, "mUrisToSend = " + mUrisToSend); 49177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 49277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 49377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 49465860bb589c5802ffadb14540670408d6c8dfaa9Benjamin Franz private boolean isBeamDisabled(int uid) { 4955c452dad7b24f28223414ce5e953bfcab782570eAndres Morales UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 496b42756d47f39774a07654f68af27bf3cc2c41511Andres Morales UserInfo userInfo = userManager.getUserInfo(UserHandle.getUserId(uid)); 49765860bb589c5802ffadb14540670408d6c8dfaa9Benjamin Franz return userManager.hasUserRestriction( 498b42756d47f39774a07654f68af27bf3cc2c41511Andres Morales UserManager.DISALLOW_OUTGOING_BEAM, userInfo.getUserHandle()); 499b42756d47f39774a07654f68af27bf3cc2c41511Andres Morales 5005c452dad7b24f28223414ce5e953bfcab782570eAndres Morales } 5015c452dad7b24f28223414ce5e953bfcab782570eAndres Morales 502eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen boolean beamDefaultDisabled(String pkgName) { 503eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen try { 504eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen ApplicationInfo ai = mPackageManager.getApplicationInfo(pkgName, 505eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen PackageManager.GET_META_DATA); 506eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen if (ai == null || ai.metaData == null) { 507eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen return false; 508eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen } 509eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen return ai.metaData.getBoolean(DISABLE_BEAM_DEFAULT); 510eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen } catch (NameNotFoundException e) { 511eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen return false; 51277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 513eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen } 514eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen 515eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen NdefMessage createDefaultNdef(String pkgName) { 516eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen NdefRecord appUri = NdefRecord.createUri(Uri.parse( 517eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen "http://play.google.com/store/apps/details?id=" + pkgName + "&feature=beam")); 518eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen NdefRecord appRecord = NdefRecord.createApplicationRecord(pkgName); 519eec585407f2cfc47814f572a1e2a0f7d56b41451Martijn Coenen return new NdefMessage(new NdefRecord[] { appUri, appRecord }); 52077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 52177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 5223329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen void disconnectLlcpServices() { 5233329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen synchronized (this) { 5243329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mConnectTask != null) { 5253329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mConnectTask.cancel(true); 5263329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mConnectTask = null; 5273329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 5283329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // Close any already connected LLCP clients 5293329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mNdefPushClient != null) { 5303329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mNdefPushClient.close(); 5313329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mNdefPushClient = null; 5323329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 5333329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mSnepClient != null) { 5343329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mSnepClient.close(); 5353329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mSnepClient = null; 5363329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 5373329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mHandoverClient != null) { 5383329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mHandoverClient.close(); 5393329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mHandoverClient = null; 5403329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 5413329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mLlcpServicesConnected = false; 5423329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 5433329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 5443329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 54577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly /** 54677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly * Must be called on UI Thread. 54777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly */ 54877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void onLlcpDeactivated() { 54977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly Log.i(TAG, "LLCP deactivated."); 55077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 5516f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen if (mEchoServer != null) { 5526f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mEchoServer.onLlcpDeactivated(); 5536f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } 5546f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen 55577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly switch (mLinkState) { 55677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_DOWN: 55777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_DEBOUNCE: 55877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly Log.i(TAG, "Duplicate onLlcpDectivated()"); 55977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 56077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_UP: 56177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly // Debounce 56277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mLinkState = LINK_STATE_DEBOUNCE; 5631a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen int debounceTimeout = 0; 5641a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen switch (mSendState) { 5651a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen case SEND_STATE_NOTHING_TO_SEND: 5661a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen debounceTimeout = 0; 5671a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen break; 5681a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen case SEND_STATE_NEED_CONFIRMATION: 5691a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen debounceTimeout = LINK_SEND_PENDING_DEBOUNCE_MS; 5701a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen break; 5711a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen case SEND_STATE_SENDING: 5721a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen debounceTimeout = LINK_SEND_CONFIRMED_DEBOUNCE_MS; 5731a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen break; 5749340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen case SEND_STATE_COMPLETE: 5751a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen debounceTimeout = LINK_SEND_COMPLETE_DEBOUNCE_MS; 5761a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen break; 5779340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen case SEND_STATE_CANCELED: 5789340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen debounceTimeout = LINK_SEND_CANCELED_DEBOUNCE_MS; 5791a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen } 5809340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen scheduleTimeoutLocked(MSG_DEBOUNCE_TIMEOUT, debounceTimeout); 5811a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen if (mSendState == SEND_STATE_SENDING) { 5821a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen Log.e(TAG, "onP2pSendDebounce()"); 5831a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen mEventListener.onP2pSendDebounce(); 5841a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen } 58577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly cancelSendNdefMessage(); 5863329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen disconnectLlcpServices(); 58777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 58877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 58977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 59077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 59177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 592a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen void onHandoverUnsupported() { 593a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen mHandler.sendEmptyMessage(MSG_HANDOVER_NOT_SUPPORTED); 594a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen } 595a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen 596aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales void onHandoverBusy() { 597aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales mHandler.sendEmptyMessage(MSG_HANDOVER_BUSY); 598aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales } 599aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales 600416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton void onSendComplete(NdefMessage msg, long elapsedRealtime) { 60177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly // Make callbacks on UI thread 6028a558ba19be56e71e6c2015dea862d150e6d07cbNick Pelly mHandler.sendEmptyMessage(MSG_SEND_COMPLETE); 60377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 60477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 60577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly void sendNdefMessage() { 60677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 60777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly cancelSendNdefMessage(); 60877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendTask = new SendTask(); 60977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendTask.execute(); 61077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 61177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 61277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 61377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly void cancelSendNdefMessage() { 61477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (P2pLinkManager.this) { 61577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (mSendTask != null) { 61677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendTask.cancel(true); 61777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 61877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 61977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 62077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 6213329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen void connectLlcpServices() { 6223329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen synchronized (P2pLinkManager.this) { 6233329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mConnectTask != null) { 6243329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen Log.e(TAG, "Still had a reference to mConnectTask!"); 6253329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6263329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mConnectTask = new ConnectTask(); 6273329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mConnectTask.execute(); 6283329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6293329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6303329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 6313329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // Must be called on UI-thread 6323329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen void onLlcpServicesConnected() { 6333329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (DBG) Log.d(TAG, "onLlcpServicesConnected"); 6343329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen synchronized (P2pLinkManager.this) { 6353329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mLinkState != LINK_STATE_UP) { 6363329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return; 6373329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6383329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mLlcpServicesConnected = true; 639ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen if (mSendState == SEND_STATE_NEED_CONFIRMATION) { 640ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen if (DBG) Log.d(TAG, "onP2pSendConfirmationRequested()"); 641ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen mEventListener.onP2pSendConfirmationRequested(); 642ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen } else if (mSendState == SEND_STATE_SENDING) { 6431a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen mEventListener.onP2pResumeSend(); 6443329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen sendNdefMessage(); 6453329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } else { 646ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen // Either nothing to send or canceled/complete, ignore 6473329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6483329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6493329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6503329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 6513329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen final class ConnectTask extends AsyncTask<Void, Void, Boolean> { 6523329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen @Override 6533329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen protected void onPostExecute(Boolean result) { 6543329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (isCancelled()) { 6553329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (DBG) Log.d(TAG, "ConnectTask was cancelled"); 6563329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return; 6573329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6583329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (result) { 6593329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen onLlcpServicesConnected(); 6603329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } else { 6613329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen Log.e(TAG, "Could not connect required NFC transports"); 6623329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6633329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6643329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 6653329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen @Override 6663329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen protected Boolean doInBackground(Void... params) { 6673329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen boolean needsHandover = false; 6683329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen boolean needsNdef = false; 6693329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen boolean success = false; 6703329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen HandoverClient handoverClient = null; 6713329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen SnepClient snepClient = null; 6723329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen NdefPushClient nppClient = null; 6733329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 6743329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen synchronized(P2pLinkManager.this) { 6753329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mUrisToSend != null) { 6763329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen needsHandover = true; 6773329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6783329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 6793329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (mMessageToSend != null) { 6803329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen needsNdef = true; 6813329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6823329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6833329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // We know either is requested - otherwise this task 6843329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // wouldn't have been started. 6853329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (needsHandover) { 6863329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen handoverClient = new HandoverClient(); 6873329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen try { 6883329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen handoverClient.connect(); 6893329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen success = true; // Regardless of NDEF result 6903329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } catch (IOException e) { 6913329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen handoverClient = null; 6923329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6933329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 6943329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 695d72b205b870f4bccb33d466a0b4f704aca8d060aMartijn Coenen if (needsNdef || (needsHandover && handoverClient == null)) { 6963329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen snepClient = new SnepClient(); 6973329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen try { 6983329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen snepClient.connect(); 6993329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen success = true; 7003329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } catch (IOException e) { 7013329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen snepClient = null; 7023329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7033329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 7043329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (!success) { 7053329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen nppClient = new NdefPushClient(); 7063329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen try { 7073329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen nppClient.connect(); 7083329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen success = true; 7093329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } catch (IOException e) { 7103329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen nppClient = null; 7113329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7123329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7133329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7143329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 7153329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen synchronized (P2pLinkManager.this) { 7163329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (isCancelled()) { 7173329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // Cancelled by onLlcpDeactivated on UI thread 7183329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (handoverClient != null) { 7193329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen handoverClient.close(); 7203329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7213329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (snepClient != null) { 7223329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen snepClient.close(); 7233329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7243329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (nppClient != null) { 7253329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen nppClient.close(); 7263329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7273329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return false; 7283329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } else { 7293329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // Once assigned, these are the responsibility of 7303329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // the code on the UI thread to release - typically 7313329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // through onLlcpDeactivated(). 7323329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mHandoverClient = handoverClient; 7333329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mSnepClient = snepClient; 7343329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen mNdefPushClient = nppClient; 7353329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return success; 7363329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7373329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7383329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7393329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen }; 7403329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 74177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final class SendTask extends AsyncTask<Void, Void, Void> { 7423329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen NdefPushClient nppClient; 7433329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen SnepClient snepClient; 7443329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen HandoverClient handoverClient; 7453329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 746b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales int doHandover(Uri[] uris, UserHandle userHandle) throws IOException { 7473329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen NdefMessage response = null; 748b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales BeamManager beamManager = BeamManager.getInstance(); 749b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 750b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales if (beamManager.isBeamInProgress()) { 751aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales return HANDOVER_BUSY; 752b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 753b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 754b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales NdefMessage request = mHandoverDataParser.createHandoverRequestMessage(); 7553329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (request != null) { 7563329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (handoverClient != null) { 7573329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen response = handoverClient.sendHandoverRequest(request); 7583329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7593329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (response == null && snepClient != null) { 7603329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // Remote device may not support handover service, 7613329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // try the (deprecated) SNEP GET implementation 7623329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen // for devices running Android 4.1 7633329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen SnepMessage snepResponse = snepClient.get(request); 7643329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen response = snepResponse.getNdefMessage(); 7653329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7663329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (response == null) { 76773c03d85bfdfc8c4e1255ede5231991bce5e575aRuchi Kandoi if (snepClient != null) 76873c03d85bfdfc8c4e1255ede5231991bce5e575aRuchi Kandoi return HANDOVER_UNSUPPORTED; 76973c03d85bfdfc8c4e1255ede5231991bce5e575aRuchi Kandoi else 77073c03d85bfdfc8c4e1255ede5231991bce5e575aRuchi Kandoi return HANDOVER_FAILURE; 7713329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7723329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } else { 7733329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return HANDOVER_UNSUPPORTED; 7743329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 775b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 776aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales if (!beamManager.startBeamSend(mContext, 777b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales mHandoverDataParser.getOutgoingHandoverData(response), uris, userHandle)) { 778aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales return HANDOVER_BUSY; 779b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales } 780b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales 781aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales return HANDOVER_SUCCESS; 7823329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7833329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 7843329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen int doSnepProtocol(NdefMessage msg) throws IOException { 7853329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (msg != null) { 7863329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen snepClient.put(msg); 7873329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return SNEP_SUCCESS; 7883329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } else { 7893329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return SNEP_FAILURE; 7903329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7913329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 7923329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen 79377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly @Override 79477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public Void doInBackground(Void... args) { 79577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly NdefMessage m; 79683558889207858d7ce8500f9fce8a707a86b495eMartijn Coenen Uri[] uris; 797b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales UserHandle userHandle; 7983329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen boolean result = false; 79977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 80077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (P2pLinkManager.this) { 80177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (mLinkState != LINK_STATE_UP || mSendState != SEND_STATE_SENDING) { 80277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return null; 80377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 80477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly m = mMessageToSend; 80583558889207858d7ce8500f9fce8a707a86b495eMartijn Coenen uris = mUrisToSend; 806b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales userHandle = mUserHandle; 8073329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen snepClient = mSnepClient; 8083329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen handoverClient = mHandoverClient; 8093329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen nppClient = mNdefPushClient; 81077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 81177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 812416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton long time = SystemClock.elapsedRealtime(); 81343f2fa7ad4c72ef4849f2d2b78a963c1925c63a3Nick Pelly 8143329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (uris != null) { 8153329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (DBG) Log.d(TAG, "Trying handover request"); 8163329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen try { 817b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales int handoverResult = doHandover(uris, userHandle); 8183329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen switch (handoverResult) { 8193329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen case HANDOVER_SUCCESS: 8203329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = true; 8213329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen break; 8223329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen case HANDOVER_FAILURE: 8233329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = false; 8243329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen break; 8253329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen case HANDOVER_UNSUPPORTED: 8263329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = false; 8273329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen onHandoverUnsupported(); 8283329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen break; 829aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales case HANDOVER_BUSY: 830aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales result = false; 831aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales onHandoverBusy(); 832aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales break; 8333329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 8343329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } catch (IOException e) { 8353329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = false; 83677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 8373329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 83877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 8393329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (!result && m != null && snepClient != null) { 8403329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (DBG) Log.d(TAG, "Sending ndef via SNEP"); 8413329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen try { 8423329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen int snepResult = doSnepProtocol(m); 8433329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen switch (snepResult) { 8443329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen case SNEP_SUCCESS: 8453329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = true; 8463329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen break; 8473329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen case SNEP_FAILURE: 8483329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = false; 8493329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen break; 8503329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen default: 8513329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = false; 8523329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 8533329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } catch (IOException e) { 8540f2b555fe51f3d8a828cf61d269b8be6eecbf68bMartijn Coenen result = false; 8550f2b555fe51f3d8a828cf61d269b8be6eecbf68bMartijn Coenen } 85677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 857416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton 8583329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (!result && m != null && nppClient != null) { 8593329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen result = nppClient.push(m); 8603329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen } 861416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton 8623329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen time = SystemClock.elapsedRealtime() - time; 8633329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen if (DBG) Log.d(TAG, "SendTask result=" + result + ", time ms=" + time); 8648a558ba19be56e71e6c2015dea862d150e6d07cbNick Pelly if (result) { 865416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton onSendComplete(m, time); 8668a558ba19be56e71e6c2015dea862d150e6d07cbNick Pelly } 86777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 8683329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen return null; 86977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 8703329e45c618c5896cb662f686930a75eb2ee5bbcMartijn Coenen }; 87177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 87277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 873f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen final HandoverServer.Callback mHandoverCallback = new HandoverServer.Callback() { 874f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen @Override 875f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen public void onHandoverRequestReceived() { 876f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen onReceiveHandover(); 877f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen } 878aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales 879aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales @Override 880aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales public void onHandoverBusy() { 8813ac6710f5a6cf7a9948046abd71f732eebe770b9Satoshi Fujita P2pLinkManager.this.onHandoverBusy(); 882aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales } 883f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen }; 884f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen 88577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final NdefPushServer.Callback mNppCallback = new NdefPushServer.Callback() { 88677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly @Override 88777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void onMessageReceived(NdefMessage msg) { 88877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly onReceiveComplete(msg); 88977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 89077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly }; 89177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 89277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly final SnepServer.Callback mDefaultSnepCallback = new SnepServer.Callback() { 89377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly @Override 89477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public SnepMessage doPut(NdefMessage msg) { 89577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly onReceiveComplete(msg); 89677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return SnepMessage.getMessage(SnepMessage.RESPONSE_SUCCESS); 89777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 89877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 89977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly @Override 90077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public SnepMessage doGet(int acceptableLength, NdefMessage msg) { 901f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen // The NFC Forum Default SNEP server is not allowed to respond to 902f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen // SNEP GET requests - see SNEP 1.0 TS section 6.1. However, 903f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen // since Android 4.1 used the NFC Forum default server to 904f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen // implement connection handover, we will support this 905f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen // until we can deprecate it. 906b82d80d891077ccd74729e4143925a66eb89eef2Andres Morales NdefMessage response = mHandoverDataParser.getIncomingHandoverData(msg).handoverSelect; 90743f2fa7ad4c72ef4849f2d2b78a963c1925c63a3Nick Pelly if (response != null) { 908d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen onReceiveHandover(); 90943f2fa7ad4c72ef4849f2d2b78a963c1925c63a3Nick Pelly return SnepMessage.getSuccessResponse(response); 91043f2fa7ad4c72ef4849f2d2b78a963c1925c63a3Nick Pelly } else { 911f5a196b643c654c7ea98a5e2935e3bff6683399bMartijn Coenen return SnepMessage.getMessage(SnepMessage.RESPONSE_NOT_IMPLEMENTED); 91243f2fa7ad4c72ef4849f2d2b78a963c1925c63a3Nick Pelly } 91377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 91477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly }; 91577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 916d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen void onReceiveHandover() { 917d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen mHandler.obtainMessage(MSG_RECEIVE_HANDOVER).sendToTarget(); 918d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen } 919d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen 92077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly void onReceiveComplete(NdefMessage msg) { 92177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly // Make callbacks on UI thread 92277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mHandler.obtainMessage(MSG_RECEIVE_COMPLETE, msg).sendToTarget(); 92377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 92477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 92577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly @Override 92677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public boolean handleMessage(Message msg) { 92777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly switch (msg.what) { 9286f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen case MSG_START_ECHOSERVER: 9296f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen synchronized (this) { 9306f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mEchoServer.start(); 9316f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen break; 9326f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } 9336f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen case MSG_STOP_ECHOSERVER: 9346f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen synchronized (this) { 9356f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen mEchoServer.stop(); 9366f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen break; 9376f0e3b8e1de5137077127bf3144effa2016c27c6Martijn Coenen } 9389340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen case MSG_WAIT_FOR_LINK_TIMEOUT: 9399340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen synchronized (this) { 9409340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // User wanted to send something but no link 9419340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // came up. Just cancel the send 9429340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_NOTHING_TO_SEND; 9439340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mEventListener.onP2pTimeoutWaitingForLink(); 9449340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 9459340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen break; 94677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case MSG_DEBOUNCE_TIMEOUT: 94777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 94877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (mLinkState != LINK_STATE_DEBOUNCE) { 94977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 95077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 95177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (DBG) Log.d(TAG, "Debounce timeout"); 95277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mLinkState = LINK_STATE_DOWN; 95377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendState = SEND_STATE_NOTHING_TO_SEND; 95477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mMessageToSend = null; 95583558889207858d7ce8500f9fce8a707a86b495eMartijn Coenen mUrisToSend = null; 95677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (DBG) Log.d(TAG, "onP2pOutOfRange()"); 95777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mEventListener.onP2pOutOfRange(); 95877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 95977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 960d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen case MSG_RECEIVE_HANDOVER: 961d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen // We're going to do a handover request 962d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen synchronized (this) { 963d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen if (mLinkState == LINK_STATE_DOWN) { 964d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen break; 965d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen } 966d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen if (mSendState == SEND_STATE_SENDING) { 967d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen cancelSendNdefMessage(); 968d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen } 969d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen mSendState = SEND_STATE_NOTHING_TO_SEND; 970d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen if (DBG) Log.d(TAG, "onP2pReceiveComplete()"); 971d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen mEventListener.onP2pReceiveComplete(false); 972d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen } 973d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen break; 97477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case MSG_RECEIVE_COMPLETE: 97577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly NdefMessage m = (NdefMessage) msg.obj; 97677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 97777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (mLinkState == LINK_STATE_DOWN) { 97877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 97977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 98077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (mSendState == SEND_STATE_SENDING) { 98177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly cancelSendNdefMessage(); 98277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 98377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendState = SEND_STATE_NOTHING_TO_SEND; 98477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (DBG) Log.d(TAG, "onP2pReceiveComplete()"); 985d82d9db81f30ccecd29a0531e6db9b49c9c2cd95Martijn Coenen mEventListener.onP2pReceiveComplete(true); 98677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly NfcService.getInstance().sendMockNdefTag(m); 98777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 98877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 989a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen case MSG_HANDOVER_NOT_SUPPORTED: 990a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen synchronized (P2pLinkManager.this) { 991a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen mSendTask = null; 992a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen 993a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen if (mLinkState == LINK_STATE_DOWN || mSendState != SEND_STATE_SENDING) { 994a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen break; 995a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen } 996a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen mSendState = SEND_STATE_NOTHING_TO_SEND; 997a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen if (DBG) Log.d(TAG, "onP2pHandoverNotSupported()"); 998a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen mEventListener.onP2pHandoverNotSupported(); 999a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen } 1000a3715d12aeba988c1104726e935462ea4f39eca7Martijn Coenen break; 100177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case MSG_SEND_COMPLETE: 100277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (P2pLinkManager.this) { 100377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendTask = null; 100477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 100577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (mLinkState == LINK_STATE_DOWN || mSendState != SEND_STATE_SENDING) { 100677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 100777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 10089340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_COMPLETE; 10091a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen mHandler.removeMessages(MSG_DEBOUNCE_TIMEOUT); 101077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (DBG) Log.d(TAG, "onP2pSendComplete()"); 10118a558ba19be56e71e6c2015dea862d150e6d07cbNick Pelly mEventListener.onP2pSendComplete(); 101277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (mCallbackNdef != null) { 101377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly try { 10142daeeee63456a515693980372908234e1fa14ba5Martijn Coenen mCallbackNdef.onNdefPushComplete(mPeerLlcpVersion); 10155bacd361e693472b7d54d31fe0d23b9d22851988Martijn Coenen } catch (Exception e) { 10165bacd361e693472b7d54d31fe0d23b9d22851988Martijn Coenen Log.e(TAG, "Failed NDEF completed callback: " + e.getMessage()); 10175bacd361e693472b7d54d31fe0d23b9d22851988Martijn Coenen } 101877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 101977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 102077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly break; 1021aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales case MSG_HANDOVER_BUSY: 1022aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales synchronized (P2pLinkManager.this) { 1023aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales mSendTask = null; 1024aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales 1025aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales if (mLinkState == LINK_STATE_DOWN || mSendState != SEND_STATE_SENDING) { 1026aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales break; 1027aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales } 1028aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales mSendState = SEND_STATE_NOTHING_TO_SEND; 1029aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales if (DBG) Log.d(TAG, "onP2pHandoverBusy()"); 1030aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales mEventListener.onP2pHandoverBusy(); 1031aaca83594d177442e993a8ba68349a5f7cb31200Andres Morales } 103277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 103377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return true; 103477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 103577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 1036416e2fc507d696486a127f932105b3b95519d0cbJeff Hamilton 103777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly @Override 103877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly public void onP2pSendConfirmed() { 1039cf4ef456bbf2c10f674b291ef7960af8b6bf6efaEmily Bernier onP2pSendConfirmed(true); 1040cf4ef456bbf2c10f674b291ef7960af8b6bf6efaEmily Bernier } 1041cf4ef456bbf2c10f674b291ef7960af8b6bf6efaEmily Bernier 1042cf4ef456bbf2c10f674b291ef7960af8b6bf6efaEmily Bernier private void onP2pSendConfirmed(boolean requireConfirmation) { 104377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly if (DBG) Log.d(TAG, "onP2pSendConfirmed()"); 104477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 1045cf4ef456bbf2c10f674b291ef7960af8b6bf6efaEmily Bernier if (mLinkState == LINK_STATE_DOWN || (requireConfirmation 1046cf4ef456bbf2c10f674b291ef7960af8b6bf6efaEmily Bernier && mSendState != SEND_STATE_NEED_CONFIRMATION)) { 104777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return; 104877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 104977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly mSendState = SEND_STATE_SENDING; 1050ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen if (mLinkState == LINK_STATE_UP) { 1051ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen if (mLlcpServicesConnected) { 1052ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen sendNdefMessage(); 1053ddefd2afcd6b09c3a48db4b2f69377dbc3a8a282Martijn Coenen } // else, will send messages when link comes up 10541a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen } else if (mLinkState == LINK_STATE_DEBOUNCE) { 10559340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // Restart debounce timeout and tell user to tap again 10569340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen scheduleTimeoutLocked(MSG_DEBOUNCE_TIMEOUT, LINK_SEND_CONFIRMED_DEBOUNCE_MS); 10571a158c7f354d1e1b031fba88928dbaa022e0d0dfMartijn Coenen mEventListener.onP2pSendDebounce(); 105877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 105977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 106077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 106177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 10629340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 10639340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen @Override 10649340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen public void onP2pCanceled() { 10659340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen synchronized (this) { 10669340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mSendState = SEND_STATE_CANCELED; 10679340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen if (mLinkState == LINK_STATE_DOWN) { 10689340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // If we were waiting for the link to come up, stop doing so 10699340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mHandler.removeMessages(MSG_WAIT_FOR_LINK_TIMEOUT); 10709340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } else if (mLinkState == LINK_STATE_DEBOUNCE) { 10719340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // We're in debounce state so link is down. Reschedule debounce 10729340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // timeout to occur sooner, we don't want to wait any longer. 10739340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen scheduleTimeoutLocked(MSG_DEBOUNCE_TIMEOUT, LINK_SEND_CANCELED_DEBOUNCE_MS); 10749340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } else { 10759340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // Link is up, nothing else to do but wait for link to go down 10769340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 10779340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 10789340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 10799340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 10809340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen void scheduleTimeoutLocked(int what, int timeout) { 10819340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen // Cancel any outstanding debounce timeouts. 10829340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mHandler.removeMessages(what); 10839340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen mHandler.sendEmptyMessageDelayed(what, timeout); 10849340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen } 10859340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen 108677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static String sendStateToString(int state) { 108777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly switch (state) { 108877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case SEND_STATE_NOTHING_TO_SEND: 108977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "SEND_STATE_NOTHING_TO_SEND"; 109077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case SEND_STATE_NEED_CONFIRMATION: 109177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "SEND_STATE_NEED_CONFIRMATION"; 109277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case SEND_STATE_SENDING: 109377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "SEND_STATE_SENDING"; 10949340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen case SEND_STATE_COMPLETE: 10959340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen return "SEND_STATE_COMPLETE"; 10969340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen case SEND_STATE_CANCELED: 10979340b42304a512cb8fe9f4c068ba1b908876fb10Martijn Coenen return "SEND_STATE_CANCELED"; 109877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly default: 109977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "<error>"; 110077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 110177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 110277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 110377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly static String linkStateToString(int state) { 110477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly switch (state) { 110577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_DOWN: 110677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "LINK_STATE_DOWN"; 110777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_DEBOUNCE: 110877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "LINK_STATE_DEBOUNCE"; 110977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly case LINK_STATE_UP: 111077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "LINK_STATE_UP"; 111177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly default: 111277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly return "<error>"; 111377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 111477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 111577d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 111677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 111777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly synchronized (this) { 111877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly pw.println("mIsSendEnabled=" + mIsSendEnabled); 111977d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly pw.println("mIsReceiveEnabled=" + mIsReceiveEnabled); 112077d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly pw.println("mLinkState=" + linkStateToString(mLinkState)); 112177d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly pw.println("mSendState=" + sendStateToString(mSendState)); 112277d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly 112377d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly pw.println("mCallbackNdef=" + mCallbackNdef); 112477d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly pw.println("mMessageToSend=" + mMessageToSend); 112583558889207858d7ce8500f9fce8a707a86b495eMartijn Coenen pw.println("mUrisToSend=" + mUrisToSend); 112677d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 112777d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly } 112877d0b56bfa6a4e4e1449c476a1141a7486f34ad9Nick Pelly} 1129