• 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 java.io.File;
36 import java.util.ArrayList;
37 
38 import android.bluetooth.BluetoothAdapter;
39 import android.bluetooth.BluetoothDevice;
40 import android.content.Context;
41 import android.util.Log;
42 
43 import com.google.android.collect.Lists;
44 
45 /**
46  * This class stores information about a batch of OPP shares that should be
47  * transferred in one session.
48  */
49 /*There are a few cases: 1. create a batch for a single file to send
50  * 2. create a batch for multiple files to send
51  * 3. add additional file(s) to existing batch to send
52  * 4. create a batch for receive single file
53  * 5. add additional file to existing batch to receive (this only happens as the server
54  * session notify more files to receive)
55  * 6. Cancel sending a single file
56  * 7. Cancel sending a file from multiple files (implies cancel the transfer, rest of
57  * the unsent files are also canceled)
58  * 8. Cancel receiving a single file
59  * 9. Cancel receiving a file (implies cancel the transfer, no additional files will be received)
60  */
61 
62 public class BluetoothOppBatch {
63     private static final String TAG = "BtOppBatch";
64     private static final boolean V = Constants.VERBOSE;
65 
66     public int mId;
67     public int mStatus;
68 
69     public final long mTimestamp;
70     public final int mDirection;
71     public final BluetoothDevice mDestination;
72 
73     private BluetoothOppBatchListener mListener;
74 
75     private final ArrayList<BluetoothOppShareInfo> mShares;
76     private final Context mContext;
77 
78     /**
79      * An interface for notifying when BluetoothOppTransferBatch is changed
80      */
81     public interface BluetoothOppBatchListener {
82         /**
83          * Called to notify when a share is added into the batch
84          * @param id , BluetoothOppShareInfo.id
85          */
onShareAdded(int id)86         public void onShareAdded(int id);
87 
88         /**
89          * Called to notify when a share is deleted from the batch
90          * @param id , BluetoothOppShareInfo.id
91          */
onShareDeleted(int id)92         public void onShareDeleted(int id);
93 
94         /**
95          * Called to notify when the batch is canceled
96          */
onBatchCanceled()97         public void onBatchCanceled();
98     }
99 
100     /**
101      * A batch is always created with at least one ShareInfo
102      * @param context, Context
103      * @param info, BluetoothOppShareInfo
104      */
BluetoothOppBatch(Context context, BluetoothOppShareInfo info)105     public BluetoothOppBatch(Context context, BluetoothOppShareInfo info) {
106         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
107         mContext = context;
108         mShares = Lists.newArrayList();
109         mTimestamp = info.mTimestamp;
110         mDirection = info.mDirection;
111         mDestination = adapter.getRemoteDevice(info.mDestination);
112         mStatus = Constants.BATCH_STATUS_PENDING;
113         mShares.add(info);
114 
115         if (V) Log.v(TAG, "New Batch created for info " + info.mId);
116     }
117 
118     /**
119      * Add one share into the batch.
120      */
121     /* There are 2 cases: Service scans the databases and it's multiple send
122      * Service receives database update and know additional file should be received
123      */
124 
addShare(BluetoothOppShareInfo info)125     public void addShare(BluetoothOppShareInfo info) {
126         mShares.add(info);
127         if (mListener != null) {
128             mListener.onShareAdded(info.mId);
129         }
130     }
131 
132     /**
133      * Delete one share from the batch. Not used now.
134      */
135     /*It should only be called under requirement that cancel one single share, but not to
136      * cancel the whole batch. Currently we assume "cancel" is to cancel whole batch.
137      */
deleteShare(BluetoothOppShareInfo info)138     public void deleteShare(BluetoothOppShareInfo info) {
139         if (info.mStatus == BluetoothShare.STATUS_RUNNING) {
140             info.mStatus = BluetoothShare.STATUS_CANCELED;
141             if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && info.mFilename != null) {
142                 new File(info.mFilename).delete();
143             }
144         }
145 
146         if (mListener != null) {
147             mListener.onShareDeleted(info.mId);
148         }
149     }
150 
151     /**
152      * Cancel the whole batch.
153      */
154     /* 1) If the batch is running, stop the transfer
155      * 2) Go through mShares list and mark all incomplete share as CANCELED status
156      * 3) update ContentProvider for these canceled transfer
157      */
cancelBatch()158     public void cancelBatch() {
159         if (V) Log.v(TAG, "batch " + this.mId + " is canceled");
160 
161         if (mListener != null) {
162             mListener.onBatchCanceled();
163         }
164         //TODO investigate if below code is redundant
165         for (int i = mShares.size() - 1; i >= 0; i--) {
166             BluetoothOppShareInfo info = mShares.get(i);
167 
168             if (info.mStatus < 200) {
169                 if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && info.mFilename != null) {
170                     new File(info.mFilename).delete();
171                 }
172                 if (V) Log.v(TAG, "Cancel batch for info " + info.mId);
173 
174                 Constants.updateShareStatus(mContext, info.mId, BluetoothShare.STATUS_CANCELED);
175             }
176         }
177         mShares.clear();
178     }
179 
180     /** check if a specific share is in this batch */
hasShare(BluetoothOppShareInfo info)181     public boolean hasShare(BluetoothOppShareInfo info) {
182         return mShares.contains(info);
183     }
184 
185     /** if this batch is empty */
isEmpty()186     public boolean isEmpty() {
187         return (mShares.size() == 0);
188     }
189 
getNumShares()190     public int getNumShares() {
191         return mShares.size();
192     }
193 
194     /**
195      * Get the running status of the batch
196      * @return
197      */
198 
199     /** register a listener for the batch change */
registerListern(BluetoothOppBatchListener listener)200     public void registerListern(BluetoothOppBatchListener listener) {
201         mListener = listener;
202     }
203 
204     /**
205      * Get the first pending ShareInfo of the batch
206      * @return BluetoothOppShareInfo, for the first pending share, or null if
207      *         none exists
208      */
getPendingShare()209     public BluetoothOppShareInfo getPendingShare() {
210         for (int i = 0; i < mShares.size(); i++) {
211             BluetoothOppShareInfo share = mShares.get(i);
212             if (share.mStatus == BluetoothShare.STATUS_PENDING) {
213                 return share;
214             }
215         }
216         return null;
217     }
218 }
219