HandoverTransfer.java revision be1939b4b6003ac7a65fcb95a3912f5e1ce8e75f
1be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectpackage com.android.nfc.handover;
2be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
3be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.Notification;
4be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.NotificationManager;
5be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.PendingIntent;
6be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.app.Notification.Builder;
7be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.bluetooth.BluetoothDevice;
8be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.content.ContentResolver;
9be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.content.Context;
10be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.content.Intent;
11be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.media.MediaScannerConnection;
12be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.net.Uri;
13be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Environment;
14be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Handler;
15be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Looper;
16be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.Message;
17be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.SystemClock;
18be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.os.UserHandle;
19be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport android.util.Log;
20be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
21be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport com.android.nfc.R;
22be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
23be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.io.File;
24be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.text.SimpleDateFormat;
25be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.util.ArrayList;
26be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.util.Date;
27be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectimport java.util.HashMap;
28be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
29be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project/**
30be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * A HandoverTransfer object represents a set of files
31be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * that were received through NFC connection handover
32be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * from the same source address.
33be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project *
34be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * For Bluetooth, files are received through OPP, and
35be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * we have no knowledge how many files will be transferred
36be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * as part of a single transaction.
37be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * Hence, a transfer has a notion of being "alive": if
38be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * the last update to a transfer was within WAIT_FOR_NEXT_TRANSFER_MS
39be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * milliseconds, we consider a new file transfer from the
40be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * same source address as part of the same transfer.
41be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project * The corresponding URIs will be grouped in a single folder.
42be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project *
43be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project */
44be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Projectpublic class HandoverTransfer implements Handler.Callback,
45be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        MediaScannerConnection.OnScanCompletedListener {
46be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
47be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    interface Callback {
48be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        void onTransferComplete(HandoverTransfer transfer, boolean success);
49be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    };
50be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
51be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final String TAG = "HandoverTransfer";
52be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
53be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final Boolean DBG = true;
54be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
55be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // In the states below we still accept new file transfer
56be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int STATE_NEW = 0;
57be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int STATE_IN_PROGRESS = 1;
58be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int STATE_W4_NEXT_TRANSFER = 2;
59be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
60be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // In the states below no new files are accepted.
61be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int STATE_W4_MEDIA_SCANNER = 3;
62be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int STATE_FAILED = 4;
63be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int STATE_SUCCESS = 5;
64be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int STATE_CANCELLED = 6;
65be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
66be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int MSG_NEXT_TRANSFER_TIMER = 0;
67be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int MSG_TRANSFER_TIMEOUT = 1;
68be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
69be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // We need to receive an update within this time period
70be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // to still consider this transfer to be "alive" (ie
71be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // a reason to keep the handover transport enabled).
72be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int ALIVE_CHECK_MS = 20000;
73be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
74be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // The amount of time to wait for a new transfer
75be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // once the current one completes.
76be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final int WAIT_FOR_NEXT_TRANSFER_MS = 4000;
77be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
78be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    static final String BEAM_DIR = "beam";
79be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
80be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final boolean mIncoming;  // whether this is an incoming transfer
81be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final int mTransferId; // Unique ID of this transfer used for notifications
82be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final PendingIntent mCancelIntent;
83be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final Context mContext;
84be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final Handler mHandler;
85be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final NotificationManager mNotificationManager;
86be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final BluetoothDevice mRemoteDevice;
87be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    final Callback mCallback;
88be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
89be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    // Variables below are only accessed on the main thread
90be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    int mState;
91be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    boolean mCalledBack;
92be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    Long mLastUpdate; // Last time an event occurred for this transfer
93be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    float mProgress; // Progress in range [0..1]
94be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    ArrayList<Uri> mBtUris; // Received uris from Bluetooth OPP
95be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    ArrayList<String> mBtMimeTypes; // Mime-types received from Bluetooth OPP
96be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
97be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    ArrayList<String> mPaths; // Raw paths on the filesystem for Beam-stored files
98be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    HashMap<String, String> mMimeTypes; // Mime-types associated with each path
99be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    HashMap<String, Uri> mMediaUris; // URIs found by the media scanner for each path
100be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    int mUrisScanned;
101be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
102be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    public HandoverTransfer(Context context, Callback callback,
103be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            PendingHandoverTransfer pendingTransfer) {
104be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mContext = context;
105be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mCallback = callback;
106be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mRemoteDevice = pendingTransfer.remoteDevice;
107be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mIncoming = pendingTransfer.incoming;
108be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mTransferId = pendingTransfer.id;
109be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mLastUpdate = SystemClock.elapsedRealtime();
110be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mProgress = 0.0f;
111be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mState = STATE_NEW;
112be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mBtUris = new ArrayList<Uri>();
113be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mBtMimeTypes = new ArrayList<String>();
114be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mPaths = new ArrayList<String>();
115be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mMimeTypes = new HashMap<String, String>();
116be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mMediaUris = new HashMap<String, Uri>();
117be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mCancelIntent = buildCancelIntent();
118be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mUrisScanned = 0;
119be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
120be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mHandler = new Handler(Looper.getMainLooper(), this);
121be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mHandler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS);
122be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mNotificationManager = (NotificationManager) mContext.getSystemService(
123be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                Context.NOTIFICATION_SERVICE);
124be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
125be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
126be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    void whitelistOppDevice(BluetoothDevice device) {
127be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (DBG) Log.d(TAG, "Whitelisting " + device + " for BT OPP");
128be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        Intent intent = new Intent(HandoverManager.ACTION_WHITELIST_DEVICE);
129be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
130be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
131be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
132be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
133be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    public void updateFileProgress(float progress) {
134be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (!isRunning()) return; // Ignore when we're no longer running
135be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
136be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mHandler.removeMessages(MSG_NEXT_TRANSFER_TIMER);
137be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
138be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        this.mProgress = progress;
139be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
140be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // We're still receiving data from this device - keep it in
141be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // the whitelist for a while longer
142be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mIncoming) whitelistOppDevice(mRemoteDevice);
143be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
144be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        updateStateAndNotification(STATE_IN_PROGRESS);
145be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
146be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
147be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    public void finishTransfer(boolean success, Uri uri, String mimeType) {
148be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (!isRunning()) return; // Ignore when we're no longer running
149be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
150be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (success && uri != null) {
151be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (DBG) Log.d(TAG, "Transfer success, uri " + uri + " mimeType " + mimeType);
152be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            this.mProgress = 1.0f;
153be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (mimeType == null) {
154be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                mimeType = BluetoothOppHandover.getMimeTypeForUri(mContext, uri);
155be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            }
156be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (mimeType != null) {
157be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                mBtUris.add(uri);
158be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                mBtMimeTypes.add(mimeType);
159be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            } else {
160be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                if (DBG) Log.d(TAG, "Could not get mimeType for file.");
161be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            }
162be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else {
163be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            Log.e(TAG, "Handover transfer failed");
164be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // Do wait to see if there's another file coming.
165be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
166be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mHandler.removeMessages(MSG_NEXT_TRANSFER_TIMER);
167be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mHandler.sendEmptyMessageDelayed(MSG_NEXT_TRANSFER_TIMER, WAIT_FOR_NEXT_TRANSFER_MS);
168be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        updateStateAndNotification(STATE_W4_NEXT_TRANSFER);
169be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
170be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
171be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    public boolean isRunning() {
172be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mState != STATE_NEW && mState != STATE_IN_PROGRESS && mState != STATE_W4_NEXT_TRANSFER) {
173be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            return false;
174be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else {
175be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            return true;
176be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
177be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
178be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
179be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    void cancel() {
180be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (!isRunning()) return;
181be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
182be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // Delete all files received so far
183be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        for (Uri uri : mBtUris) {
184be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            File file = new File(uri.getPath());
185be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (file.exists()) file.delete();
186be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
187be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
188be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        updateStateAndNotification(STATE_CANCELLED);
189be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
190be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
191be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    void updateNotification() {
192be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (!mIncoming) return; // No notifications for outgoing transfers
193be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
194be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        Builder notBuilder = new Notification.Builder(mContext);
195be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
196be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mState == STATE_NEW || mState == STATE_IN_PROGRESS ||
197be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                mState == STATE_W4_NEXT_TRANSFER || mState == STATE_W4_MEDIA_SCANNER) {
198be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setAutoCancel(false);
199be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download);
200be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setTicker(mContext.getString(R.string.beam_progress));
201be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setContentTitle(mContext.getString(R.string.beam_progress));
202be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.addAction(R.drawable.ic_menu_cancel_holo_dark,
203be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                    mContext.getString(R.string.cancel), mCancelIntent);
204be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setDeleteIntent(mCancelIntent);
205be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // We do have progress indication on a per-file basis, but in a multi-file
206be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // transfer we don't know the total progress. So for now, just show an
207be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // indeterminate progress bar.
208be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setProgress(100, 0, true);
209be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else if (mState == STATE_SUCCESS) {
210be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setAutoCancel(true);
211be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
212be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setTicker(mContext.getString(R.string.beam_complete));
213be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setContentTitle(mContext.getString(R.string.beam_complete));
214be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setContentText(mContext.getString(R.string.beam_touch_to_view));
215be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
216be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            Intent viewIntent = buildViewIntent();
217be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            PendingIntent contentIntent = PendingIntent.getActivity(
218be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                    mContext, 0, viewIntent, 0, null);
219be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
220be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setContentIntent(contentIntent);
221be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else if (mState == STATE_FAILED) {
222be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setAutoCancel(false);
223be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
224be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setTicker(mContext.getString(R.string.beam_failed));
225be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setContentTitle(mContext.getString(R.string.beam_failed));
226be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else if (mState == STATE_CANCELLED) {
227be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setAutoCancel(false);
228be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setSmallIcon(android.R.drawable.stat_sys_download_done);
229be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setTicker(mContext.getString(R.string.beam_canceled));
230be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            notBuilder.setContentTitle(mContext.getString(R.string.beam_canceled));
231be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else {
232be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            return;
233be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
234be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
235be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mNotificationManager.notify(null, mTransferId, notBuilder.build());
236be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
237be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
238be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    void updateStateAndNotification(int newState) {
239be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        this.mState = newState;
240be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        this.mLastUpdate = SystemClock.elapsedRealtime();
241be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
242be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mHandler.hasMessages(MSG_TRANSFER_TIMEOUT)) {
243be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // Update timeout timer
244be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            mHandler.removeMessages(MSG_TRANSFER_TIMEOUT);
245be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            mHandler.sendEmptyMessageDelayed(MSG_TRANSFER_TIMEOUT, ALIVE_CHECK_MS);
246be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
247be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
248be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        updateNotification();
249be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
250be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if ((mState == STATE_SUCCESS || mState == STATE_FAILED || mState == STATE_CANCELLED)
251be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                && !mCalledBack) {
252be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            mCalledBack = true;
253be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // Notify that we're done with this transfer
254be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            mCallback.onTransferComplete(this, mState == STATE_SUCCESS);
255be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
256be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
257be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
258be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    void processFiles() {
259be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // Check the amount of files we received in this transfer;
260be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // If more than one, create a separate directory for it.
261be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        String extRoot = Environment.getExternalStorageDirectory().getPath();
262be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        File beamPath = new File(extRoot + "/" + BEAM_DIR);
263be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
264be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (!checkMediaStorage(beamPath) || mBtUris.size() == 0) {
265be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            Log.e(TAG, "Media storage not valid or no uris received.");
266be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            updateStateAndNotification(STATE_FAILED);
267be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            return;
268be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
269be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
270be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mBtUris.size() > 1) {
271be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            beamPath = generateMultiplePath(extRoot + "/" + BEAM_DIR + "/");
272be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (!beamPath.isDirectory() && !beamPath.mkdir()) {
273be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                Log.e(TAG, "Failed to create multiple path " + beamPath.toString());
274be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                updateStateAndNotification(STATE_FAILED);
275be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                return;
276be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            }
277be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
278be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
279be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        for (int i = 0; i < mBtUris.size(); i++) {
280be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            Uri uri = mBtUris.get(i);
281be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            String mimeType = mBtMimeTypes.get(i);
282be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
283be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            File srcFile = new File(uri.getPath());
284be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
285be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            File dstFile = generateUniqueDestination(beamPath.getAbsolutePath(),
286be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                    uri.getLastPathSegment());
287be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (!srcFile.renameTo(dstFile)) {
288be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                if (DBG) Log.d(TAG, "Failed to rename from " + srcFile + " to " + dstFile);
289be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                srcFile.delete();
290be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                return;
291be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            } else {
292be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                mPaths.add(dstFile.getAbsolutePath());
293be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                mMimeTypes.put(dstFile.getAbsolutePath(), mimeType);
294be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                if (DBG) Log.d(TAG, "Did successful rename from " + srcFile + " to " + dstFile);
295be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            }
296be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
297be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
298be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // We can either add files to the media provider, or provide an ACTION_VIEW
299be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // intent to the file directly. We base this decision on the mime type
300be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // of the first file; if it's media the platform can deal with,
301be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // use the media provider, if it's something else, just launch an ACTION_VIEW
302be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // on the file.
303be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        String mimeType = mMimeTypes.get(mPaths.get(0));
304be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mimeType.startsWith("image/") || mimeType.startsWith("video/") ||
305be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                mimeType.startsWith("audio/")) {
306be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            String[] arrayPaths = new String[mPaths.size()];
307be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            MediaScannerConnection.scanFile(mContext, mPaths.toArray(arrayPaths), null, this);
308be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            updateStateAndNotification(STATE_W4_MEDIA_SCANNER);
309be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else {
310be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // We're done.
311be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            updateStateAndNotification(STATE_SUCCESS);
312be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
313be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
314be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
315be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
316be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    public int getTransferId() {
317be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        return mTransferId;
318be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
319be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
320be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    public boolean handleMessage(Message msg) {
321be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (msg.what == MSG_NEXT_TRANSFER_TIMER) {
322be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // We didn't receive a new transfer in time, finalize this one
323be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (mIncoming) {
324be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                processFiles();
325be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            } else {
326be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                updateStateAndNotification(STATE_SUCCESS);
327be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            }
328be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            return true;
329be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else if (msg.what == MSG_TRANSFER_TIMEOUT) {
330be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // No update on this transfer for a while, check
331be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // to see if it's still running, and fail it if it is.
332be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (isRunning()) {
333be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                updateStateAndNotification(STATE_FAILED);
334be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            }
335be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
336be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        return false;
337be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
338be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
339be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    public synchronized void onScanCompleted(String path, Uri uri) {
340be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (DBG) Log.d(TAG, "Scan completed, path " + path + " uri " + uri);
341be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (uri != null) {
342be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            mMediaUris.put(path, uri);
343be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
344be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        mUrisScanned++;
345be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mUrisScanned == mPaths.size()) {
346be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            // We're done
347be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            updateStateAndNotification(STATE_SUCCESS);
348be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
349be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
350be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
351be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    boolean checkMediaStorage(File path) {
352be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
353be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            if (!path.isDirectory() && !path.mkdir()) {
354be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                Log.e(TAG, "Not dir or not mkdir " + path.getAbsolutePath());
355be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                return false;
356be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            }
357be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            return true;
358be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else {
359be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            Log.e(TAG, "External storage not mounted, can't store file.");
360be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            return false;
361be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
362be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
363be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
364be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    Intent buildViewIntent() {
365be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (mPaths.size() == 0) return null;
366be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
367be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        Intent viewIntent = new Intent(Intent.ACTION_VIEW);
368be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
369be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        String filePath = mPaths.get(0);
370be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        Uri mediaUri = mMediaUris.get(filePath);
371be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        Uri uri =  mediaUri != null ? mediaUri :
372be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            Uri.parse(ContentResolver.SCHEME_FILE + "://" + filePath);
373be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        viewIntent.setDataAndTypeAndNormalize(uri, mMimeTypes.get(filePath));
374be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        viewIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
375be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        return viewIntent;
376be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
377be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
378be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    PendingIntent buildCancelIntent() {
379be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        Intent intent = new Intent(HandoverService.ACTION_CANCEL_HANDOVER_TRANSFER);
380be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        intent.putExtra(HandoverService.EXTRA_SOURCE_ADDRESS, mRemoteDevice.getAddress());
381be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
382be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
383be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        return pi;
384be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
385be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
386be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    File generateUniqueDestination(String path, String fileName) {
387be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        int dotIndex = fileName.lastIndexOf(".");
388be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        String extension = null;
389be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        String fileNameWithoutExtension = null;
390be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        if (dotIndex < 0) {
391be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            extension = "";
392be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            fileNameWithoutExtension = fileName;
393be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        } else {
394be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            extension = fileName.substring(dotIndex);
395be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            fileNameWithoutExtension = fileName.substring(0, dotIndex);
396be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
397be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        File dstFile = new File(path + File.separator + fileName);
398be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        int count = 0;
399be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        while (dstFile.exists()) {
400be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            dstFile = new File(path + File.separator + fileNameWithoutExtension + "-" +
401be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                    Integer.toString(count) + extension);
402be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            count++;
403be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
404be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        return dstFile;
405be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
406be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
407be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    File generateMultiplePath(String beamRoot) {
408be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        // Generate a unique directory with the date
409be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        String format = "yyyy-MM-dd";
410be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        SimpleDateFormat sdf = new SimpleDateFormat(format);
411be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        String newPath = beamRoot + "beam-" + sdf.format(new Date());
412be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        File newFile = new File(newPath);
413be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        int count = 0;
414be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        while (newFile.exists()) {
415be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            newPath = beamRoot + "beam-" + sdf.format(new Date()) + "-" +
416be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project                    Integer.toString(count);
417be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            newFile = new File(newPath);
418be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project            count++;
419be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        }
420be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project        return newFile;
421be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project    }
422be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project}
423be1939b4b6003ac7a65fcb95a3912f5e1ce8e75fThe Android Open Source Project
424