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
3541ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.bluetooth.BluetoothAdapter;
3641ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.bluetooth.BluetoothDevice;
3709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.ContentResolver;
3809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.ContentValues;
3909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.Context;
40c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yueimport android.content.Intent;
4109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellyimport android.content.SharedPreferences;
4241ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.net.Uri;
43c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yueimport android.os.Process;
448099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenenimport android.os.SystemClock;
45c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yueimport android.text.TextUtils;
4641ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport android.util.Log;
478099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenenimport android.util.Pair;
4809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
49c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport com.android.bluetooth.R;
50c4fbd756e2645147470c486ae96f2253f5e13a52Jack He
5141ef8d494511c040451f2f887cb31c3100746b61Nick Pellyimport java.util.ArrayList;
528099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenenimport java.util.Iterator;
53d6eaf19f39e163e16d22e29907edec402b30622eNick Pellyimport java.util.List;
5409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
5509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly/**
5609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * This class provides a simplified interface on top of other Bluetooth service
5709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * layer components; Also it handles some Opp application level variables. It's
5809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly * a singleton got from BluetoothOppManager.getInstance(context);
5909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly */
6009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pellypublic class BluetoothOppManager {
6109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String TAG = "BluetoothOppManager";
62ce4d93666275df294cb073fe41de5b85932570a8Nick Pelly    private static final boolean V = Constants.VERBOSE;
6309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
641bd017d12cf16ecd52fb486722e300790bddeefcJack He    private static BluetoothOppManager sInstance;
6509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /** Used when obtaining a reference to the singleton instance. */
671bd017d12cf16ecd52fb486722e300790bddeefcJack He    private static final Object INSTANCE_LOCK = new Object();
6809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
6909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private boolean mInitialized;
7009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private Context mContext;
7209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7341ef8d494511c040451f2f887cb31c3100746b61Nick Pelly    private BluetoothAdapter mAdapter;
7409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7555470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick    private String mMimeTypeOfSendingFile;
7609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private String mUriOfSendingFile;
7809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
7955470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick    private String mMimeTypeOfSendingFiles;
8009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
811ac5507790a87810061a19dadec36eb328a222eaTao Liejun    private ArrayList<Uri> mUrisOfSendingFiles;
8209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
838099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen    private boolean mIsHandoverInitiated;
848099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen
8509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String OPP_PREFERENCE_FILE = "OPPMGR";
8609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String SENDING_FLAG = "SENDINGFLAG";
8809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
8909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String MIME_TYPE = "MIMETYPE";
9009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String FILE_URI = "FILE_URI";
9209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String MIME_TYPE_MULTIPLE = "MIMETYPE_MULTIPLE";
9409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String FILE_URIS = "FILE_URIS";
9609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
9709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private static final String MULTIPLE_FLAG = "MULTIPLE_FLAG";
9809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
99c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    private static final String ARRAYLIST_ITEM_SEPERATOR = ";";
100c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
101c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    private static final int ALLOWED_INSERT_SHARE_THREAD_NUMBER = 3;
10209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
10309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    // used to judge if need continue sending process after received a
10409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    // ENABLED_ACTION
10509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public boolean mSendingFlag;
10609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
10709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public boolean mMultipleFlag;
10809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
1098bc413b0b749ea9df59e858493273e05087fe887Jack He    private int mFileNumInBatch;
110c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
111c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    private int mInsertShareThreadNum = 0;
11209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
1138099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen    // A list of devices that may send files over OPP to this device
1148099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen    // without user confirmation. Used for connection handover from forex NFC.
115c4fbd756e2645147470c486ae96f2253f5e13a52Jack He    private List<Pair<String, Long>> mWhitelist = new ArrayList<Pair<String, Long>>();
1168099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen
1178099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen    // The time for which the whitelist entries remain valid.
1188099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen    private static final int WHITELIST_DURATION_MS = 15000;
1198099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen
12009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
12109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Get singleton instance.
12209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
12309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public static BluetoothOppManager getInstance(Context context) {
12409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        synchronized (INSTANCE_LOCK) {
1251bd017d12cf16ecd52fb486722e300790bddeefcJack He            if (sInstance == null) {
1261bd017d12cf16ecd52fb486722e300790bddeefcJack He                sInstance = new BluetoothOppManager();
12709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
1281bd017d12cf16ecd52fb486722e300790bddeefcJack He            sInstance.init(context);
12909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
1301bd017d12cf16ecd52fb486722e300790bddeefcJack He            return sInstance;
13109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
13209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
13309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
13409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
13509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * init
13609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
13709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private boolean init(Context context) {
138c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        if (mInitialized) {
13909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            return true;
140c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        }
14109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mInitialized = true;
14209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
1430bd5f7b5c36a60687ffe895368fd8df6df38acabJaikumar Ganesh        mContext = context;
14409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
1453a88b20fcd71e42451e402d27374b19eeb2ff0daNick Pelly        mAdapter = BluetoothAdapter.getDefaultAdapter();
14641ef8d494511c040451f2f887cb31c3100746b61Nick Pelly        if (mAdapter == null) {
147c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            if (V) {
148c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                Log.v(TAG, "BLUETOOTH_SERVICE is not started! ");
149c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            }
15009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
15109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
15209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        // Restore data from preference
15309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        restoreApplicationData();
15409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
15509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        return true;
15609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
15709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
1588099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen
1598099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen    private void cleanupWhitelist() {
1608099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        // Removes expired entries
1618099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        long curTime = SystemClock.elapsedRealtime();
162c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        for (Iterator<Pair<String, Long>> iter = mWhitelist.iterator(); iter.hasNext(); ) {
163c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            Pair<String, Long> entry = iter.next();
1648099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen            if (curTime - entry.second > WHITELIST_DURATION_MS) {
165c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                if (V) {
166c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                    Log.v(TAG, "Cleaning out whitelist entry " + entry.first);
167c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                }
1688099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                iter.remove();
1698099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen            }
1708099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        }
1718099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen    }
172d6eaf19f39e163e16d22e29907edec402b30622eNick Pelly
1737a4cc5c2f6ec06e8dc6f930680ce9aceff6df359Martijn Coenen    public synchronized void addToWhitelist(String address) {
174c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        if (address == null) {
175c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            return;
176c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        }
1777a4cc5c2f6ec06e8dc6f930680ce9aceff6df359Martijn Coenen        // Remove any existing entries
178c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        for (Iterator<Pair<String, Long>> iter = mWhitelist.iterator(); iter.hasNext(); ) {
179c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            Pair<String, Long> entry = iter.next();
1807a4cc5c2f6ec06e8dc6f930680ce9aceff6df359Martijn Coenen            if (entry.first.equals(address)) {
1817a4cc5c2f6ec06e8dc6f930680ce9aceff6df359Martijn Coenen                iter.remove();
1827a4cc5c2f6ec06e8dc6f930680ce9aceff6df359Martijn Coenen            }
1837a4cc5c2f6ec06e8dc6f930680ce9aceff6df359Martijn Coenen        }
1848099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        mWhitelist.add(new Pair<String, Long>(address, SystemClock.elapsedRealtime()));
185d6eaf19f39e163e16d22e29907edec402b30622eNick Pelly    }
186d6eaf19f39e163e16d22e29907edec402b30622eNick Pelly
1877a4cc5c2f6ec06e8dc6f930680ce9aceff6df359Martijn Coenen    public synchronized boolean isWhitelisted(String address) {
1888099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        cleanupWhitelist();
189c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        for (Pair<String, Long> entry : mWhitelist) {
190c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            if (entry.first.equals(address)) {
191c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                return true;
192c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            }
1938099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        }
1948099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        return false;
195d6eaf19f39e163e16d22e29907edec402b30622eNick Pelly    }
196d6eaf19f39e163e16d22e29907edec402b30622eNick Pelly
19709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
19809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Restore data from preference
19909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
20009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    private void restoreApplicationData() {
20109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        SharedPreferences settings = mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0);
20209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
203c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        // All member vars are not initialized till now
20409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mSendingFlag = settings.getBoolean(SENDING_FLAG, false);
20555470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick        mMimeTypeOfSendingFile = settings.getString(MIME_TYPE, null);
20609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mUriOfSendingFile = settings.getString(FILE_URI, null);
20755470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick        mMimeTypeOfSendingFiles = settings.getString(MIME_TYPE_MULTIPLE, null);
20809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        mMultipleFlag = settings.getBoolean(MULTIPLE_FLAG, false);
20909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
210c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        if (V) {
211c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            Log.v(TAG, "restoreApplicationData! " + mSendingFlag + mMultipleFlag
21255470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick                    + mMimeTypeOfSendingFile + mUriOfSendingFile);
213c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        }
21409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
21509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        String strUris = settings.getString(FILE_URIS, null);
216c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        mUrisOfSendingFiles = new ArrayList<Uri>();
217c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        if (strUris != null) {
218c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            String[] splitUri = strUris.split(ARRAYLIST_ITEM_SEPERATOR);
219c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            for (int i = 0; i < splitUri.length; i++) {
220c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                mUrisOfSendingFiles.add(Uri.parse(splitUri[i]));
221c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                if (V) {
222c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                    Log.v(TAG, "Uri in batch:  " + Uri.parse(splitUri[i]));
223c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                }
224c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
225c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        }
226c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
22755470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick        mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0).edit().clear().apply();
22809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
22909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
23009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
231c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * Save application data to preference, need restore these data when service restart
23209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
233c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    private void storeApplicationData() {
234c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        SharedPreferences.Editor editor =
235c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0).edit();
23655470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick        editor.putBoolean(SENDING_FLAG, mSendingFlag);
23755470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick        editor.putBoolean(MULTIPLE_FLAG, mMultipleFlag);
238c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        if (mMultipleFlag) {
23955470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.putString(MIME_TYPE_MULTIPLE, mMimeTypeOfSendingFiles);
240c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            StringBuilder sb = new StringBuilder();
241c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            for (int i = 0, count = mUrisOfSendingFiles.size(); i < count; i++) {
242c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                Uri uriContent = mUrisOfSendingFiles.get(i);
243c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                sb.append(uriContent);
244c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                sb.append(ARRAYLIST_ITEM_SEPERATOR);
245c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
246c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            String strUris = sb.toString();
24755470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.putString(FILE_URIS, strUris);
24809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
24955470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.remove(MIME_TYPE);
25055470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.remove(FILE_URI);
251c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        } else {
25255470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.putString(MIME_TYPE, mMimeTypeOfSendingFile);
25355470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.putString(FILE_URI, mUriOfSendingFile);
254c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
25555470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.remove(MIME_TYPE_MULTIPLE);
25655470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            editor.remove(FILE_URIS);
25709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
25855470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick        editor.apply();
259c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        if (V) {
260c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            Log.v(TAG, "Application data stored to SharedPreference! ");
261c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        }
26209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
26309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
264fe1c54e3fcbb75af7e49aecbd27ab7327a631c64Jack He    public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover,
265fe1c54e3fcbb75af7e49aecbd27ab7327a631c64Jack He            boolean fromExternal) throws IllegalArgumentException {
266c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        synchronized (BluetoothOppManager.this) {
267c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            mMultipleFlag = false;
26855470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            mMimeTypeOfSendingFile = mimeType;
2698099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen            mIsHandoverInitiated = isHandover;
270ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby            Uri uri = Uri.parse(uriString);
2714f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta            BluetoothOppSendFileInfo sendFileInfo =
272c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                    BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType,
2734f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                    fromExternal);
2744f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta            uri = BluetoothOppUtility.generateUri(uri, sendFileInfo);
2754f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta            BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo);
2764f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta            mUriOfSendingFile = uri.toString();
277c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            storeApplicationData();
278c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        }
27909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
28009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
281fe1c54e3fcbb75af7e49aecbd27ab7327a631c64Jack He    public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover,
282fe1c54e3fcbb75af7e49aecbd27ab7327a631c64Jack He            boolean fromExternal) throws IllegalArgumentException {
283c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        synchronized (BluetoothOppManager.this) {
284c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            mMultipleFlag = true;
28555470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            mMimeTypeOfSendingFiles = mimeType;
2864f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta            mUrisOfSendingFiles = new ArrayList<Uri>();
2878099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen            mIsHandoverInitiated = isHandover;
288ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby            for (Uri uri : uris) {
2894f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                BluetoothOppSendFileInfo sendFileInfo =
290c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                        BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType,
2914f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                        fromExternal);
2924f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                uri = BluetoothOppUtility.generateUri(uri, sendFileInfo);
2934f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                mUrisOfSendingFiles.add(uri);
2944f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                BluetoothOppUtility.putSendFileInfo(uri, sendFileInfo);
295ee52ddf33a0ce2cf89cc028136f60ae600c45de5Jake Hamby            }
296c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            storeApplicationData();
297c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        }
29809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
299c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
30009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
30109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Get the current status of Bluetooth hardware.
30209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * @return true if Bluetooth enabled, false otherwise.
30309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
30409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public boolean isEnabled() {
30541ef8d494511c040451f2f887cb31c3100746b61Nick Pelly        if (mAdapter != null) {
30641ef8d494511c040451f2f887cb31c3100746b61Nick Pelly            return mAdapter.isEnabled();
30709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        } else {
308c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            if (V) {
309c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                Log.v(TAG, "BLUETOOTH_SERVICE is not available! ");
310c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            }
31109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            return false;
31209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
31309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
31409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
31509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
31609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Enable Bluetooth hardware.
31709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
31809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void enableBluetooth() {
31941ef8d494511c040451f2f887cb31c3100746b61Nick Pelly        if (mAdapter != null) {
32041ef8d494511c040451f2f887cb31c3100746b61Nick Pelly            mAdapter.enable();
32109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
32209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
32309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
32409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
32509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Disable Bluetooth hardware.
32609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
32709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    public void disableBluetooth() {
32841ef8d494511c040451f2f887cb31c3100746b61Nick Pelly        if (mAdapter != null) {
32941ef8d494511c040451f2f887cb31c3100746b61Nick Pelly            mAdapter.disable();
33009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
33109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
33209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
33309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
33409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     * Get device name per bluetooth address.
33509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
33641ef8d494511c040451f2f887cb31c3100746b61Nick Pelly    public String getDeviceName(BluetoothDevice device) {
33784df5050bb2db34b9caeb67774caf3896a22c30fHemant Gupta        String deviceName = null;
33809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
33984df5050bb2db34b9caeb67774caf3896a22c30fHemant Gupta        if (device != null) {
34084df5050bb2db34b9caeb67774caf3896a22c30fHemant Gupta            deviceName = device.getAliasName();
34184df5050bb2db34b9caeb67774caf3896a22c30fHemant Gupta            if (deviceName == null) {
34284df5050bb2db34b9caeb67774caf3896a22c30fHemant Gupta                deviceName = BluetoothOppPreference.getInstance(mContext).getName(device);
34384df5050bb2db34b9caeb67774caf3896a22c30fHemant Gupta            }
34409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
34509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
34609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        if (deviceName == null) {
34709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            deviceName = mContext.getString(R.string.unknown_device);
34809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
34909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
35009e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        return deviceName;
35109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
35209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
353c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    public int getBatchSize() {
354c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        synchronized (BluetoothOppManager.this) {
3558bc413b0b749ea9df59e858493273e05087fe887Jack He            return mFileNumInBatch;
356c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        }
357c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    }
358c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
35909e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    /**
360c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * Fork a thread to insert share info to db.
36109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly     */
36241ef8d494511c040451f2f887cb31c3100746b61Nick Pelly    public void startTransfer(BluetoothDevice device) {
363c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        if (V) {
364c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            Log.v(TAG, "Active InsertShareThread number is : " + mInsertShareThreadNum);
365c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        }
366c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        InsertShareInfoThread insertThread;
367c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        synchronized (BluetoothOppManager.this) {
368c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            if (mInsertShareThreadNum > ALLOWED_INSERT_SHARE_THREAD_NUMBER) {
369c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                Log.e(TAG, "Too many shares user triggered concurrently!");
370c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
371c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                // Notice user
372c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                Intent in = new Intent(mContext, BluetoothOppBtErrorActivity.class);
373c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
374c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                in.putExtra("title", mContext.getString(R.string.enabling_progress_title));
375c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                in.putExtra("content", mContext.getString(R.string.ErrorTooManyRequests));
376c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                mContext.startActivity(in);
377c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
378c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                return;
379c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
38055470710c2624bde2aa56275d29b60055638c06cBrad Fitzpatrick            insertThread = new InsertShareInfoThread(device, mMultipleFlag, mMimeTypeOfSendingFile,
3818099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                    mUriOfSendingFile, mMimeTypeOfSendingFiles, mUrisOfSendingFiles,
3828099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                    mIsHandoverInitiated);
383c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            if (mMultipleFlag) {
3848bc413b0b749ea9df59e858493273e05087fe887Jack He                mFileNumInBatch = mUrisOfSendingFiles.size();
385c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
38609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
38709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
388c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        insertThread.start();
389c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    }
390c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
391c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    /**
392c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * Thread to insert share info to db. In multiple files (say 100 files)
393c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * share case, the inserting share info to db operation would be a time
394c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * consuming operation, so need a thread to handle it. This thread allows
395c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * multiple instances to support below case: User select multiple files to
396c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * share to one device (say device 1), and then right away share to second
397c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     * device (device 2), we need insert all these share info to db.
398c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue     */
399c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue    private class InsertShareInfoThread extends Thread {
400c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private final BluetoothDevice mRemoteDevice;
401c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
402c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private final String mTypeOfSingleFile;
403c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
404c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private final String mUri;
405c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
406c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private final String mTypeOfMultipleFiles;
407c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
408c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private final ArrayList<Uri> mUris;
409c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
410c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private final boolean mIsMultiple;
411c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
4128099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen        private final boolean mIsHandoverInitiated;
4138099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen
414c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        InsertShareInfoThread(BluetoothDevice device, boolean multiple, String typeOfSingleFile,
415c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                String uri, String typeOfMultipleFiles, ArrayList<Uri> uris,
416c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                boolean handoverInitiated) {
417c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            super("Insert ShareInfo Thread");
418c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            this.mRemoteDevice = device;
419c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            this.mIsMultiple = multiple;
420c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            this.mTypeOfSingleFile = typeOfSingleFile;
421c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            this.mUri = uri;
422c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            this.mTypeOfMultipleFiles = typeOfMultipleFiles;
423c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            this.mUris = uris;
4248099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen            this.mIsHandoverInitiated = handoverInitiated;
425c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
426c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            synchronized (BluetoothOppManager.this) {
427c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                mInsertShareThreadNum++;
428c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
429c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
430c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            if (V) {
431c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                Log.v(TAG, "Thread id is: " + this.getId());
432c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            }
43309e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
43409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
435c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        @Override
436c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        public void run() {
437c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
438c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            if (mRemoteDevice == null) {
439c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                Log.e(TAG, "Target bt device is null!");
440c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                return;
441c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
442c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            if (mIsMultiple) {
443c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                insertMultipleShare();
444c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            } else {
445c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                insertSingleShare();
446c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
447c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            synchronized (BluetoothOppManager.this) {
448c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                mInsertShareThreadNum--;
449c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            }
450c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        }
45109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
452c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        /**
453c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue         * Insert multiple sending sessions to db, only used by Opp application.
454c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue         */
455c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private void insertMultipleShare() {
456c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            int count = mUris.size();
45709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            Long ts = System.currentTimeMillis();
45809e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            for (int i = 0; i < count; i++) {
459c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                Uri fileUri = mUris.get(i);
4604f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                ContentValues values = new ContentValues();
4614f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                values.put(BluetoothShare.URI, fileUri.toString());
46209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                ContentResolver contentResolver = mContext.getContentResolver();
4634f729983b79023a42a84a124248cc2fd39b51d0eHemant Gupta                fileUri = BluetoothOppUtility.originalUri(fileUri);
4641ac5507790a87810061a19dadec36eb328a222eaTao Liejun                String contentType = contentResolver.getType(fileUri);
465c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                if (V) {
466c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                    Log.v(TAG, "Got mimetype: " + contentType + "  Got uri: " + fileUri);
467c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                }
468c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                if (TextUtils.isEmpty(contentType)) {
469c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                    contentType = mTypeOfMultipleFiles;
470c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                }
47109e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly
47209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                values.put(BluetoothShare.MIMETYPE, contentType);
473c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue                values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress());
47409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly                values.put(BluetoothShare.TIMESTAMP, ts);
4758099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                if (mIsHandoverInitiated) {
4768099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                    values.put(BluetoothShare.USER_CONFIRMATION,
4778099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                            BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED);
4788099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                }
479c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                final Uri contentUri =
480c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                        mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values);
481c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                if (V) {
482c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                    Log.v(TAG, "Insert contentUri: " + contentUri + "  to device: " + getDeviceName(
483c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                            mRemoteDevice));
484c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                }
48509e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            }
486c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        }
487c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
488c4fbd756e2645147470c486ae96f2253f5e13a52Jack He        /**
489c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue         * Insert single sending session to db, only used by Opp application.
490c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue         */
491c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue        private void insertSingleShare() {
49209e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly            ContentValues values = new ContentValues();
493c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            values.put(BluetoothShare.URI, mUri);
494c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            values.put(BluetoothShare.MIMETYPE, mTypeOfSingleFile);
495c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue            values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress());
4968099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen            if (mIsHandoverInitiated) {
4978099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                values.put(BluetoothShare.USER_CONFIRMATION,
4988099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen                        BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED);
4998099f5e7bfa7227ba674b5f0076f331e737bafd7Martijn Coenen            }
500c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            final Uri contentUri =
501c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                    mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values);
502c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            if (V) {
503c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                Log.v(TAG, "Insert contentUri: " + contentUri + "  to device: " + getDeviceName(
504c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                        mRemoteDevice));
505c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            }
50609e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly        }
50709e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly    }
508c6f1bacf1d4c39d7efd5dc98004d936c18ed51f1Lixin Yue
5091c87133a411302f275440bad23aa04b720dcd753Hemant Gupta    void cleanUpSendingFileInfo() {
5101c87133a411302f275440bad23aa04b720dcd753Hemant Gupta        synchronized (BluetoothOppManager.this) {
511c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            if (V) {
512c4fbd756e2645147470c486ae96f2253f5e13a52Jack He                Log.v(TAG, "cleanUpSendingFileInfo: mMultipleFlag = " + mMultipleFlag);
513c4fbd756e2645147470c486ae96f2253f5e13a52Jack He            }
5141c87133a411302f275440bad23aa04b720dcd753Hemant Gupta            if (!mMultipleFlag && (mUriOfSendingFile != null)) {
5151c87133a411302f275440bad23aa04b720dcd753Hemant Gupta                Uri uri = Uri.parse(mUriOfSendingFile);
5161c87133a411302f275440bad23aa04b720dcd753Hemant Gupta                BluetoothOppUtility.closeSendFileInfo(uri);
5171c87133a411302f275440bad23aa04b720dcd753Hemant Gupta            } else if (mUrisOfSendingFiles != null) {
5181c87133a411302f275440bad23aa04b720dcd753Hemant Gupta                for (Uri uri : mUrisOfSendingFiles) {
5191c87133a411302f275440bad23aa04b720dcd753Hemant Gupta                    BluetoothOppUtility.closeSendFileInfo(uri);
5201c87133a411302f275440bad23aa04b720dcd753Hemant Gupta                }
5211c87133a411302f275440bad23aa04b720dcd753Hemant Gupta            }
5221c87133a411302f275440bad23aa04b720dcd753Hemant Gupta        }
5231c87133a411302f275440bad23aa04b720dcd753Hemant Gupta    }
52409e9cba205af60b3f42e7a4d891a7d1392e1f2a5Nick Pelly}
525