109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/* 209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Copyright (c) 2008-2009, Motorola, Inc. 309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * All rights reserved. 509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Redistribution and use in source and binary forms, with or without 709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * modification, are permitted provided that the following conditions are met: 809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions of source code must retain the above copyright notice, 1009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer. 1109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Redistributions in binary form must reproduce the above copyright notice, 1309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * this list of conditions and the following disclaimer in the documentation 1409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * and/or other materials provided with the distribution. 1509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * - Neither the name of the Motorola, Inc. nor the names of its contributors 1709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * may be used to endorse or promote products derived from this software 1809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * without specific prior written permission. 1909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 2009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * POSSIBILITY OF SUCH DAMAGE. 3109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 3209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypackage com.android.bluetooth.opp; 3409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.ContentValues; 3609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Context; 3709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Intent; 3809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.net.Uri; 3909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Handler; 4009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Message; 4152236de777c23788df8147de15912a57e8bc36ddTao Liejunimport android.os.PowerManager; 4252236de777c23788df8147de15912a57e8bc36ddTao Liejunimport android.os.PowerManager.WakeLock; 4371f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamotoimport android.os.SystemClock; 4409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log; 4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.webkit.MimeTypeMap; 4609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 470ad53ef457f156314595a27c63660454450d3c84Jack Heimport com.android.bluetooth.BluetoothMetricsProto; 48c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport com.android.bluetooth.BluetoothObexTransport; 490ad53ef457f156314595a27c63660454450d3c84Jack Heimport com.android.bluetooth.btservice.MetricsLogger; 50c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 51c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport java.io.BufferedOutputStream; 52c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport java.io.File; 53c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport java.io.IOException; 54c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport java.io.InputStream; 55c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport java.util.Arrays; 56c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.HeaderSet; 5809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ObexTransport; 5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.Operation; 6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ResponseCodes; 6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ServerRequestHandler; 6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ServerSession; 6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/** 6509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * This class runs as an OBEX server 6609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 67c4fbd756e2645147470c486ae96f2253f5e13a52Jack Hepublic class BluetoothOppObexServerSession extends ServerRequestHandler 68c4fbd756e2645147470c486ae96f2253f5e13a52Jack He implements BluetoothOppObexSession { 6909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 70ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final String TAG = "BtOppObexServer"; 71ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean D = Constants.DEBUG; 72ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean V = Constants.VERBOSE; 7309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private ObexTransport mTransport; 7509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Context mContext; 7709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Handler mCallback = null; 7909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* status when server is blocking for user/auto confirmation */ 8109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean mServerBlocking = true; 8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* the current transfer info */ 8409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppShareInfo mInfo; 8509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* info id when we insert the record */ 8709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private int mLocalShareInfoId; 8809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private int mAccepted = BluetoothShare.USER_CONFIRMATION_PENDING; 9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean mInterrupted = false; 9209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private ServerSession mSession; 9409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private long mTimestamp; 9609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppReceiveFileInfo mFileInfo; 9809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9952236de777c23788df8147de15912a57e8bc36ddTao Liejun private WakeLock mPartialWakeLock; 10052236de777c23788df8147de15912a57e8bc36ddTao Liejun 1011ac5507790a87810061a19dadec36eb328a222eaTao Liejun boolean mTimeoutMsgSent = false; 1021ac5507790a87810061a19dadec36eb328a222eaTao Liejun 1037621506c7ade0a034f1cb77f5c1215db103768dbHansong Zhang private BluetoothOppService mBluetoothOppService; 1044aa5e4e2fe52c06d97481db0bf180349053dae48Hemant Gupta 1050ad53ef457f156314595a27c63660454450d3c84Jack He private int mNumFilesAttemptedToReceive; 1060ad53ef457f156314595a27c63660454450d3c84Jack He 107c4fbd756e2645147470c486ae96f2253f5e13a52Jack He public BluetoothOppObexServerSession(Context context, ObexTransport transport, 1087621506c7ade0a034f1cb77f5c1215db103768dbHansong Zhang BluetoothOppService service) { 10909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mContext = context; 11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mTransport = transport; 1117621506c7ade0a034f1cb77f5c1215db103768dbHansong Zhang mBluetoothOppService = service; 112c4fbd756e2645147470c486ae96f2253f5e13a52Jack He PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 11352236de777c23788df8147de15912a57e8bc36ddTao Liejun mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 114d2f6bd176055ed6c707f3e27ff130318afd231b1Ajay Panicker mPartialWakeLock.setReferenceCounted(false); 11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 1172fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 11809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void unblock() { 11909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mServerBlocking = false; 12009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 12109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 12309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Called when connection is accepted from remote, to retrieve the first 12409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Header then wait for user confirmation 12509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 126db94389c30d5ad5555a922d28868b119e1c6f2e1Andre Eisenbach public void preStart() { 12709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 128c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 129c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Create ServerSession with transport " + mTransport.toString()); 130c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 13109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSession = new ServerSession(mTransport, this, null); 13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 13309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Create server session error" + e); 13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 13809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Called from BluetoothOppTransfer to start the "Transfer" 13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 1402fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 1418eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen public void start(Handler handler, int numShares) { 142c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 143c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Start!"); 144c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 14509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = handler; 14609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 14709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 14809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 14909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 1506769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun * Called from BluetoothOppTransfer to cancel the "Transfer" Otherwise, 1516769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun * server should end by itself. 15209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 1532fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 15409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void stop() { 15509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 15609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * TODO now we implement in a tough way, just close the socket. 15709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * maybe need nice way 15809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 159c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 160c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Stop!"); 161c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 16209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInterrupted = true; 16309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mSession != null) { 16409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 16509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSession.close(); 16609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mTransport.close(); 16709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 16809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "close mTransport error" + e); 16909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 1711ac5507790a87810061a19dadec36eb328a222eaTao Liejun mCallback = null; 1721ac5507790a87810061a19dadec36eb328a222eaTao Liejun mSession = null; 17309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 1752fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 17609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void addShare(BluetoothOppShareInfo info) { 177c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 178c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "addShare for id " + info.mId); 179c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 18009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInfo = info; 18109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mFileInfo = processShareInfo(); 18209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 18409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 18509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public int onPut(Operation op) { 186c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 187c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "onPut " + op.toString()); 188c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 18909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 19079cd1a86171c772516d79c640bc244bcffee2960Myles Watson /* For multiple objects, reject further objects after the user denies the first one */ 19109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mAccepted == BluetoothShare.USER_CONFIRMATION_DENIED) { 19209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return ResponseCodes.OBEX_HTTP_FORBIDDEN; 19309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 19409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 19503f25a2055e51bcc5e8870642763b502956b6830Martijn Coenen String destination; 196bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde if (mTransport instanceof BluetoothObexTransport) { 197c4fbd756e2645147470c486ae96f2253f5e13a52Jack He destination = ((BluetoothObexTransport) mTransport).getRemoteAddress(); 19803f25a2055e51bcc5e8870642763b502956b6830Martijn Coenen } else { 19903f25a2055e51bcc5e8870642763b502956b6830Martijn Coenen destination = "FF:FF:FF:00:00:00"; 20003f25a2055e51bcc5e8870642763b502956b6830Martijn Coenen } 201e2f0e0fce32c77e0ac097b5b14dead5102959b82Jack He boolean isWhitelisted = 202e2f0e0fce32c77e0ac097b5b14dead5102959b82Jack He BluetoothOppManager.getInstance(mContext).isWhitelisted(destination); 20303f25a2055e51bcc5e8870642763b502956b6830Martijn Coenen 20479cd1a86171c772516d79c640bc244bcffee2960Myles Watson HeaderSet request; 20579cd1a86171c772516d79c640bc244bcffee2960Myles Watson String name, mimeType; 20679cd1a86171c772516d79c640bc244bcffee2960Myles Watson Long length; 20709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 2086769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun request = op.getReceivedHeader(); 209c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 210c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Constants.logHeader(request); 211c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 212c4fbd756e2645147470c486ae96f2253f5e13a52Jack He name = (String) request.getHeader(HeaderSet.NAME); 213c4fbd756e2645147470c486ae96f2253f5e13a52Jack He length = (Long) request.getHeader(HeaderSet.LENGTH); 214c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mimeType = (String) request.getHeader(HeaderSet.TYPE); 21579cd1a86171c772516d79c640bc244bcffee2960Myles Watson } catch (IOException e) { 21679cd1a86171c772516d79c640bc244bcffee2960Myles Watson Log.e(TAG, "onPut: getReceivedHeaders error " + e); 21779cd1a86171c772516d79c640bc244bcffee2960Myles Watson return ResponseCodes.OBEX_HTTP_BAD_REQUEST; 21879cd1a86171c772516d79c640bc244bcffee2960Myles Watson } 21909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 22079cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (length == 0) { 22179cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (D) { 22279cd1a86171c772516d79c640bc244bcffee2960Myles Watson Log.w(TAG, "length is 0, reject the transfer"); 22309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 22479cd1a86171c772516d79c640bc244bcffee2960Myles Watson return ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED; 22579cd1a86171c772516d79c640bc244bcffee2960Myles Watson } 22609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 22779cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (name == null || name.isEmpty()) { 22879cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (D) { 22979cd1a86171c772516d79c640bc244bcffee2960Myles Watson Log.w(TAG, "name is null or empty, reject the transfer"); 23009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 23179cd1a86171c772516d79c640bc244bcffee2960Myles Watson return ResponseCodes.OBEX_HTTP_BAD_REQUEST; 23279cd1a86171c772516d79c640bc244bcffee2960Myles Watson } 23309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 23479cd1a86171c772516d79c640bc244bcffee2960Myles Watson // First we look for the mime type in the Android map 23579cd1a86171c772516d79c640bc244bcffee2960Myles Watson String extension, type; 23679cd1a86171c772516d79c640bc244bcffee2960Myles Watson int dotIndex = name.lastIndexOf("."); 23779cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (dotIndex < 0 && mimeType == null) { 23879cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (D) { 23979cd1a86171c772516d79c640bc244bcffee2960Myles Watson Log.w(TAG, "There is no file extension or mime type, reject the transfer"); 24079cd1a86171c772516d79c640bc244bcffee2960Myles Watson } 24179cd1a86171c772516d79c640bc244bcffee2960Myles Watson return ResponseCodes.OBEX_HTTP_BAD_REQUEST; 24279cd1a86171c772516d79c640bc244bcffee2960Myles Watson } else { 24379cd1a86171c772516d79c640bc244bcffee2960Myles Watson extension = name.substring(dotIndex + 1).toLowerCase(); 24479cd1a86171c772516d79c640bc244bcffee2960Myles Watson MimeTypeMap map = MimeTypeMap.getSingleton(); 24579cd1a86171c772516d79c640bc244bcffee2960Myles Watson type = map.getMimeTypeFromExtension(extension); 24679cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (V) { 24779cd1a86171c772516d79c640bc244bcffee2960Myles Watson Log.v(TAG, "Mimetype guessed from extension " + extension + " is " + type); 24879cd1a86171c772516d79c640bc244bcffee2960Myles Watson } 24979cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (type != null) { 25079cd1a86171c772516d79c640bc244bcffee2960Myles Watson mimeType = type; 25179cd1a86171c772516d79c640bc244bcffee2960Myles Watson } else { 25279cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (mimeType == null) { 253c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 25479cd1a86171c772516d79c640bc244bcffee2960Myles Watson Log.w(TAG, "Can't get mimetype, reject the transfer"); 25509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 25679cd1a86171c772516d79c640bc244bcffee2960Myles Watson return ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE; 25709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 25809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 25979cd1a86171c772516d79c640bc244bcffee2960Myles Watson mimeType = mimeType.toLowerCase(); 26079cd1a86171c772516d79c640bc244bcffee2960Myles Watson } 26109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 26279cd1a86171c772516d79c640bc244bcffee2960Myles Watson // Reject anything outside the "whitelist" plus unspecified MIME Types. 26379cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (mimeType == null || (!isWhitelisted && !Constants.mimeTypeMatches(mimeType, 26479cd1a86171c772516d79c640bc244bcffee2960Myles Watson Constants.ACCEPTABLE_SHARE_INBOUND_TYPES))) { 26579cd1a86171c772516d79c640bc244bcffee2960Myles Watson if (D) { 26679cd1a86171c772516d79c640bc244bcffee2960Myles Watson Log.w(TAG, "mimeType is null or in unacceptable list, reject the transfer"); 26709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 26879cd1a86171c772516d79c640bc244bcffee2960Myles Watson return ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE; 26909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 27009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 27109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ContentValues values = new ContentValues(); 27209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly values.put(BluetoothShare.FILENAME_HINT, name); 2733aecf54308d60eea10fe10a5c18e4dff455aef66Pradeep Panigrahi values.put(BluetoothShare.TOTAL_BYTES, length); 27409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly values.put(BluetoothShare.MIMETYPE, mimeType); 2758099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen values.put(BluetoothShare.DESTINATION, destination); 27609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly values.put(BluetoothShare.DIRECTION, BluetoothShare.DIRECTION_INBOUND); 27709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly values.put(BluetoothShare.TIMESTAMP, mTimestamp); 27809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 27979cd1a86171c772516d79c640bc244bcffee2960Myles Watson // It's not first put if !serverBlocking, so we auto accept it 280c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!mServerBlocking && (mAccepted == BluetoothShare.USER_CONFIRMATION_CONFIRMED 281c4fbd756e2645147470c486ae96f2253f5e13a52Jack He || mAccepted == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED)) { 28209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly values.put(BluetoothShare.USER_CONFIRMATION, 28309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED); 28409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 28509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 28603f25a2055e51bcc5e8870642763b502956b6830Martijn Coenen if (isWhitelisted) { 2878099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen values.put(BluetoothShare.USER_CONFIRMATION, 2888099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); 2898099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen } 2908099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen 29109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Uri contentUri = mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values); 29209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mLocalShareInfoId = Integer.parseInt(contentUri.getPathSegments().get(1)); 29309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 294c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 295c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "insert contentUri: " + contentUri); 296c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "mLocalShareInfoId = " + mLocalShareInfoId); 297c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 29809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 29909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly synchronized (this) { 300f6ae67403c20cec20bc8f906411fce4c9ea769f0Sunny Goyal mPartialWakeLock.acquire(); 3014492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh mServerBlocking = true; 30209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 303df7415da0e510ab8e4b73831a5ade38306982fe1Tao Liejun 30409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (mServerBlocking) { 30509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly wait(1000); 3061ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (mCallback != null && !mTimeoutMsgSent) { 307c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mCallback.sendMessageDelayed(mCallback.obtainMessage( 308c4fbd756e2645147470c486ae96f2253f5e13a52Jack He BluetoothOppObexSession.MSG_CONNECT_TIMEOUT), 30909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppObexSession.SESSION_TIMEOUT); 3101ac5507790a87810061a19dadec36eb328a222eaTao Liejun mTimeoutMsgSent = true; 311c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 312c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_CONNECT_TIMEOUT sent"); 313c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 31409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 31509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 31609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (InterruptedException e) { 317c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 318c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "Interrupted in onPut blocking"); 319c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 32009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 32109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 322c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 323c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Server unblocked "); 324c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 3259d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun synchronized (this) { 3269d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (mCallback != null && mTimeoutMsgSent) { 3279d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); 3289d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } 3296769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun } 33009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 33109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* we should have mInfo now */ 33209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 33309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 33409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * TODO check if this mInfo match the one that we insert before server 33509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * blocking? just to make sure no error happens 33609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 33709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mInfo.mId != mLocalShareInfoId) { 33809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Unexpected error!"); 33909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 34009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mAccepted = mInfo.mConfirm; 34109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 342c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 343c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "after confirm: userAccepted=" + mAccepted); 344c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 34509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int status = BluetoothShare.STATUS_SUCCESS; 34609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 34779cd1a86171c772516d79c640bc244bcffee2960Myles Watson int obexResponse = ResponseCodes.OBEX_HTTP_OK; 34879cd1a86171c772516d79c640bc244bcffee2960Myles Watson 34909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mAccepted == BluetoothShare.USER_CONFIRMATION_CONFIRMED 3508099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen || mAccepted == BluetoothShare.USER_CONFIRMATION_AUTO_CONFIRMED 3518099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen || mAccepted == BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED) { 35209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* Confirm or auto-confirm */ 3530ad53ef457f156314595a27c63660454450d3c84Jack He mNumFilesAttemptedToReceive++; 35409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 35509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mFileInfo.mFileName == null) { 35609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly status = mFileInfo.mStatus; 35709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* TODO need to check if this line is correct */ 35809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInfo.mStatus = mFileInfo.mStatus; 35909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Constants.updateShareStatus(mContext, mInfo.mId, status); 36009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly obexResponse = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 36109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 36209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 36309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 36409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mFileInfo.mFileName != null) { 36509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 36609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ContentValues updateValues = new ContentValues(); 36709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + mInfo.mId); 36809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateValues.put(BluetoothShare._DATA, mFileInfo.mFileName); 36909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateValues.put(BluetoothShare.STATUS, BluetoothShare.STATUS_RUNNING); 37009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mContext.getContentResolver().update(contentUri, updateValues, null, null); 37109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 37209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly status = receiveFile(mFileInfo, op); 37309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 37409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * TODO map status to obex response code 37509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 37609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (status != BluetoothShare.STATUS_SUCCESS) { 37709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly obexResponse = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 37809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 37909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Constants.updateShareStatus(mContext, mInfo.mId, status); 38009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 38109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 38209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (status == BluetoothShare.STATUS_SUCCESS) { 38309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Message msg = Message.obtain(mCallback, BluetoothOppObexSession.MSG_SHARE_COMPLETE); 38409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.obj = mInfo; 38509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.sendToTarget(); 38609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 3871ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (mCallback != null) { 388c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Message msg = 389c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Message.obtain(mCallback, BluetoothOppObexSession.MSG_SESSION_ERROR); 3901ac5507790a87810061a19dadec36eb328a222eaTao Liejun mInfo.mStatus = status; 3911ac5507790a87810061a19dadec36eb328a222eaTao Liejun msg.obj = mInfo; 3921ac5507790a87810061a19dadec36eb328a222eaTao Liejun msg.sendToTarget(); 3931ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 39409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 39509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (mAccepted == BluetoothShare.USER_CONFIRMATION_DENIED 39609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly || mAccepted == BluetoothShare.USER_CONFIRMATION_TIMEOUT) { 39709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* user actively deny the inbound transfer */ 39809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 39909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Note There is a question: what's next if user deny the first obj? 40009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Option 1 :continue prompt for next objects 40109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Option 2 :reject next objects and finish the session 40209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Now we take option 2: 40309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 40452236de777c23788df8147de15912a57e8bc36ddTao Liejun 40552236de777c23788df8147de15912a57e8bc36ddTao Liejun Log.i(TAG, "Rejected incoming request"); 4061ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (mFileInfo.mFileName != null) { 4071ac5507790a87810061a19dadec36eb328a222eaTao Liejun try { 4081ac5507790a87810061a19dadec36eb328a222eaTao Liejun mFileInfo.mOutputStream.close(); 4091ac5507790a87810061a19dadec36eb328a222eaTao Liejun } catch (IOException e) { 4101ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.e(TAG, "error close file stream"); 4111ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 4121ac5507790a87810061a19dadec36eb328a222eaTao Liejun new File(mFileInfo.mFileName).delete(); 4131ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 4141ac5507790a87810061a19dadec36eb328a222eaTao Liejun // set status as local cancel 4151ac5507790a87810061a19dadec36eb328a222eaTao Liejun status = BluetoothShare.STATUS_CANCELED; 41609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Constants.updateShareStatus(mContext, mInfo.mId, status); 41709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly obexResponse = ResponseCodes.OBEX_HTTP_FORBIDDEN; 4181ac5507790a87810061a19dadec36eb328a222eaTao Liejun 41909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Message msg = Message.obtain(mCallback); 42009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.what = BluetoothOppObexSession.MSG_SHARE_INTERRUPTED; 4211ac5507790a87810061a19dadec36eb328a222eaTao Liejun mInfo.mStatus = status; 42209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.obj = mInfo; 42309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.sendToTarget(); 42409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 42509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return obexResponse; 42609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 42709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 42809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private int receiveFile(BluetoothOppReceiveFileInfo fileInfo, Operation op) { 42909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 43009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * implement receive file 43109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 43209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int status = -1; 43309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BufferedOutputStream bos = null; 43409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 43509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly InputStream is = null; 43609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly boolean error = false; 43709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 43809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly is = op.openInputStream(); 43909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e1) { 44009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error when openInputStream"); 44109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly status = BluetoothShare.STATUS_OBEX_DATA_ERROR; 44209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly error = true; 44309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 44409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 44509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + mInfo.mId); 44609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 44709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!error) { 44809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ContentValues updateValues = new ContentValues(); 44909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateValues.put(BluetoothShare._DATA, fileInfo.mFileName); 45009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mContext.getContentResolver().update(contentUri, updateValues, null, null); 45109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 45209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 453944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri long position = 0; 45479cd1a86171c772516d79c640bc244bcffee2960Myles Watson long percent; 455944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri long prevPercent = 0; 456944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri 45709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!error) { 4581ac5507790a87810061a19dadec36eb328a222eaTao Liejun bos = new BufferedOutputStream(fileInfo.mOutputStream, 0x10000); 45909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 46009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 46109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!error) { 46209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int outputBufferSize = op.getMaxPacketSize(); 46309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly byte[] b = new byte[outputBufferSize]; 46479cd1a86171c772516d79c640bc244bcffee2960Myles Watson int readLength; 46552236de777c23788df8147de15912a57e8bc36ddTao Liejun long timestamp = 0; 46679cd1a86171c772516d79c640bc244bcffee2960Myles Watson long currentTime; 46771f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto long prevTimestamp = SystemClock.elapsedRealtime(); 46809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 46909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while ((!mInterrupted) && (position != fileInfo.mLength)) { 47009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 471c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 47271f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto timestamp = SystemClock.elapsedRealtime(); 473c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 47409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 47509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly readLength = is.read(b); 47609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 47709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (readLength == -1) { 478c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 479c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Receive file reached stream end at position" + position); 480c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 48109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 48209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 48309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 48409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly bos.write(b, 0, readLength); 48509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly position += readLength; 486944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri percent = position * 100 / fileInfo.mLength; 48771f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto currentTime = SystemClock.elapsedRealtime(); 48809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 489ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) { 490c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, 491c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "Receive file position = " + position + " readLength " + readLength 49271f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto + " bytes took " + (currentTime - timestamp) + " ms"); 49309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 49409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 495944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri // Update the Progress Bar only if there is change in percentage 49671f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto // or once per a period to notify NFC of this transfer is still alive 49771f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto if (percent > prevPercent 49871f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto || currentTime - prevTimestamp > Constants.NFC_ALIVE_CHECK_MS) { 499944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri ContentValues updateValues = new ContentValues(); 500944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri updateValues.put(BluetoothShare.CURRENT_BYTES, position); 501944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri mContext.getContentResolver().update(contentUri, updateValues, null, null); 502944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri prevPercent = percent; 50371f70164a0044b0f5c26847def4eecfd0a306102Hiroki Yamamoto prevTimestamp = currentTime; 504944be107f513c90a7a8319f19bbe132b236ef1e7Deepak A Metri } 50509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 50609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e1) { 507cc284c80ef076eb33b99521cbb1cf3d6982fa341Ajay Panicker Log.e(TAG, "Error when receiving file: " + e1); 5089abe9c9e1ccad600b1069490293d78dfd984017bAndreas Areskoug /* OBEX Abort packet received from remote device */ 5099abe9c9e1ccad600b1069490293d78dfd984017bAndreas Areskoug if ("Abort Received".equals(e1.getMessage())) { 5109abe9c9e1ccad600b1069490293d78dfd984017bAndreas Areskoug status = BluetoothShare.STATUS_CANCELED; 5119abe9c9e1ccad600b1069490293d78dfd984017bAndreas Areskoug } else { 5129abe9c9e1ccad600b1069490293d78dfd984017bAndreas Areskoug status = BluetoothShare.STATUS_OBEX_DATA_ERROR; 5139abe9c9e1ccad600b1069490293d78dfd984017bAndreas Areskoug } 51409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly error = true; 51509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 51609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 51709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 51809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mInterrupted) { 519c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 520c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "receiving file interrupted by user."); 521c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 52209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly status = BluetoothShare.STATUS_CANCELED; 52309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 52409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (position == fileInfo.mLength) { 525c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 526c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Receiving file completed for " + fileInfo.mFileName); 527c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 52809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly status = BluetoothShare.STATUS_SUCCESS; 52909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 530c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 531c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Reading file failed at " + position + " of " + fileInfo.mLength); 532c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 53309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (status == -1) { 53409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly status = BluetoothShare.STATUS_UNKNOWN_ERROR; 53509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 53609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 53709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 53809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 53909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (bos != null) { 54009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 54109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly bos.close(); 54209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (IOException e) { 54309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Error when closing stream after send"); 54409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 54509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 5460eab1c87e9a0b26e3f61dcc46681a0a20f9cb745Hemant Gupta BluetoothOppUtility.cancelNotification(mContext); 54709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return status; 54809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 54909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 55009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppReceiveFileInfo processShareInfo() { 551c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 552c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "processShareInfo() " + mInfo.mId); 553c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 554c4fbd756e2645147470c486ae96f2253f5e13a52Jack He BluetoothOppReceiveFileInfo fileInfo = 555c4fbd756e2645147470c486ae96f2253f5e13a52Jack He BluetoothOppReceiveFileInfo.generateFileInfo(mContext, mInfo.mId); 556ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) { 55709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "Generate BluetoothOppReceiveFileInfo:"); 55809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "filename :" + fileInfo.mFileName); 55909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "length :" + fileInfo.mLength); 56009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "status :" + fileInfo.mStatus); 56109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 56209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return fileInfo; 56309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 56409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 56509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 56609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public int onConnect(HeaderSet request, HeaderSet reply) { 56709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 568c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 569c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "onConnect"); 570c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 571c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 572c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Constants.logHeader(request); 573c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 5748eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen Long objectCount = null; 5759d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun try { 576c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET); 577c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (V) { 578c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "onConnect(): uuid =" + Arrays.toString(uuid)); 579c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 580c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (uuid != null) { 581c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE; 5829d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } 5838eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen 5848eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen objectCount = (Long) request.getHeader(HeaderSet.COUNT); 5859d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } catch (IOException e) { 5869d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun Log.e(TAG, e.toString()); 5879d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR; 5889d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } 5898eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen String destination; 590bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde if (mTransport instanceof BluetoothObexTransport) { 591c4fbd756e2645147470c486ae96f2253f5e13a52Jack He destination = ((BluetoothObexTransport) mTransport).getRemoteAddress(); 5928eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen } else { 5938eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen destination = "FF:FF:FF:00:00:00"; 5948eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen } 59579cd1a86171c772516d79c640bc244bcffee2960Myles Watson boolean isHandover = BluetoothOppManager.getInstance(mContext).isWhitelisted(destination); 5968eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen if (isHandover) { 5978eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen // Notify the handover requester file transfer has started 5988eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen Intent intent = new Intent(Constants.ACTION_HANDOVER_STARTED); 5998eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen if (objectCount != null) { 6008eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen intent.putExtra(Constants.EXTRA_BT_OPP_OBJECT_COUNT, objectCount.intValue()); 6018eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen } else { 6028eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen intent.putExtra(Constants.EXTRA_BT_OPP_OBJECT_COUNT, 6038eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen Constants.COUNT_HEADER_UNAVAILABLE); 6048eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen } 6058eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen intent.putExtra(Constants.EXTRA_BT_OPP_ADDRESS, destination); 6068eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen mContext.sendBroadcast(intent, Constants.HANDOVER_STATUS_PERMISSION); 6078eb70f8bdf4e8c970810b3400aba8d08d14ce222Martijn Coenen } 60809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mTimestamp = System.currentTimeMillis(); 6090ad53ef457f156314595a27c63660454450d3c84Jack He mNumFilesAttemptedToReceive = 0; 61009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return ResponseCodes.OBEX_HTTP_OK; 61109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 61209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 61309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 61409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void onDisconnect(HeaderSet req, HeaderSet resp) { 615c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 616c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "onDisconnect"); 617c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 6180ad53ef457f156314595a27c63660454450d3c84Jack He if (mNumFilesAttemptedToReceive > 0) { 6190ad53ef457f156314595a27c63660454450d3c84Jack He // Log incoming OPP transfer if more than one file is accepted by user 6200ad53ef457f156314595a27c63660454450d3c84Jack He MetricsLogger.logProfileConnectionEvent(BluetoothMetricsProto.ProfileId.OPP); 6210ad53ef457f156314595a27c63660454450d3c84Jack He } 62209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly resp.responseCode = ResponseCodes.OBEX_HTTP_OK; 62309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 62409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6254492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh private synchronized void releaseWakeLocks() { 62632e47df203390052c1ef771d78b22fc4aa5f9e72Tao Liejun if (mPartialWakeLock.isHeld()) { 62732e47df203390052c1ef771d78b22fc4aa5f9e72Tao Liejun mPartialWakeLock.release(); 62832e47df203390052c1ef771d78b22fc4aa5f9e72Tao Liejun } 6294492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh } 6304492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh 6314492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh @Override 6324492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh public void onClose() { 633c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (D) { 634c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "onClose"); 635c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 6364492b2c66cf3b26fd988f3b7f1f5df6cc9ed49f2Jaikumar Ganesh releaseWakeLocks(); 6377621506c7ade0a034f1cb77f5c1215db103768dbHansong Zhang mBluetoothOppService.acceptNewConnections(); 6380eab1c87e9a0b26e3f61dcc46681a0a20f9cb745Hemant Gupta BluetoothOppUtility.cancelNotification(mContext); 6399d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun /* onClose could happen even before start() where mCallback is set */ 6409d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (mCallback != null) { 6419d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun Message msg = Message.obtain(mCallback); 6429d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun msg.what = BluetoothOppObexSession.MSG_SESSION_COMPLETE; 6439d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun msg.obj = mInfo; 6449d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun msg.sendToTarget(); 6459d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } 64609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 64709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly} 648