• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2008-2009, Motorola, Inc.
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * - Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * - Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * - Neither the name of the Motorola, Inc. nor the names of its contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 package com.android.bluetooth.opp;
34 
35 import android.bluetooth.BluetoothAdapter;
36 import android.bluetooth.BluetoothDevice;
37 import android.content.Context;
38 import android.util.Log;
39 
40 import com.android.bluetooth.BluetoothMethodProxy;
41 
42 import java.util.ArrayList;
43 
44 /**
45  * This class stores information about a batch of OPP shares that should be transferred in one
46  * session.
47  */
48 /*There are a few cases: 1. create a batch for a single file to send
49  * 2. create a batch for multiple files to send
50  * 3. add additional file(s) to existing batch to send
51  * 4. create a batch for receive single file
52  * 5. add additional file to existing batch to receive (this only happens as the server
53  * session notify more files to receive)
54  * 6. Cancel sending a single file
55  * 7. Cancel sending a file from multiple files (implies cancel the transfer, rest of
56  * the unsent files are also canceled)
57  * 8. Cancel receiving a single file
58  * 9. Cancel receiving a file (implies cancel the transfer, no additional files will be received)
59  */
60 
61 public class BluetoothOppBatch {
62     private static final String TAG = BluetoothOppBatch.class.getSimpleName();
63 
64     public int mId;
65     public int mStatus;
66 
67     public final long mTimestamp;
68     public final int mDirection;
69     public final BluetoothDevice mDestination;
70 
71     private BluetoothOppBatchListener mListener;
72 
73     private final ArrayList<BluetoothOppShareInfo> mShares;
74     private final Context mContext;
75 
76     /** An interface for notifying when BluetoothOppTransferBatch is changed */
77     public interface BluetoothOppBatchListener {
78         /**
79          * Called to notify when a share is added into the batch
80          *
81          * @param id , BluetoothOppShareInfo.id
82          */
onShareAdded(int id)83         void onShareAdded(int id);
84 
85         /**
86          * Called to notify when a share is deleted from the batch
87          *
88          * @param id , BluetoothOppShareInfo.id
89          */
onShareDeleted(int id)90         void onShareDeleted(int id);
91 
92         /** Called to notify when the batch is canceled */
onBatchCanceled()93         void onBatchCanceled();
94     }
95 
96     /**
97      * A batch is always created with at least one ShareInfo
98      *
99      * @param context, Context
100      * @param info, BluetoothOppShareInfo
101      */
BluetoothOppBatch(Context context, BluetoothOppShareInfo info)102     public BluetoothOppBatch(Context context, BluetoothOppShareInfo info) {
103         mContext = context;
104         mShares = new ArrayList();
105         mTimestamp = info.mTimestamp;
106         mDirection = info.mDirection;
107         mDestination = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(info.mDestination);
108         mStatus = Constants.BATCH_STATUS_PENDING;
109         mShares.add(info);
110 
111         Log.v(TAG, "New Batch created for info " + info.mId);
112     }
113 
114     /** Add one share into the batch. */
115     /* There are 2 cases: Service scans the databases and it's multiple send
116      * Service receives database update and know additional file should be received
117      */
addShare(BluetoothOppShareInfo info)118     public void addShare(BluetoothOppShareInfo info) {
119         mShares.add(info);
120         if (mListener != null) {
121             mListener.onShareAdded(info.mId);
122         }
123     }
124 
125     /** Cancel the whole batch. */
126     /* 1) If the batch is running, stop the transfer
127      * 2) Go through mShares list and mark all incomplete share as CANCELED status
128      * 3) update ContentProvider for these canceled transfer
129      */
cancelBatch()130     public void cancelBatch() {
131         Log.v(TAG, "batch " + this.mId + " is canceled");
132 
133         if (mListener != null) {
134             mListener.onBatchCanceled();
135         }
136         // TODO investigate if below code is redundant
137         for (int i = mShares.size() - 1; i >= 0; i--) {
138             BluetoothOppShareInfo info = mShares.get(i);
139 
140             if (info.mStatus < 200) {
141                 if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && info.mUri != null) {
142                     BluetoothMethodProxy.getInstance()
143                             .contentResolverDelete(
144                                     mContext.getContentResolver(), info.mUri, null, null);
145                 }
146                 Log.v(TAG, "Cancel batch for info " + info.mId);
147 
148                 Constants.updateShareStatus(mContext, info.mId, BluetoothShare.STATUS_CANCELED);
149             }
150         }
151         mShares.clear();
152     }
153 
154     /** check if a specific share is in this batch */
hasShare(BluetoothOppShareInfo info)155     public boolean hasShare(BluetoothOppShareInfo info) {
156         return mShares.contains(info);
157     }
158 
159     /** if this batch is empty */
isEmpty()160     public boolean isEmpty() {
161         return (mShares.size() == 0);
162     }
163 
getNumShares()164     public int getNumShares() {
165         return mShares.size();
166     }
167 
168     /**
169      * Get the running status of the batch
170      *
171      * @return
172      */
173 
174     /** register a listener for the batch change */
registerListener(BluetoothOppBatchListener listener)175     public void registerListener(BluetoothOppBatchListener listener) {
176         mListener = listener;
177     }
178 
179     /**
180      * Get the first pending ShareInfo of the batch
181      *
182      * @return BluetoothOppShareInfo, for the first pending share, or null if none exists
183      */
getPendingShare()184     public BluetoothOppShareInfo getPendingShare() {
185         for (int i = 0; i < mShares.size(); i++) {
186             BluetoothOppShareInfo share = mShares.get(i);
187             if (share.mStatus == BluetoothShare.STATUS_PENDING) {
188                 return share;
189             }
190         }
191         return null;
192     }
193 }
194