Home | History | Annotate | Download | only in opp
      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.google.android.collect.Lists;
     41 
     42 import java.io.File;
     43 import java.util.ArrayList;
     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          */
     86         void onShareAdded(int id);
     87 
     88         /**
     89          * Called to notify when a share is deleted from the batch
     90          * @param id , BluetoothOppShareInfo.id
     91          */
     92         void onShareDeleted(int id);
     93 
     94         /**
     95          * Called to notify when the batch is canceled
     96          */
     97         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      */
    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) {
    116             Log.v(TAG, "New Batch created for info " + info.mId);
    117         }
    118     }
    119 
    120     /**
    121      * Add one share into the batch.
    122      */
    123     /* There are 2 cases: Service scans the databases and it's multiple send
    124      * Service receives database update and know additional file should be received
    125      */
    126     public void addShare(BluetoothOppShareInfo info) {
    127         mShares.add(info);
    128         if (mListener != null) {
    129             mListener.onShareAdded(info.mId);
    130         }
    131     }
    132 
    133     /**
    134      * Cancel the whole batch.
    135      */
    136     /* 1) If the batch is running, stop the transfer
    137      * 2) Go through mShares list and mark all incomplete share as CANCELED status
    138      * 3) update ContentProvider for these canceled transfer
    139      */
    140     public void cancelBatch() {
    141         if (V) {
    142             Log.v(TAG, "batch " + this.mId + " is canceled");
    143         }
    144 
    145         if (mListener != null) {
    146             mListener.onBatchCanceled();
    147         }
    148         //TODO investigate if below code is redundant
    149         for (int i = mShares.size() - 1; i >= 0; i--) {
    150             BluetoothOppShareInfo info = mShares.get(i);
    151 
    152             if (info.mStatus < 200) {
    153                 if (info.mDirection == BluetoothShare.DIRECTION_INBOUND && info.mFilename != null) {
    154                     new File(info.mFilename).delete();
    155                 }
    156                 if (V) {
    157                     Log.v(TAG, "Cancel batch for info " + info.mId);
    158                 }
    159 
    160                 Constants.updateShareStatus(mContext, info.mId, BluetoothShare.STATUS_CANCELED);
    161             }
    162         }
    163         mShares.clear();
    164     }
    165 
    166     /** check if a specific share is in this batch */
    167     public boolean hasShare(BluetoothOppShareInfo info) {
    168         return mShares.contains(info);
    169     }
    170 
    171     /** if this batch is empty */
    172     public boolean isEmpty() {
    173         return (mShares.size() == 0);
    174     }
    175 
    176     public int getNumShares() {
    177         return mShares.size();
    178     }
    179 
    180     /**
    181      * Get the running status of the batch
    182      * @return
    183      */
    184 
    185     /** register a listener for the batch change */
    186     public void registerListern(BluetoothOppBatchListener listener) {
    187         mListener = listener;
    188     }
    189 
    190     /**
    191      * Get the first pending ShareInfo of the batch
    192      * @return BluetoothOppShareInfo, for the first pending share, or null if
    193      *         none exists
    194      */
    195     public BluetoothOppShareInfo getPendingShare() {
    196         for (int i = 0; i < mShares.size(); i++) {
    197             BluetoothOppShareInfo share = mShares.get(i);
    198             if (share.mStatus == BluetoothShare.STATUS_PENDING) {
    199                 return share;
    200             }
    201         }
    202         return null;
    203     }
    204 }
    205