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 com.google.android.collect.Lists; 3609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport javax.obex.ObexTransport; 3709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 3809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.app.Service; 3941ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.bluetooth.BluetoothAdapter; 4009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.BroadcastReceiver; 410a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrickimport android.content.ContentResolver; 4209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.ContentValues; 4309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Context; 4409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Intent; 4509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.IntentFilter; 4609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.database.CharArrayBuffer; 4709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.database.ContentObserver; 4809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.database.Cursor; 4909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.media.MediaScannerConnection; 5009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.media.MediaScannerConnection.MediaScannerConnectionClient; 5109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.net.Uri; 5209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Handler; 5309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.IBinder; 5409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Message; 5509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.PowerManager; 5609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.util.Log; 5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.os.Process; 5809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.FileNotFoundException; 6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.IOException; 6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.io.InputStream; 6209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport java.util.ArrayList; 6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/** 656769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun * Performs the background Bluetooth OPP transfer. It also starts thread to 666769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun * accept incoming OPP connection. 6709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 6809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 6909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypublic class BluetoothOppService extends Service { 70ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean D = Constants.DEBUG; 71ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly private static final boolean V = Constants.VERBOSE; 7209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean userAccepted = false; 7409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private class BluetoothShareContentObserver extends ContentObserver { 7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 7709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public BluetoothShareContentObserver() { 7809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly super(new Handler()); 7909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 8109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void onChange(boolean selfChange) { 83ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "ContentObserver received notification"); 8409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateFromProvider(); 8509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 8609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 8709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 884852c5686229f1014e9851f4e9a3a19547581b45fredc private static final String TAG = "BtOppService"; 8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** Observer to get notified when the content observer's data changes */ 9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothShareContentObserver mObserver; 9209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** Class to handle Notification Manager updates */ 9409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppNotification mNotifier; 9509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean mPendingUpdate; 9709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private UpdateThread mUpdateThread; 9909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 10009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private ArrayList<BluetoothOppShareInfo> mShares; 10109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 10209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private ArrayList<BluetoothOppBatch> mBatchs; 10309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 10409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppTransfer mTransfer; 10509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 10609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppTransfer mServerTransfer; 10709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 10809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private int mBatchId; 10909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 11109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Array used when extracting strings from content provider 11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 11309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private CharArrayBuffer mOldChars; 11409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 11509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 11609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Array used when extracting strings from content provider 11709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 11809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private CharArrayBuffer mNewChars; 11909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 12041ef8d494511c040451f2f887cb31c3100746b61Nick Pelly private BluetoothAdapter mAdapter; 12109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private PowerManager mPowerManager; 12309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 12409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppRfcommListener mSocketListener; 12509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 12609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean mListenStarted = false; 12709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 1281ac5507790a87810061a19dadec36eb328a222eaTao Liejun private boolean mMediaScanInProgress; 1291ac5507790a87810061a19dadec36eb328a222eaTao Liejun 1301ac5507790a87810061a19dadec36eb328a222eaTao Liejun private int mIncomingRetries = 0; 1311ac5507790a87810061a19dadec36eb328a222eaTao Liejun 1321ac5507790a87810061a19dadec36eb328a222eaTao Liejun private ObexTransport mPendingConnection = null; 1331ac5507790a87810061a19dadec36eb328a222eaTao Liejun 13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * TODO No support for queue incoming from multiple devices. 13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Make an array list of server session to support receiving queue from 13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * multiple devices 13809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppObexServerSession mServerSession; 14009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 14109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 14209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public IBinder onBind(Intent arg0) { 14309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly throw new UnsupportedOperationException("Cannot bind to Bluetooth OPP Service"); 14409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 14509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 14609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 14709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void onCreate() { 14809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly super.onCreate(); 1494852c5686229f1014e9851f4e9a3a19547581b45fredc if (V) Log.v(TAG, "onCreate"); 1503a88b20fcd71e42451e402d27374b19eeb2ff0daNick Pelly mAdapter = BluetoothAdapter.getDefaultAdapter(); 15141ef8d494511c040451f2f887cb31c3100746b61Nick Pelly mSocketListener = new BluetoothOppRfcommListener(mAdapter); 15209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mShares = Lists.newArrayList(); 15309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchs = Lists.newArrayList(); 15409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mObserver = new BluetoothShareContentObserver(); 15509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly getContentResolver().registerContentObserver(BluetoothShare.CONTENT_URI, true, mObserver); 15609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchId = 1; 15709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifier = new BluetoothOppNotification(this); 15809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifier.mNotificationMgr.cancelAll(); 15909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifier.updateNotification(); 16009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 1610a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick final ContentResolver contentResolver = getContentResolver(); 1620a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick new Thread("trimDatabase") { 1630a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick public void run() { 1640a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick trimDatabase(contentResolver); 1650a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick } 1660a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick }.start(); 16709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 168f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 169f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly registerReceiver(mBluetoothReceiver, filter); 17009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 1716769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun synchronized (BluetoothOppService.this) { 17241ef8d494511c040451f2f887cb31c3100746b61Nick Pelly if (mAdapter == null) { 17309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.w(TAG, "Local BT device is not enabled"); 17409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 175ef697b0b9a74e15b5003e134307e72b20b48de12jhtop.kim startListener(); 17609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 17709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 178ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) BluetoothOppPreference.getInstance(this).dump(); 17909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateFromProvider(); 18009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 18109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 18209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 1838222c7902a2281929fd31e840f6012038e6fa44aLixin Yue public int onStartCommand(Intent intent, int flags, int startId) { 1844852c5686229f1014e9851f4e9a3a19547581b45fredc if (V) Log.v(TAG, "onStartCommand"); 18531ba132491053bc86d419a7d51fc04af3299c076fredc //int retCode = super.onStartCommand(intent, flags, startId); 18631ba132491053bc86d419a7d51fc04af3299c076fredc //if (retCode == START_STICKY) { 1878222c7902a2281929fd31e840f6012038e6fa44aLixin Yue if (mAdapter == null) { 1888222c7902a2281929fd31e840f6012038e6fa44aLixin Yue Log.w(TAG, "Local BT device is not enabled"); 1898222c7902a2281929fd31e840f6012038e6fa44aLixin Yue } else { 190ef697b0b9a74e15b5003e134307e72b20b48de12jhtop.kim startListener(); 1918222c7902a2281929fd31e840f6012038e6fa44aLixin Yue } 1928222c7902a2281929fd31e840f6012038e6fa44aLixin Yue updateFromProvider(); 19331ba132491053bc86d419a7d51fc04af3299c076fredc //} 19431ba132491053bc86d419a7d51fc04af3299c076fredc return START_NOT_STICKY; 19509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 19609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 197ef697b0b9a74e15b5003e134307e72b20b48de12jhtop.kim private void startListener() { 19809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!mListenStarted) { 19941ef8d494511c040451f2f887cb31c3100746b61Nick Pelly if (mAdapter.isEnabled()) { 200ef697b0b9a74e15b5003e134307e72b20b48de12jhtop.kim if (V) Log.v(TAG, "Starting RfcommListener"); 201ef697b0b9a74e15b5003e134307e72b20b48de12jhtop.kim mHandler.sendMessage(mHandler.obtainMessage(START_LISTENER)); 20209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mListenStarted = true; 20309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 20409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 20509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 20609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 20709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static final int START_LISTENER = 1; 20809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 20909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static final int MEDIA_SCANNED = 2; 21009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 21109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static final int MEDIA_SCANNED_FAILED = 3; 21209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 2131ac5507790a87810061a19dadec36eb328a222eaTao Liejun private static final int MSG_INCOMING_CONNECTION_RETRY = 4; 2141ac5507790a87810061a19dadec36eb328a222eaTao Liejun 21531ba132491053bc86d419a7d51fc04af3299c076fredc private static final int STOP_LISTENER = 200; 21631ba132491053bc86d419a7d51fc04af3299c076fredc 21709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Handler mHandler = new Handler() { 21809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 21909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void handleMessage(Message msg) { 22009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly switch (msg.what) { 22131ba132491053bc86d419a7d51fc04af3299c076fredc case STOP_LISTENER: 222275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala if(mSocketListener != null){ 223275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala mSocketListener.stop(); 224275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala } 22531ba132491053bc86d419a7d51fc04af3299c076fredc mListenStarted = false; 226275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala //Stop Active INBOUND Transfer 227275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala if(mServerTransfer != null){ 228275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala mServerTransfer.onBatchCanceled(); 229275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala mServerTransfer =null; 230275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala } 231275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala //Stop Active OUTBOUND Transfer 232275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala if(mTransfer != null){ 233275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala mTransfer.onBatchCanceled(); 234275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala mTransfer =null; 235275aaa55584ba62ab176a30cdabc432a6ff875d2Ashwini Munigala } 23631ba132491053bc86d419a7d51fc04af3299c076fredc synchronized (BluetoothOppService.this) { 23731ba132491053bc86d419a7d51fc04af3299c076fredc if (mUpdateThread == null) { 23831ba132491053bc86d419a7d51fc04af3299c076fredc stopSelf(); 23931ba132491053bc86d419a7d51fc04af3299c076fredc } 24031ba132491053bc86d419a7d51fc04af3299c076fredc } 24131ba132491053bc86d419a7d51fc04af3299c076fredc break; 24209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly case START_LISTENER: 24341ef8d494511c040451f2f887cb31c3100746b61Nick Pelly if (mAdapter.isEnabled()) { 24409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly startSocketListener(); 24509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 24609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 24709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly case MEDIA_SCANNED: 248ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Update mInfo.id " + msg.arg1 + " for data uri= " 24952236de777c23788df8147de15912a57e8bc36ddTao Liejun + msg.obj.toString()); 25009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ContentValues updateValues = new ContentValues(); 25109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + msg.arg1); 25209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateValues.put(Constants.MEDIA_SCANNED, Constants.MEDIA_SCANNED_SCANNED_OK); 25309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateValues.put(BluetoothShare.URI, msg.obj.toString()); // update 25409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateValues.put(BluetoothShare.MIMETYPE, getContentResolver().getType( 25509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Uri.parse(msg.obj.toString()))); 25609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly getContentResolver().update(contentUri, updateValues, null, null); 2571ac5507790a87810061a19dadec36eb328a222eaTao Liejun synchronized (BluetoothOppService.this) { 2581ac5507790a87810061a19dadec36eb328a222eaTao Liejun mMediaScanInProgress = false; 2591ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 26009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 26109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly case MEDIA_SCANNED_FAILED: 26209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "Update mInfo.id " + msg.arg1 + " for MEDIA_SCANNED_FAILED"); 26309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ContentValues updateValues1 = new ContentValues(); 26409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Uri contentUri1 = Uri.parse(BluetoothShare.CONTENT_URI + "/" + msg.arg1); 26509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateValues1.put(Constants.MEDIA_SCANNED, 26609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Constants.MEDIA_SCANNED_SCANNED_FAILED); 26709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly getContentResolver().update(contentUri1, updateValues1, null, null); 2681ac5507790a87810061a19dadec36eb328a222eaTao Liejun synchronized (BluetoothOppService.this) { 2691ac5507790a87810061a19dadec36eb328a222eaTao Liejun mMediaScanInProgress = false; 2701ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 2711ac5507790a87810061a19dadec36eb328a222eaTao Liejun break; 2721ac5507790a87810061a19dadec36eb328a222eaTao Liejun case BluetoothOppRfcommListener.MSG_INCOMING_BTOPP_CONNECTION: 273ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (D) Log.d(TAG, "Get incoming connection"); 2741ac5507790a87810061a19dadec36eb328a222eaTao Liejun ObexTransport transport = (ObexTransport)msg.obj; 2751ac5507790a87810061a19dadec36eb328a222eaTao Liejun /* 2761ac5507790a87810061a19dadec36eb328a222eaTao Liejun * Strategy for incoming connections: 2771ac5507790a87810061a19dadec36eb328a222eaTao Liejun * 1. If there is no ongoing transfer, no on-hold connection, start it 2781ac5507790a87810061a19dadec36eb328a222eaTao Liejun * 2. If there is ongoing transfer, hold it for 20 seconds(1 seconds * 20 times) 2791ac5507790a87810061a19dadec36eb328a222eaTao Liejun * 3. If there is on-hold connection, reject directly 2801ac5507790a87810061a19dadec36eb328a222eaTao Liejun */ 2811ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (mBatchs.size() == 0 && mPendingConnection == null) { 2821ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "Start Obex Server"); 2831ac5507790a87810061a19dadec36eb328a222eaTao Liejun createServerSession(transport); 2841ac5507790a87810061a19dadec36eb328a222eaTao Liejun } else { 2851ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (mPendingConnection != null) { 2861ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.w(TAG, "OPP busy! Reject connection"); 2871ac5507790a87810061a19dadec36eb328a222eaTao Liejun try { 2881ac5507790a87810061a19dadec36eb328a222eaTao Liejun transport.close(); 2891ac5507790a87810061a19dadec36eb328a222eaTao Liejun } catch (IOException e) { 2901ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.e(TAG, "close tranport error"); 2911ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 292a930b6831d0c70b6c5d34e548e6b1dceaa6529a0Mohammad Shamsi } else if (Constants.USE_TCP_DEBUG && !Constants.USE_TCP_SIMPLE_SERVER) { 293888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun Log.i(TAG, "Start Obex Server in TCP DEBUG mode"); 294888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun createServerSession(transport); 2951ac5507790a87810061a19dadec36eb328a222eaTao Liejun } else { 2961ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "OPP busy! Retry after 1 second"); 2971ac5507790a87810061a19dadec36eb328a222eaTao Liejun mIncomingRetries = mIncomingRetries + 1; 2981ac5507790a87810061a19dadec36eb328a222eaTao Liejun mPendingConnection = transport; 2991ac5507790a87810061a19dadec36eb328a222eaTao Liejun Message msg1 = Message.obtain(mHandler); 3001ac5507790a87810061a19dadec36eb328a222eaTao Liejun msg1.what = MSG_INCOMING_CONNECTION_RETRY; 3011ac5507790a87810061a19dadec36eb328a222eaTao Liejun mHandler.sendMessageDelayed(msg1, 1000); 3021ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 3031ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 3041ac5507790a87810061a19dadec36eb328a222eaTao Liejun break; 3051ac5507790a87810061a19dadec36eb328a222eaTao Liejun case MSG_INCOMING_CONNECTION_RETRY: 3061ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (mBatchs.size() == 0) { 3071ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "Start Obex Server"); 3081ac5507790a87810061a19dadec36eb328a222eaTao Liejun createServerSession(mPendingConnection); 3091ac5507790a87810061a19dadec36eb328a222eaTao Liejun mIncomingRetries = 0; 3101ac5507790a87810061a19dadec36eb328a222eaTao Liejun mPendingConnection = null; 3111ac5507790a87810061a19dadec36eb328a222eaTao Liejun } else { 3121ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (mIncomingRetries == 20) { 3131ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.w(TAG, "Retried 20 seconds, reject connection"); 3141ac5507790a87810061a19dadec36eb328a222eaTao Liejun try { 3151ac5507790a87810061a19dadec36eb328a222eaTao Liejun mPendingConnection.close(); 3161ac5507790a87810061a19dadec36eb328a222eaTao Liejun } catch (IOException e) { 3171ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.e(TAG, "close tranport error"); 3181ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 3191ac5507790a87810061a19dadec36eb328a222eaTao Liejun mIncomingRetries = 0; 3201ac5507790a87810061a19dadec36eb328a222eaTao Liejun mPendingConnection = null; 3211ac5507790a87810061a19dadec36eb328a222eaTao Liejun } else { 3221ac5507790a87810061a19dadec36eb328a222eaTao Liejun Log.i(TAG, "OPP busy! Retry after 1 second"); 3231ac5507790a87810061a19dadec36eb328a222eaTao Liejun mIncomingRetries = mIncomingRetries + 1; 3241ac5507790a87810061a19dadec36eb328a222eaTao Liejun Message msg2 = Message.obtain(mHandler); 3251ac5507790a87810061a19dadec36eb328a222eaTao Liejun msg2.what = MSG_INCOMING_CONNECTION_RETRY; 3261ac5507790a87810061a19dadec36eb328a222eaTao Liejun mHandler.sendMessageDelayed(msg2, 1000); 3271ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 3281ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 3291ac5507790a87810061a19dadec36eb328a222eaTao Liejun break; 33009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 33109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 33209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly }; 33309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 33409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void startSocketListener() { 33509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 336ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "start RfcommListener"); 3371ac5507790a87810061a19dadec36eb328a222eaTao Liejun mSocketListener.start(mHandler); 338ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "RfcommListener started"); 33909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 34009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 34109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 34209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void onDestroy() { 3434852c5686229f1014e9851f4e9a3a19547581b45fredc if (V) Log.v(TAG, "onDestroy"); 34409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly super.onDestroy(); 34509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly getContentResolver().unregisterContentObserver(mObserver); 346f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly unregisterReceiver(mBluetoothReceiver); 34709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketListener.stop(); 3483fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan 3493fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan if(mBatchs != null) { 3503fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mBatchs.clear(); 3513fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan } 3523fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan if(mShares != null) { 3533fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mShares.clear(); 3543fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan } 3553fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan if(mHandler != null) { 3563fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan mHandler.removeCallbacksAndMessages(null); 3573fafe61ef25c1899fdc817c52163aec16c31055cRavi Nagarajan } 35809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 35909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 36009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* suppose we auto accept an incoming OPUSH connection */ 36109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void createServerSession(ObexTransport transport) { 36209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mServerSession = new BluetoothOppObexServerSession(this, transport); 36309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mServerSession.preStart(); 364ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (D) Log.d(TAG, "Get ServerSession " + mServerSession.toString() 36509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + " for incoming connection" + transport.toString()); 36609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 36709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 368f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly private final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() { 36909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 37009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void onReceive(Context context, Intent intent) { 37109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly String action = intent.getAction(); 37209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 373f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 374613bae227d65f61903e196944a9c718b4394f25aNick Pelly switch (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) { 375f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly case BluetoothAdapter.STATE_ON: 376ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, 37709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly "Receiver BLUETOOTH_STATE_CHANGED_ACTION, BLUETOOTH_STATE_ON"); 37809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly startSocketListener(); 37909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 380f4a286ee2aba5a75abe41881334bbdb5d0080105Nick Pelly case BluetoothAdapter.STATE_TURNING_OFF: 381ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Receiver DISABLED_ACTION "); 38231ba132491053bc86d419a7d51fc04af3299c076fredc //FIX: Don't block main thread 38331ba132491053bc86d419a7d51fc04af3299c076fredc /* 38409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mSocketListener.stop(); 38509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mListenStarted = false; 3866769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun synchronized (BluetoothOppService.this) { 38709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mUpdateThread == null) { 38809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly stopSelf(); 38909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 39009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 39131ba132491053bc86d419a7d51fc04af3299c076fredc */ 39231ba132491053bc86d419a7d51fc04af3299c076fredc mHandler.sendMessage(mHandler.obtainMessage(STOP_LISTENER)); 39331ba132491053bc86d419a7d51fc04af3299c076fredc 39409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 39509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 39609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 39709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 39809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly }; 39909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 40009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void updateFromProvider() { 4016769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun synchronized (BluetoothOppService.this) { 40209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mPendingUpdate = true; 40309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mUpdateThread == null) { 40409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mUpdateThread = new UpdateThread(); 40509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mUpdateThread.start(); 40609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 40709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 40809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 40909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 41009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private class UpdateThread extends Thread { 41109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public UpdateThread() { 41209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly super("Bluetooth Share Service"); 41309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 41409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 41509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly @Override 41609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void run() { 41709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 41809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 4191ac5507790a87810061a19dadec36eb328a222eaTao Liejun boolean keepService = false; 42009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (;;) { 4216769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun synchronized (BluetoothOppService.this) { 42209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mUpdateThread != this) { 42309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly throw new IllegalStateException( 42409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly "multiple UpdateThreads in BluetoothOppService"); 42509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 426ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "pendingUpdate is " + mPendingUpdate + " keepUpdateThread is " 4271ac5507790a87810061a19dadec36eb328a222eaTao Liejun + keepService + " sListenStarted is " + mListenStarted); 42809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!mPendingUpdate) { 42909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mUpdateThread = null; 4301ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (!keepService && !mListenStarted) { 43109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly stopSelf(); 43209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly break; 43309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 43409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 43509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 43609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mPendingUpdate = false; 43709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 43809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Cursor cursor = getContentResolver().query(BluetoothShare.CONTENT_URI, null, null, 43909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly null, BluetoothShare._ID); 44009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 44109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (cursor == null) { 44209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 44309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 44409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 44509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.moveToFirst(); 44609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 44709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int arrayPos = 0; 44809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 4491ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = false; 45009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly boolean isAfterLast = cursor.isAfterLast(); 45109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 45209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int idColumn = cursor.getColumnIndexOrThrow(BluetoothShare._ID); 45309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 45409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Walk the cursor and the local array to keep them in sync. The 45509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * key to the algorithm is that the ids are unique and sorted 45609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * both in the cursor and in the array, so that they can be 45709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * processed in order in both sources at the same time: at each 45809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * step, both sources point to the lowest id that hasn't been 45909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * processed from that source, and the algorithm processes the 46009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * lowest id from those two possibilities. At each step: -If the 46109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * array contains an entry that's not in the cursor, remove the 46209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * entry, move to next entry in the array. -If the array 46309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * contains an entry that's in the cursor, nothing to do, move 46409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * to next cursor row and next array entry. -If the cursor 46509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * contains an entry that's not in the array, insert a new entry 46609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * in the array, move to next cursor row and next array entry. 46709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 46809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly while (!isAfterLast || arrayPos < mShares.size()) { 46909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (isAfterLast) { 47009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // We're beyond the end of the cursor but there's still 47109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // some 47209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // stuff in the local array, which can only be junk 473750fd64e9e3724902190f74ebb2538a966a3e11eJuffin Alex Varghese if (mShares.size() != 0) 474750fd64e9e3724902190f74ebb2538a966a3e11eJuffin Alex Varghese if (V) Log.v(TAG, "Array update: trimming " + 475ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly mShares.get(arrayPos).mId + " @ " + arrayPos); 47609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 47709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (shouldScanFile(arrayPos)) { 47809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly scanFile(null, arrayPos); 47909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 48009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly deleteShare(arrayPos); // this advances in the array 48109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 48209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int id = cursor.getInt(idColumn); 48309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 48409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (arrayPos == mShares.size()) { 48509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly insertShare(cursor, arrayPos); 486ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Array update: inserting " + id + " @ " + arrayPos); 48709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (shouldScanFile(arrayPos) && (!scanFile(cursor, arrayPos))) { 4881ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 48909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 49009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (visibleNotification(arrayPos)) { 4911ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 49209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 49309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (needAction(arrayPos)) { 4941ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 49509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 49609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 49709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ++arrayPos; 49809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.moveToNext(); 49909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly isAfterLast = cursor.isAfterLast(); 50009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 501750fd64e9e3724902190f74ebb2538a966a3e11eJuffin Alex Varghese int arrayId = 0; 502750fd64e9e3724902190f74ebb2538a966a3e11eJuffin Alex Varghese if (mShares.size() != 0) 503750fd64e9e3724902190f74ebb2538a966a3e11eJuffin Alex Varghese arrayId = mShares.get(arrayPos).mId; 50409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 50509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (arrayId < id) { 506ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Array update: removing " + arrayId + " @ " 50709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + arrayPos); 50809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (shouldScanFile(arrayPos)) { 50909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly scanFile(null, arrayPos); 51009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 51109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly deleteShare(arrayPos); 51209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (arrayId == id) { 51309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // This cursor row already exists in the stored 51409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // array 51509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly updateShare(cursor, arrayPos, userAccepted); 51609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (shouldScanFile(arrayPos) && (!scanFile(cursor, arrayPos))) { 5171ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 51809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 51909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (visibleNotification(arrayPos)) { 5201ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 52109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 52209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (needAction(arrayPos)) { 5231ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 52409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 52509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 52609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ++arrayPos; 52709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.moveToNext(); 52809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly isAfterLast = cursor.isAfterLast(); 52909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 53009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // This cursor entry didn't exist in the stored 53109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // array 532ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Array update: appending " + id + " @ " + arrayPos); 53309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly insertShare(cursor, arrayPos); 53409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 53509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (shouldScanFile(arrayPos) && (!scanFile(cursor, arrayPos))) { 5361ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 53709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 53809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (visibleNotification(arrayPos)) { 5391ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 54009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 54109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (needAction(arrayPos)) { 5421ac5507790a87810061a19dadec36eb328a222eaTao Liejun keepService = true; 54309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 54409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly ++arrayPos; 54509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.moveToNext(); 54609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly isAfterLast = cursor.isAfterLast(); 54709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 54809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 54909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 55009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 55109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 55209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifier.updateNotification(); 55309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 55409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.close(); 55509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 55609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 55709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 55809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 55909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 56009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void insertShare(Cursor cursor, int arrayPos) { 561ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby String uriString = cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.URI)); 562ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby Uri uri; 563ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby if (uriString != null) { 564ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby uri = Uri.parse(uriString); 565ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby Log.d(TAG, "insertShare parsed URI: " + uri); 566ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby } else { 567ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby uri = null; 568ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby Log.e(TAG, "insertShare found null URI at cursor!"); 569ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby } 57009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppShareInfo info = new BluetoothOppShareInfo( 57109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)), 572ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby uri, 57309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT)), 57409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare._DATA)), 57509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.MIMETYPE)), 57609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION)), 57709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.DESTINATION)), 57809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY)), 57909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION)), 58009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.STATUS)), 5815f10fd1ef7709ce6c89414ad732831b6759b982aHemant Gupta cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TOTAL_BYTES)), 5825f10fd1ef7709ce6c89414ad732831b6759b982aHemant Gupta cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES)), 5835f10fd1ef7709ce6c89414ad732831b6759b982aHemant Gupta cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP)), 58409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) != Constants.MEDIA_SCANNED_NOT_SCANNED); 58509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 586ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) { 58709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "Service adding new entry"); 58809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "ID : " + info.mId); 58909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // Log.v(TAG, "URI : " + ((info.mUri != null) ? "yes" : "no")); 59009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "URI : " + info.mUri); 59109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "HINT : " + info.mHint); 59209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "FILENAME: " + info.mFilename); 59309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "MIMETYPE: " + info.mMimetype); 59409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "DIRECTION: " + info.mDirection); 59509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "DESTINAT: " + info.mDestination); 59609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "VISIBILI: " + info.mVisibility); 59709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "CONFIRM : " + info.mConfirm); 59809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "STATUS : " + info.mStatus); 59909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "TOTAL : " + info.mTotalBytes); 60009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "CURRENT : " + info.mCurrentBytes); 60109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "TIMESTAMP : " + info.mTimestamp); 60209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "SCANNED : " + info.mMediaScanned); 60309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 60409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 60509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mShares.add(arrayPos, info); 60609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 60709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* Mark the info as failed if it's in invalid status */ 60809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (info.isObsolete()) { 60909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Constants.updateShareStatus(this, info.mId, BluetoothShare.STATUS_UNKNOWN_ERROR); 61009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 61109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 61209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Add info into a batch. The logic is 61309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1) Only add valid and readyToStart info 61409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 2) If there is no batch, create a batch and insert this transfer into batch, 61509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * then run the batch 61609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 3) If there is existing batch and timestamp match, insert transfer into batch 61709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 4) If there is existing batch and timestamp does not match, create a new batch and 61809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * put in queue 61909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 62009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 62109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (info.isReadyToStart()) { 62209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (info.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 62309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* check if the file exists */ 624ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby BluetoothOppSendFileInfo sendFileInfo = BluetoothOppUtility.getSendFileInfo( 625ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby info.mUri); 626ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby if (sendFileInfo == null || sendFileInfo.mInputStream == null) { 62709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Can't open file for OUTBOUND info " + info.mId); 62809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Constants.updateShareStatus(this, info.mId, BluetoothShare.STATUS_BAD_REQUEST); 629ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby BluetoothOppUtility.closeSendFileInfo(info.mUri); 63009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 63109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 63209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 63309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mBatchs.size() == 0) { 63409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppBatch newBatch = new BluetoothOppBatch(this, info); 63509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly newBatch.mId = mBatchId; 63609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchId++; 63709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchs.add(newBatch); 63809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (info.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 639ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Service create new Batch " + newBatch.mId 64009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + " for OUTBOUND info " + info.mId); 64109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mTransfer = new BluetoothOppTransfer(this, mPowerManager, newBatch); 64209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (info.mDirection == BluetoothShare.DIRECTION_INBOUND) { 643ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Service create new Batch " + newBatch.mId 64409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + " for INBOUND info " + info.mId); 64509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mServerTransfer = new BluetoothOppTransfer(this, mPowerManager, newBatch, 64609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mServerSession); 64709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 64809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 64909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (info.mDirection == BluetoothShare.DIRECTION_OUTBOUND && mTransfer != null) { 650ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Service start transfer new Batch " + newBatch.mId 65109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + " for info " + info.mId); 65209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mTransfer.start(); 65309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (info.mDirection == BluetoothShare.DIRECTION_INBOUND 65409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly && mServerTransfer != null) { 655ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Service start server transfer new Batch " + newBatch.mId 65609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + " for info " + info.mId); 65709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mServerTransfer.start(); 65809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 65909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 66009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 66109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int i = findBatchWithTimeStamp(info.mTimestamp); 66209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (i != -1) { 663ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Service add info " + info.mId + " to existing batch " 66409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + mBatchs.get(i).mId); 66509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchs.get(i).addShare(info); 66609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 667888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun // There is ongoing batch 66809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppBatch newBatch = new BluetoothOppBatch(this, info); 66909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly newBatch.mId = mBatchId; 67009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchId++; 67109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchs.add(newBatch); 672888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "Service add new Batch " + newBatch.mId + " for info " + 673888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun info.mId); 674888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (Constants.USE_TCP_DEBUG && !Constants.USE_TCP_SIMPLE_SERVER) { 675888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun // only allow concurrent serverTransfer in debug mode 676888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (info.mDirection == BluetoothShare.DIRECTION_INBOUND) { 677888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun if (V) Log.v(TAG, "TCP_DEBUG start server transfer new Batch " + 678888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun newBatch.mId + " for info " + info.mId); 679888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mServerTransfer = new BluetoothOppTransfer(this, mPowerManager, 680888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun newBatch, mServerSession); 681888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun mServerTransfer.start(); 682888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 683888485a3f5fe991116c5536bb6d6903d47b63a70Tao Liejun } 68409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 68509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 68609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 68709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 68809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 68909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void updateShare(Cursor cursor, int arrayPos, boolean userAccepted) { 6906769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun BluetoothOppShareInfo info = mShares.get(arrayPos); 69109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int statusColumn = cursor.getColumnIndexOrThrow(BluetoothShare.STATUS); 69209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 69309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mId = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)); 694ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby if (info.mUri != null) { 695ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby info.mUri = Uri.parse(stringFromCursor(info.mUri.toString(), cursor, 696ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby BluetoothShare.URI)); 697ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby } else { 6980f4ef70f0bc246b224f7b6da524128db89fcc8a7Matthew Xie Log.w(TAG, "updateShare() called for ID " + info.mId + " with null URI"); 699ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby } 70009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mHint = stringFromCursor(info.mHint, cursor, BluetoothShare.FILENAME_HINT); 70109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mFilename = stringFromCursor(info.mFilename, cursor, BluetoothShare._DATA); 70209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mMimetype = stringFromCursor(info.mMimetype, cursor, BluetoothShare.MIMETYPE); 70309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mDirection = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.DIRECTION)); 70409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mDestination = stringFromCursor(info.mDestination, cursor, BluetoothShare.DESTINATION); 70509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int newVisibility = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare.VISIBILITY)); 70609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 707e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie boolean confirmUpdated = false; 70809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int newConfirm = cursor.getInt(cursor 70909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly .getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION)); 71009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 71109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (info.mVisibility == BluetoothShare.VISIBILITY_VISIBLE 71209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly && newVisibility != BluetoothShare.VISIBILITY_VISIBLE 71309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly && (BluetoothShare.isStatusCompleted(info.mStatus) || newConfirm == BluetoothShare.USER_CONFIRMATION_PENDING)) { 71409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifier.mNotificationMgr.cancel(info.mId); 71509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 71609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 71709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mVisibility = newVisibility; 71809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 71909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (info.mConfirm == BluetoothShare.USER_CONFIRMATION_PENDING 720e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie && newConfirm != BluetoothShare.USER_CONFIRMATION_PENDING) { 721e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie confirmUpdated = true; 72209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 72309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mConfirm = cursor.getInt(cursor 72409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly .getColumnIndexOrThrow(BluetoothShare.USER_CONFIRMATION)); 72509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int newStatus = cursor.getInt(statusColumn); 72609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 72709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (!BluetoothShare.isStatusCompleted(info.mStatus) 72809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly && BluetoothShare.isStatusCompleted(newStatus)) { 72909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNotifier.mNotificationMgr.cancel(info.mId); 73009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 73109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 73209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mStatus = newStatus; 7335f10fd1ef7709ce6c89414ad732831b6759b982aHemant Gupta info.mTotalBytes = cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TOTAL_BYTES)); 7345f10fd1ef7709ce6c89414ad732831b6759b982aHemant Gupta info.mCurrentBytes = cursor.getLong(cursor 73509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly .getColumnIndexOrThrow(BluetoothShare.CURRENT_BYTES)); 7365f10fd1ef7709ce6c89414ad732831b6759b982aHemant Gupta info.mTimestamp = cursor.getLong(cursor.getColumnIndexOrThrow(BluetoothShare.TIMESTAMP)); 73709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly info.mMediaScanned = (cursor.getInt(cursor.getColumnIndexOrThrow(Constants.MEDIA_SCANNED)) != Constants.MEDIA_SCANNED_NOT_SCANNED); 73809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 739e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie if (confirmUpdated) { 740e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie if (V) Log.v(TAG, "Service handle info " + info.mId + " confirmation updated"); 741e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie /* Inbounds transfer user confirmation status changed, update the session server */ 742df7415da0e510ab8e4b73831a5ade38306982fe1Tao Liejun int i = findBatchWithTimeStamp(info.mTimestamp); 7439d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (i != -1) { 7449d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun BluetoothOppBatch batch = mBatchs.get(i); 7459d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (mServerTransfer != null && batch.mId == mServerTransfer.getBatchId()) { 746e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie mServerTransfer.confirmStatusChanged(); 7479d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } //TODO need to think about else 7489d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } 74909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 75009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int i = findBatchWithTimeStamp(info.mTimestamp); 75109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (i != -1) { 75209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppBatch batch = mBatchs.get(i); 75309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (batch.mStatus == Constants.BATCH_STATUS_FINISHED 75409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly || batch.mStatus == Constants.BATCH_STATUS_FAILED) { 755ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Batch " + batch.mId + " is finished"); 75609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (batch.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 75709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mTransfer == null) { 75809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Unexpected error! mTransfer is null"); 75909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (batch.mId == mTransfer.getBatchId()) { 76009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mTransfer.stop(); 76109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 76209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Unexpected error! batch id " + batch.mId 76309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + " doesn't match mTransfer id " + mTransfer.getBatchId()); 76409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 7659d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun mTransfer = null; 76609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 76709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mServerTransfer == null) { 76809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Unexpected error! mServerTransfer is null"); 76909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else if (batch.mId == mServerTransfer.getBatchId()) { 77009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mServerTransfer.stop(); 77109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 77209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.e(TAG, "Unexpected error! batch id " + batch.mId 77309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + " doesn't match mServerTransfer id " 77409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly + mServerTransfer.getBatchId()); 77509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 7769d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun mServerTransfer = null; 77709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 77809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly removeBatch(batch); 77909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 78009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 78109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 78209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 78309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /** 78409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Removes the local copy of the info about a share. 78509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 78609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void deleteShare(int arrayPos) { 7876769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun BluetoothOppShareInfo info = mShares.get(arrayPos); 78809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 78909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly /* 79009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * Delete arrayPos from a batch. The logic is 79109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 1) Search existing batch for the info 79209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 2) cancel the batch 79309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * 3) If the batch become empty delete the batch 79409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */ 79509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int i = findBatchWithTimeStamp(info.mTimestamp); 79609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (i != -1) { 79709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothOppBatch batch = mBatchs.get(i); 79809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (batch.hasShare(info)) { 799ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Service cancel batch for share " + info.mId); 80009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly batch.cancelBatch(); 80109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 80209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (batch.isEmpty()) { 803ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Service remove batch " + batch.mId); 80409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly removeBatch(batch); 80509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 80609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 80709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mShares.remove(arrayPos); 80809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 80909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 81009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private String stringFromCursor(String old, Cursor cursor, String column) { 81109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int index = cursor.getColumnIndexOrThrow(column); 81209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (old == null) { 81309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return cursor.getString(index); 81409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 81509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mNewChars == null) { 81609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mNewChars = new CharArrayBuffer(128); 81709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 81809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.copyStringToBuffer(index, mNewChars); 81909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly int length = mNewChars.sizeCopied; 82009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (length != old.length()) { 82109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return cursor.getString(index); 82209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 82309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mOldChars == null || mOldChars.sizeCopied < length) { 82409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mOldChars = new CharArrayBuffer(length); 82509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 82609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly char[] oldArray = mOldChars.data; 82709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly char[] newArray = mNewChars.data; 82809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly old.getChars(0, length, oldArray, 0); 82909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (int i = length - 1; i >= 0; --i) { 83009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (oldArray[i] != newArray[i]) { 83109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return new String(newArray, 0, length); 83209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 83309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 83409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return old; 83509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 83609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 83709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private int findBatchWithTimeStamp(long timestamp) { 83809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (int i = mBatchs.size() - 1; i >= 0; i--) { 83909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mBatchs.get(i).mTimestamp == timestamp) { 84009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return i; 84109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 84209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 84309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return -1; 84409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 84509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 84609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private void removeBatch(BluetoothOppBatch batch) { 847ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Remove batch " + batch.mId); 84809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mBatchs.remove(batch); 8499d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun BluetoothOppBatch nextBatch; 85009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (mBatchs.size() > 0) { 85109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly for (int i = 0; i < mBatchs.size(); i++) { 85209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly // we have a running batch 8539d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun nextBatch = mBatchs.get(i); 8549d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (nextBatch.mStatus == Constants.BATCH_STATUS_RUNNING) { 85509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 85609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 8571ac5507790a87810061a19dadec36eb328a222eaTao Liejun // just finish a transfer, start pending outbound transfer 8589d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (nextBatch.mDirection == BluetoothShare.DIRECTION_OUTBOUND) { 8599d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (V) Log.v(TAG, "Start pending outbound batch " + nextBatch.mId); 8609d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun mTransfer = new BluetoothOppTransfer(this, mPowerManager, nextBatch); 86109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mTransfer.start(); 86209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 8639d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } else if (nextBatch.mDirection == BluetoothShare.DIRECTION_INBOUND 8649d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun && mServerSession != null) { 8659d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun // have to support pending inbound transfer 8669d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun // if an outbound transfer and incoming socket happens together 8679d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun if (V) Log.v(TAG, "Start pending inbound batch " + nextBatch.mId); 8689d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun mServerTransfer = new BluetoothOppTransfer(this, mPowerManager, nextBatch, 8699d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun mServerSession); 8709d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun mServerTransfer.start(); 8710787917a687e31cbd1a9d8af5eca6b684a3ef894jun.x.wang if (nextBatch.getPendingShare() != null 8720787917a687e31cbd1a9d8af5eca6b684a3ef894jun.x.wang && nextBatch.getPendingShare().mConfirm == 8739d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun BluetoothShare.USER_CONFIRMATION_CONFIRMED) { 874e93cc4d347fd5d263d7740ad85f7f99b64651126Matthew Xie mServerTransfer.confirmStatusChanged(); 8759d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun } 8769d9e511fe7425fb3105ece227ecedb43d6333333Tao Liejun return; 87709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 87809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 87909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 88009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 88109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 88209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 88309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean needAction(int arrayPos) { 8846769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun BluetoothOppShareInfo info = mShares.get(arrayPos); 88509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (BluetoothShare.isStatusCompleted(info.mStatus)) { 88609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return false; 88709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 88809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return true; 88909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 89009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 89109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean visibleNotification(int arrayPos) { 8926769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun BluetoothOppShareInfo info = mShares.get(arrayPos); 89309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return info.hasCompletionNotification(); 89409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 89509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 89609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean scanFile(Cursor cursor, int arrayPos) { 8976769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun BluetoothOppShareInfo info = mShares.get(arrayPos); 8986769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun synchronized (BluetoothOppService.this) { 899ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (D) Log.d(TAG, "Scanning file " + info.mFilename); 9001ac5507790a87810061a19dadec36eb328a222eaTao Liejun if (!mMediaScanInProgress) { 9011ac5507790a87810061a19dadec36eb328a222eaTao Liejun mMediaScanInProgress = true; 9021ac5507790a87810061a19dadec36eb328a222eaTao Liejun new MediaScannerNotifier(this, info, mHandler); 9031ac5507790a87810061a19dadec36eb328a222eaTao Liejun return true; 9041ac5507790a87810061a19dadec36eb328a222eaTao Liejun } else { 9051ac5507790a87810061a19dadec36eb328a222eaTao Liejun return false; 9061ac5507790a87810061a19dadec36eb328a222eaTao Liejun } 90709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 90809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 90909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 91009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private boolean shouldScanFile(int arrayPos) { 9116769b59d715ea98bd72eafcfea9acd2714a887daTao Liejun BluetoothOppShareInfo info = mShares.get(arrayPos); 9121ac5507790a87810061a19dadec36eb328a222eaTao Liejun return BluetoothShare.isStatusSuccess(info.mStatus) 913d5e1472188b7e21123a02339ed8766256aa8f630Martijn Coenen && info.mDirection == BluetoothShare.DIRECTION_INBOUND && !info.mMediaScanned && 914d5e1472188b7e21123a02339ed8766256aa8f630Martijn Coenen info.mConfirm != BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED; 91509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 91609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 9170a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick // Run in a background thread at boot. 9180a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick private static void trimDatabase(ContentResolver contentResolver) { 919389f6dd45f7a45b12af847a510086125777e1198Lixin Yue final String INVISIBLE = BluetoothShare.VISIBILITY + "=" + 920389f6dd45f7a45b12af847a510086125777e1198Lixin Yue BluetoothShare.VISIBILITY_HIDDEN; 921389f6dd45f7a45b12af847a510086125777e1198Lixin Yue 922389f6dd45f7a45b12af847a510086125777e1198Lixin Yue // remove the invisible/complete/outbound shares 923389f6dd45f7a45b12af847a510086125777e1198Lixin Yue final String WHERE_INVISIBLE_COMPLETE_OUTBOUND = BluetoothShare.DIRECTION + "=" 924389f6dd45f7a45b12af847a510086125777e1198Lixin Yue + BluetoothShare.DIRECTION_OUTBOUND + " AND " + BluetoothShare.STATUS + ">=" 925389f6dd45f7a45b12af847a510086125777e1198Lixin Yue + BluetoothShare.STATUS_SUCCESS + " AND " + INVISIBLE; 9260a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick int delNum = contentResolver.delete(BluetoothShare.CONTENT_URI, 927389f6dd45f7a45b12af847a510086125777e1198Lixin Yue WHERE_INVISIBLE_COMPLETE_OUTBOUND, null); 928389f6dd45f7a45b12af847a510086125777e1198Lixin Yue if (V) Log.v(TAG, "Deleted complete outbound shares, number = " + delNum); 929389f6dd45f7a45b12af847a510086125777e1198Lixin Yue 930389f6dd45f7a45b12af847a510086125777e1198Lixin Yue // remove the invisible/finished/inbound/failed shares 931389f6dd45f7a45b12af847a510086125777e1198Lixin Yue final String WHERE_INVISIBLE_COMPLETE_INBOUND_FAILED = BluetoothShare.DIRECTION + "=" 932389f6dd45f7a45b12af847a510086125777e1198Lixin Yue + BluetoothShare.DIRECTION_INBOUND + " AND " + BluetoothShare.STATUS + ">" 933389f6dd45f7a45b12af847a510086125777e1198Lixin Yue + BluetoothShare.STATUS_SUCCESS + " AND " + INVISIBLE; 9340a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick delNum = contentResolver.delete(BluetoothShare.CONTENT_URI, 935389f6dd45f7a45b12af847a510086125777e1198Lixin Yue WHERE_INVISIBLE_COMPLETE_INBOUND_FAILED, null); 936389f6dd45f7a45b12af847a510086125777e1198Lixin Yue if (V) Log.v(TAG, "Deleted complete inbound failed shares, number = " + delNum); 937389f6dd45f7a45b12af847a510086125777e1198Lixin Yue 938389f6dd45f7a45b12af847a510086125777e1198Lixin Yue // Only keep the inbound and successful shares for LiverFolder use 939389f6dd45f7a45b12af847a510086125777e1198Lixin Yue // Keep the latest 1000 to easy db query 940389f6dd45f7a45b12af847a510086125777e1198Lixin Yue final String WHERE_INBOUND_SUCCESS = BluetoothShare.DIRECTION + "=" 941389f6dd45f7a45b12af847a510086125777e1198Lixin Yue + BluetoothShare.DIRECTION_INBOUND + " AND " + BluetoothShare.STATUS + "=" 942389f6dd45f7a45b12af847a510086125777e1198Lixin Yue + BluetoothShare.STATUS_SUCCESS + " AND " + INVISIBLE; 9430a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick Cursor cursor = contentResolver.query(BluetoothShare.CONTENT_URI, new String[] { 94409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly BluetoothShare._ID 945389f6dd45f7a45b12af847a510086125777e1198Lixin Yue }, WHERE_INBOUND_SUCCESS, null, BluetoothShare._ID); // sort by id 946389f6dd45f7a45b12af847a510086125777e1198Lixin Yue 94709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (cursor == null) { 94809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly return; 94909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 950389f6dd45f7a45b12af847a510086125777e1198Lixin Yue 951389f6dd45f7a45b12af847a510086125777e1198Lixin Yue int recordNum = cursor.getCount(); 952389f6dd45f7a45b12af847a510086125777e1198Lixin Yue if (recordNum > Constants.MAX_RECORDS_IN_DATABASE) { 953389f6dd45f7a45b12af847a510086125777e1198Lixin Yue int numToDelete = recordNum - Constants.MAX_RECORDS_IN_DATABASE; 95475fc857d22de0ec22e082bddb720d8465c9e3552Lixin Yue 95575fc857d22de0ec22e082bddb720d8465c9e3552Lixin Yue if (cursor.moveToPosition(numToDelete)) { 956389f6dd45f7a45b12af847a510086125777e1198Lixin Yue int columnId = cursor.getColumnIndexOrThrow(BluetoothShare._ID); 95775fc857d22de0ec22e082bddb720d8465c9e3552Lixin Yue long id = cursor.getLong(columnId); 9580a79bdbbfa3b79b808cbbe7490731e5aae4489e9Brad Fitzpatrick delNum = contentResolver.delete(BluetoothShare.CONTENT_URI, 95975fc857d22de0ec22e082bddb720d8465c9e3552Lixin Yue BluetoothShare._ID + " < " + id, null); 96075fc857d22de0ec22e082bddb720d8465c9e3552Lixin Yue if (V) Log.v(TAG, "Deleted old inbound success share: " + delNum); 96109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 96209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 96309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly cursor.close(); 96409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 96509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 96609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private static class MediaScannerNotifier implements MediaScannerConnectionClient { 96709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 96809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private MediaScannerConnection mConnection; 96909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 97009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private BluetoothOppShareInfo mInfo; 97109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 97209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Context mContext; 97309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 97409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly private Handler mCallback; 97509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 97609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public MediaScannerNotifier(Context context, BluetoothOppShareInfo info, Handler handler) { 97709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mContext = context; 97809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mInfo = info; 97909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mCallback = handler; 98009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mConnection = new MediaScannerConnection(mContext, this); 981ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "Connecting to MediaScannerConnection "); 98209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mConnection.connect(); 98309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 98409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 98509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void onMediaScannerConnected() { 986ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "MediaScannerConnection onMediaScannerConnected"); 98709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mConnection.scanFile(mInfo.mFilename, mInfo.mMimetype); 98809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 98909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly 99009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly public void onScanCompleted(String path, Uri uri) { 99109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly try { 992ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) { 99309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "MediaScannerConnection onScanCompleted"); 99409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "MediaScannerConnection path is " + path); 99509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "MediaScannerConnection Uri is " + uri); 99609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 99709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly if (uri != null) { 99809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Message msg = Message.obtain(); 99909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.setTarget(mCallback); 100009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.what = MEDIA_SCANNED; 100109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.arg1 = mInfo.mId; 100209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.obj = uri; 100309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.sendToTarget(); 100409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } else { 100509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Message msg = Message.obtain(); 100609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.setTarget(mCallback); 100709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.what = MEDIA_SCANNED_FAILED; 100809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.arg1 = mInfo.mId; 100909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly msg.sendToTarget(); 101009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 101109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } catch (Exception ex) { 101209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly Log.v(TAG, "!!!MediaScannerConnection exception: " + ex); 101309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } finally { 1014ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly if (V) Log.v(TAG, "MediaScannerConnection disconnect"); 101509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly mConnection.disconnect(); 101609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 101709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 101809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly } 101909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly} 1020