BluetoothOppTransferHistory.java revision 5cc617943765df27844e459362c4bc1821305216
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
33package com.android.bluetooth.opp;
34
35import com.android.bluetooth.R;
36
37import android.app.Activity;
38import android.app.AlertDialog;
39import android.content.DialogInterface;
40import android.content.Intent;
41import android.database.Cursor;
42import android.net.Uri;
43import android.os.Bundle;
44import android.util.Log;
45import android.view.ContextMenu;
46import android.view.Menu;
47import android.view.MenuInflater;
48import android.view.MenuItem;
49import android.view.View;
50import android.view.ContextMenu.ContextMenuInfo;
51import android.widget.AdapterView;
52import android.widget.ListView;
53import android.widget.AdapterView.OnItemClickListener;
54
55/**
56 * View showing the user's finished bluetooth opp transfers that the user does
57 * not confirm. Including outbound and inbound transfers, both successful and
58 * failed. *
59 */
60public class BluetoothOppTransferHistory extends Activity implements
61        View.OnCreateContextMenuListener, OnItemClickListener {
62    private static final String TAG = "BluetoothOppTransferHistory";
63
64    private static final boolean D = Constants.DEBUG;
65
66    private static final boolean V = Constants.VERBOSE;
67
68    private ListView mListView;
69
70    private Cursor mTransferCursor;
71
72    private BluetoothOppTransferAdapter mTransferAdapter;
73
74    private int mIdColumnId;
75
76    private int mContextMenuPosition;
77
78    @Override
79    public void onCreate(Bundle icicle) {
80        super.onCreate(icicle);
81        setContentView(R.layout.bluetooth_transfers_page);
82        mListView = (ListView)findViewById(R.id.list);
83        mListView.setEmptyView(findViewById(R.id.empty));
84
85        String direction;
86        int dir = getIntent().getIntExtra("direction", 0);
87        if (dir == BluetoothShare.DIRECTION_OUTBOUND) {
88            setTitle(getText(R.string.outbound_history_title));
89            direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_OUTBOUND
90                    + ")";
91        } else {
92            setTitle(getText(R.string.inbound_history_title));
93            direction = "(" + BluetoothShare.DIRECTION + " == " + BluetoothShare.DIRECTION_INBOUND
94                    + ")";
95        }
96
97        final String selection = BluetoothShare.STATUS + " >= '200' AND " + "("
98                + BluetoothShare.VISIBILITY + " IS NULL OR " + BluetoothShare.VISIBILITY + " == '"
99                + BluetoothShare.VISIBILITY_VISIBLE + "'" + ")" + " AND " + direction;
100        final String sortOrder = BluetoothShare.TIMESTAMP + " DESC";
101
102        mTransferCursor = managedQuery(BluetoothShare.CONTENT_URI, new String[] {
103                "_id", BluetoothShare.FILENAME_HINT, BluetoothShare.STATUS,
104                BluetoothShare.TOTAL_BYTES, BluetoothShare._DATA, BluetoothShare.TIMESTAMP,
105                BluetoothShare.VISIBILITY, BluetoothShare.DESTINATION, BluetoothShare.DIRECTION
106        }, selection, sortOrder);
107
108        // only attach everything to the listbox if we can access
109        // the transfer database. Otherwise, just show it empty
110        if (mTransferCursor != null) {
111            mIdColumnId = mTransferCursor.getColumnIndexOrThrow(BluetoothShare._ID);
112            // Create a list "controller" for the data
113            mTransferAdapter = new BluetoothOppTransferAdapter(this,
114                    R.layout.bluetooth_transfer_item, mTransferCursor);
115            mListView.setAdapter(mTransferAdapter);
116            mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
117            mListView.setOnCreateContextMenuListener(this);
118            mListView.setOnItemClickListener(this);
119        }
120    }
121
122    @Override
123    public boolean onCreateOptionsMenu(Menu menu) {
124        if (mTransferCursor != null) {
125            MenuInflater inflater = getMenuInflater();
126            inflater.inflate(R.menu.transferhistory, menu);
127        }
128        return true;
129    }
130
131    @Override
132    public boolean onPrepareOptionsMenu(Menu menu) {
133        boolean showClear = getClearableCount() > 0;
134        menu.findItem(R.id.transfer_menu_clear_all).setEnabled(showClear);
135        return super.onPrepareOptionsMenu(menu);
136    }
137
138    @Override
139    public boolean onOptionsItemSelected(MenuItem item) {
140        switch (item.getItemId()) {
141            case R.id.transfer_menu_clear_all:
142                promptClearList();
143                return true;
144        }
145        return false;
146    }
147
148    @Override
149    public boolean onContextItemSelected(MenuItem item) {
150        mTransferCursor.moveToPosition(mContextMenuPosition);
151        switch (item.getItemId()) {
152            case R.id.transfer_menu_open:
153                openCompleteTransfer();
154                return true;
155
156            case R.id.transfer_menu_clear:
157                int sessionId = mTransferCursor.getInt(mIdColumnId);
158                Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + sessionId);
159                BluetoothOppUtility.updateVisibilityToHidden(this, contentUri);
160                return true;
161        }
162        return false;
163    }
164
165    @Override
166    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
167        if (mTransferCursor != null) {
168            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
169            mTransferCursor.moveToPosition(info.position);
170            mContextMenuPosition = info.position;
171
172            String fileName = mTransferCursor.getString(mTransferCursor
173                    .getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT));
174            if (fileName == null) {
175                fileName = this.getString(R.string.unknown_file);
176            }
177            menu.setHeaderTitle(fileName);
178
179            MenuInflater inflater = getMenuInflater();
180            inflater.inflate(R.menu.transferhistorycontextfinished, menu);
181        }
182    }
183
184    /**
185     * Prompt the user if they would like to clear the transfer history
186     */
187    private void promptClearList() {
188        new AlertDialog.Builder(this).setTitle(R.string.transfer_clear_dlg_title).setMessage(
189                R.string.transfer_clear_dlg_msg).setPositiveButton(android.R.string.ok,
190                new DialogInterface.OnClickListener() {
191                    public void onClick(DialogInterface dialog, int whichButton) {
192                        clearAllDownloads();
193                    }
194                }).setNegativeButton(android.R.string.cancel, null).show();
195    }
196
197    /**
198     * Get the number of finished transfers, including error and success.
199     */
200    private int getClearableCount() {
201        int count = 0;
202        if (mTransferCursor.moveToFirst()) {
203            while (!mTransferCursor.isAfterLast()) {
204                int statusColumnId = mTransferCursor.getColumnIndexOrThrow(BluetoothShare.STATUS);
205                int status = mTransferCursor.getInt(statusColumnId);
206                if (BluetoothShare.isStatusCompleted(status)) {
207                    count++;
208                }
209                mTransferCursor.moveToNext();
210            }
211        }
212        return count;
213    }
214
215    /**
216     * Clear all finished transfers, error and success transfer items.
217     */
218    private void clearAllDownloads() {
219        if (mTransferCursor.moveToFirst()) {
220            while (!mTransferCursor.isAfterLast()) {
221                int sessionId = mTransferCursor.getInt(mIdColumnId);
222                Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + sessionId);
223                BluetoothOppUtility.updateVisibilityToHidden(this, contentUri);
224
225                mTransferCursor.moveToNext();
226            }
227        }
228    }
229
230    /*
231     * (non-Javadoc)
232     * @see
233     * android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget
234     * .AdapterView, android.view.View, int, long)
235     */
236    public void onItemClick(AdapterView parent, View view, int position, long id) {
237        // Open the selected item
238        mTransferCursor.moveToPosition(position);
239        openCompleteTransfer();
240    }
241
242    /**
243     * Open the selected finished transfer. mDownloadCursor must be moved to
244     * appropriate position before calling this function
245     */
246    private void openCompleteTransfer() {
247        int sessionId = mTransferCursor.getInt(mIdColumnId);
248        Uri contentUri = Uri.parse(BluetoothShare.CONTENT_URI + "/" + sessionId);
249        BluetoothOppTransferInfo transInfo = new BluetoothOppTransferInfo();
250        transInfo = BluetoothOppUtility.queryRecord(this, contentUri);
251        if (transInfo == null) {
252            Log.e(TAG, "Error: Can not get data from db");
253            return;
254        }
255        if (transInfo.mDirection == BluetoothShare.DIRECTION_INBOUND
256                && BluetoothShare.isStatusSuccess(transInfo.mStatus)) {
257            // if received file successfully, open this file
258            BluetoothOppUtility.updateVisibilityToHidden(this, contentUri);
259            BluetoothOppUtility.openReceivedFile(this, transInfo.mFileName, transInfo.mFileType,
260                    transInfo.mTimeStamp, contentUri);
261        } else {
262            Intent in = new Intent(this, BluetoothOppTransferActivity.class);
263            in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
264            in.setData(contentUri);
265            this.startActivity(in);
266        }
267    }
268}
269