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 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          */
     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          */
     92         public void onShareDeleted(int id);
     93 
     94         /**
     95          * Called to notify when the batch is canceled
     96          */
     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      */
    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 
    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      */
    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      */
    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 */
    181     public boolean hasShare(BluetoothOppShareInfo info) {
    182         return mShares.contains(info);
    183     }
    184 
    185     /** if this batch is empty */
    186     public boolean isEmpty() {
    187         return (mShares.size() == 0);
    188     }
    189 
    190     /**
    191      * Get the running status of the batch
    192      * @return
    193      */
    194 
    195     /** register a listener for the batch change */
    196     public void registerListern(BluetoothOppBatchListener listener) {
    197         mListener = listener;
    198     }
    199 
    200     /**
    201      * Get the first pending ShareInfo of the batch
    202      * @return BluetoothOppShareInfo, for the first pending share, or null if
    203      *         none exists
    204      */
    205     public BluetoothOppShareInfo getPendingShare() {
    206         for (int i = 0; i < mShares.size(); i++) {
    207             BluetoothOppShareInfo share = mShares.get(i);
    208             if (share.mStatus == BluetoothShare.STATUS_PENDING) {
    209                 return share;
    210             }
    211         }
    212         return null;
    213     }
    214 }
    215