BluetoothOppTransferActivity.java revision 239bc526513429995c61c4148c105725c395b1a9
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.content.DialogInterface; 38import android.content.Intent; 39import android.net.Uri; 40import android.os.Bundle; 41import android.os.Handler; 42import android.util.Log; 43import android.view.View; 44import android.widget.TextView; 45import android.widget.Toast; 46import android.database.ContentObserver; 47import android.widget.ProgressBar; 48 49import com.android.internal.app.AlertActivity; 50import com.android.internal.app.AlertController; 51import android.app.NotificationManager; 52import android.text.format.Formatter; 53 54/** 55 * Handle all transfer related dialogs: -Ongoing transfer -Receiving one file 56 * dialog -Sending one file dialog -sending multiple files dialog -Complete 57 * transfer -receive -receive success, will trigger corresponding handler 58 * -receive fail dialog -send -send success dialog -send fail dialog -Other 59 * dialogs - - DIALOG_RECEIVE_ONGOING will transition to 60 * DIALOG_RECEIVE_COMPLETE_SUCCESS or DIALOG_RECEIVE_COMPLETE_FAIL 61 * DIALOG_SEND_ONGOING will transition to DIALOG_SEND_COMPLETE_SUCCESS or 62 * DIALOG_SEND_COMPLETE_FAIL 63 */ 64public class BluetoothOppTransferActivity extends AlertActivity implements 65 DialogInterface.OnClickListener { 66 private static final String TAG = "BluetoothOppTransferActivity"; 67 68 private Uri mUri; 69 70 // ongoing transfer-0 complete transfer-1 71 boolean mIsComplete; 72 73 private BluetoothOppTransferInfo mTransInfo; 74 75 private ProgressBar mProgressTransfer; 76 77 private TextView mPercentView; 78 79 private AlertController.AlertParams mPara; 80 81 private View mView = null; 82 83 private TextView mLine1View, mLine2View, mLine3View, mLine5View; 84 85 // Dialogs definition: 86 // Receive progress dialog 87 public static final int DIALOG_RECEIVE_ONGOING = 0; 88 89 // Receive complete and success dialog 90 public static final int DIALOG_RECEIVE_COMPLETE_SUCCESS = 1; 91 92 // Receive complete and fail dialog: will display some fail reason 93 public static final int DIALOG_RECEIVE_COMPLETE_FAIL = 2; 94 95 // Send progress dialog 96 public static final int DIALOG_SEND_ONGOING = 3; 97 98 // Send complete and success dialog 99 public static final int DIALOG_SEND_COMPLETE_SUCCESS = 4; 100 101 // Send complete and fail dialog: will let user retry 102 public static final int DIALOG_SEND_COMPLETE_FAIL = 5; 103 104 private int mWhichDialog; 105 106 /** Observer to get notified when the content observer's data changes */ 107 private BluetoothTransferContentObserver mObserver; 108 109 private class BluetoothTransferContentObserver extends ContentObserver { 110 public BluetoothTransferContentObserver() { 111 super(new Handler()); 112 } 113 114 @Override 115 public void onChange(boolean selfChange) { 116 if (Constants.LOGVV) { 117 Log.v(TAG, "received db changes."); 118 } 119 updateProgressbar(); 120 } 121 } 122 123 @Override 124 protected void onCreate(Bundle savedInstanceState) { 125 super.onCreate(savedInstanceState); 126 Intent intent = getIntent(); 127 mUri = intent.getData(); 128 129 mTransInfo = new BluetoothOppTransferInfo(); 130 mTransInfo = BluetoothOppUtility.queryRecord(this, mUri); 131 if (mTransInfo == null) { 132 if (Constants.LOGVV) { 133 Log.e(TAG, "Error: Can not get data from db"); 134 } 135 finish(); 136 return; 137 } 138 139 mIsComplete = BluetoothShare.isStatusCompleted(mTransInfo.mStatus); 140 141 displayWhichDialog(); 142 143 // update progress bar for ongoing transfer 144 if (!mIsComplete) { 145 mObserver = new BluetoothTransferContentObserver(); 146 getContentResolver().registerContentObserver(BluetoothShare.CONTENT_URI, true, 147 mObserver); 148 } 149 150 if (mWhichDialog != DIALOG_SEND_ONGOING && mWhichDialog != DIALOG_RECEIVE_ONGOING) { 151 // set this record to INVISIBLE 152 BluetoothOppUtility.updateVisibilityToHidden(this, mUri); 153 } 154 155 // Set up the "dialog" 156 setUpDialog(); 157 } 158 159 @Override 160 protected void onDestroy() { 161 if (Constants.LOGV) { 162 Log.v(TAG, "onDestroy()"); 163 } 164 165 if (mObserver != null) { 166 getContentResolver().unregisterContentObserver(mObserver); 167 } 168 super.onDestroy(); 169 } 170 171 private void displayWhichDialog() { 172 int direction = mTransInfo.mDirection; 173 boolean isSuccess = BluetoothShare.isStatusSuccess(mTransInfo.mStatus); 174 boolean isComplete = BluetoothShare.isStatusCompleted(mTransInfo.mStatus); 175 176 if (direction == BluetoothShare.DIRECTION_INBOUND) { 177 if (isComplete == true) { 178 if (isSuccess == true) { 179 // should not go here 180 mWhichDialog = DIALOG_RECEIVE_COMPLETE_SUCCESS; 181 } else if (isSuccess == false) { 182 mWhichDialog = DIALOG_RECEIVE_COMPLETE_FAIL; 183 } 184 } else if (isComplete == false) { 185 mWhichDialog = DIALOG_RECEIVE_ONGOING; 186 } 187 } else if (direction == BluetoothShare.DIRECTION_OUTBOUND) { 188 if (isComplete == true) { 189 if (isSuccess == true) { 190 mWhichDialog = DIALOG_SEND_COMPLETE_SUCCESS; 191 192 } else if (isSuccess == false) { 193 mWhichDialog = DIALOG_SEND_COMPLETE_FAIL; 194 } 195 } else if (isComplete == false) { 196 mWhichDialog = DIALOG_SEND_ONGOING; 197 } 198 } 199 200 if (Constants.LOGVV) { 201 Log.v(TAG, " WhichDialog/dir/isComplete/failOrSuccess" + mWhichDialog + direction 202 + isComplete + isSuccess); 203 } 204 } 205 206 private void setUpDialog() { 207 // final AlertController.AlertParams p = mAlertParams; 208 mPara = mAlertParams; 209 mPara.mIconId = android.R.drawable.ic_dialog_info; 210 mPara.mTitle = getString(R.string.download_title); 211 212 if ((mWhichDialog == DIALOG_RECEIVE_ONGOING) || (mWhichDialog == DIALOG_SEND_ONGOING)) { 213 mPara.mPositiveButtonText = getString(R.string.download_ok); 214 mPara.mPositiveButtonListener = this; 215 mPara.mNegativeButtonText = getString(R.string.download_cancel); 216 mPara.mNegativeButtonListener = this; 217 } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) { 218 mPara.mPositiveButtonText = getString(R.string.download_succ_ok); 219 mPara.mPositiveButtonListener = this; 220 } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) { 221 mPara.mIconId = android.R.drawable.ic_dialog_alert; 222 mPara.mPositiveButtonText = getString(R.string.download_fail_ok); 223 mPara.mPositiveButtonListener = this; 224 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) { 225 mPara.mPositiveButtonText = getString(R.string.upload_succ_ok); 226 mPara.mPositiveButtonListener = this; 227 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) { 228 mPara.mIconId = android.R.drawable.ic_dialog_alert; 229 mPara.mPositiveButtonText = getString(R.string.upload_fail_ok); 230 mPara.mPositiveButtonListener = this; 231 mPara.mNegativeButtonText = getString(R.string.upload_fail_cancel); 232 mPara.mNegativeButtonListener = this; 233 } 234 mPara.mView = createView(); 235 setupAlert(); 236 } 237 238 private View createView() { 239 240 mView = getLayoutInflater().inflate(R.layout.file_transfer, null); 241 242 mProgressTransfer = (ProgressBar)mView.findViewById(R.id.progress_transfer); 243 mPercentView = (TextView)mView.findViewById(R.id.progress_percent); 244 245 customizeViewContent(); 246 247 updateProgressbar(); 248 249 return mView; 250 } 251 252 /** 253 * customize the content of view 254 */ 255 private void customizeViewContent() { 256 String tmp; 257 258 if (mWhichDialog == DIALOG_RECEIVE_ONGOING 259 || mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) { 260 mLine1View = (TextView)mView.findViewById(R.id.line1_view); 261 tmp = getString(R.string.download_line1, mTransInfo.mDeviceName); 262 mLine1View.setText(tmp); 263 mLine2View = (TextView)mView.findViewById(R.id.line2_view); 264 tmp = getString(R.string.download_line2, mTransInfo.mFileName); 265 mLine2View.setText(tmp); 266 mLine3View = (TextView)mView.findViewById(R.id.line3_view); 267 tmp = getString(R.string.download_line3, Formatter.formatFileSize(this, 268 mTransInfo.mTotalBytes)); 269 mLine3View.setText(tmp); 270 mLine5View = (TextView)mView.findViewById(R.id.line5_view); 271 if (mWhichDialog == DIALOG_RECEIVE_ONGOING) { 272 tmp = getString(R.string.download_line5); 273 } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) { 274 tmp = getString(R.string.download_succ_line5); 275 } 276 mLine5View.setText(tmp); 277 } else if (mWhichDialog == DIALOG_SEND_ONGOING 278 || mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) { 279 mLine1View = (TextView)mView.findViewById(R.id.line1_view); 280 tmp = getString(R.string.upload_line1, mTransInfo.mDeviceName); 281 mLine1View.setText(tmp); 282 mLine2View = (TextView)mView.findViewById(R.id.line2_view); 283 tmp = getString(R.string.download_line2, mTransInfo.mFileName); 284 mLine2View.setText(tmp); 285 mLine3View = (TextView)mView.findViewById(R.id.line3_view); 286 tmp = getString(R.string.upload_line3, mTransInfo.mFileType, Formatter.formatFileSize( 287 this, mTransInfo.mTotalBytes)); 288 mLine3View.setText(tmp); 289 mLine5View = (TextView)mView.findViewById(R.id.line5_view); 290 if (mWhichDialog == DIALOG_SEND_ONGOING) { 291 tmp = getString(R.string.upload_line5); 292 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) { 293 tmp = getString(R.string.upload_succ_line5); 294 } 295 mLine5View.setText(tmp); 296 } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) { 297 if (mTransInfo.mStatus == BluetoothShare.STATUS_ERROR_SDCARD_FULL) { 298 mLine1View = (TextView)mView.findViewById(R.id.line1_view); 299 tmp = getString(R.string.bt_sm_2_1, mTransInfo.mDeviceName); 300 mLine1View.setText(tmp); 301 mLine2View = (TextView)mView.findViewById(R.id.line2_view); 302 tmp = getString(R.string.download_fail_line2, mTransInfo.mFileName); 303 mLine2View.setText(tmp); 304 mLine3View = (TextView)mView.findViewById(R.id.line3_view); 305 tmp = getString(R.string.bt_sm_2_2, Formatter.formatFileSize(this, 306 mTransInfo.mTotalBytes)); 307 mLine3View.setText(tmp); 308 } else { 309 mLine1View = (TextView)mView.findViewById(R.id.line1_view); 310 tmp = getString(R.string.download_fail_line1); 311 mLine1View.setText(tmp); 312 mLine2View = (TextView)mView.findViewById(R.id.line2_view); 313 tmp = getString(R.string.download_fail_line2, mTransInfo.mFileName); 314 mLine2View.setText(tmp); 315 mLine3View = (TextView)mView.findViewById(R.id.line3_view); 316 tmp = getString(R.string.download_fail_line3, BluetoothOppUtility 317 .getStatusDescription(this, mTransInfo.mStatus)); 318 mLine3View.setText(tmp); 319 } 320 mLine5View = (TextView)mView.findViewById(R.id.line5_view); 321 mLine5View.setVisibility(View.INVISIBLE); 322 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) { 323 mLine1View = (TextView)mView.findViewById(R.id.line1_view); 324 tmp = getString(R.string.upload_fail_line1, mTransInfo.mDeviceName); 325 mLine1View.setText(tmp); 326 mLine2View = (TextView)mView.findViewById(R.id.line2_view); 327 tmp = getString(R.string.upload_fail_line1_2, mTransInfo.mFileName); 328 mLine2View.setText(tmp); 329 mLine3View = (TextView)mView.findViewById(R.id.line3_view); 330 tmp = getString(R.string.download_fail_line3, BluetoothOppUtility.getStatusDescription( 331 this, mTransInfo.mStatus)); 332 mLine3View.setText(tmp); 333 mLine5View = (TextView)mView.findViewById(R.id.line5_view); 334 mLine5View.setVisibility(View.INVISIBLE); 335 } 336 337 if (BluetoothShare.isStatusError(mTransInfo.mStatus)) { 338 mProgressTransfer.setVisibility(View.GONE); 339 mPercentView.setVisibility(View.GONE); 340 } 341 } 342 343 public void onClick(DialogInterface dialog, int which) { 344 switch (which) { 345 case DialogInterface.BUTTON_POSITIVE: 346 if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) { 347 // "Open" - open receive file 348 BluetoothOppUtility.openReceivedFile(this, mTransInfo.mFileName, 349 mTransInfo.mFileType, mTransInfo.mTimeStamp); 350 351 // make current transfer "hidden" 352 BluetoothOppUtility.updateVisibilityToHidden(this, mUri); 353 354 // clear correspondent notification item 355 ((NotificationManager)getSystemService(NOTIFICATION_SERVICE)) 356 .cancel(mTransInfo.mID); 357 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) { 358 // "try again" 359 360 // make current transfer "hidden" 361 BluetoothOppUtility.updateVisibilityToHidden(this, mUri); 362 363 // clear correspondent notification item 364 ((NotificationManager)getSystemService(NOTIFICATION_SERVICE)) 365 .cancel(mTransInfo.mID); 366 367 // retry the failed transfer 368 BluetoothOppUtility.retryTransfer(this, mTransInfo); 369 370 // Display toast message 371 Toast.makeText( 372 this, 373 this.getString(R.string.bt_toast_4, BluetoothOppManager.getInstance( 374 this).getDeviceName(mTransInfo.mDestAddr)), Toast.LENGTH_SHORT) 375 .show(); 376 377 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) { 378 BluetoothOppUtility.updateVisibilityToHidden(this, mUri); 379 ((NotificationManager)getSystemService(NOTIFICATION_SERVICE)) 380 .cancel(mTransInfo.mID); 381 } 382 break; 383 384 case DialogInterface.BUTTON_NEGATIVE: 385 if (mWhichDialog == DIALOG_RECEIVE_ONGOING || mWhichDialog == DIALOG_SEND_ONGOING) { 386 // "Stop" button 387 this.getContentResolver().delete(mUri, null, null); 388 389 String msg = ""; 390 if (mWhichDialog == DIALOG_RECEIVE_ONGOING) { 391 msg = getString(R.string.bt_toast_3, mTransInfo.mDeviceName); 392 } else if (mWhichDialog == DIALOG_SEND_ONGOING) { 393 msg = getString(R.string.bt_toast_6, mTransInfo.mDeviceName); 394 } 395 Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); 396 397 ((NotificationManager)getSystemService(NOTIFICATION_SERVICE)) 398 .cancel(mTransInfo.mID); 399 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) { 400 401 BluetoothOppUtility.updateVisibilityToHidden(this, mUri); 402 } 403 break; 404 } 405 finish(); 406 } 407 408 /** 409 * Update progress bar per data got from content provider 410 */ 411 private void updateProgressbar() { 412 mTransInfo = BluetoothOppUtility.queryRecord(this, mUri); 413 if (mTransInfo == null) { 414 if (Constants.LOGVV) { 415 Log.e(TAG, "Error: Can not get data from db"); 416 } 417 return; 418 } 419 420 if (mTransInfo.mTotalBytes == 0) { 421 // if Max and progress both equal 0, the progress display 100%. 422 // Below is to fix it. 423 mProgressTransfer.setMax(100); 424 } else { 425 mProgressTransfer.setMax(mTransInfo.mTotalBytes); 426 } 427 428 mProgressTransfer.setProgress(mTransInfo.mCurrentBytes); 429 430 mPercentView.setText(BluetoothOppUtility.formatProgressText(mTransInfo.mTotalBytes, 431 mTransInfo.mCurrentBytes)); 432 433 // Handle the case when DIALOG_RECEIVE_ONGOING evolve to 434 // DIALOG_RECEIVE_COMPLETE_SUCCESS/DIALOG_RECEIVE_COMPLETE_FAIL 435 // Handle the case when DIALOG_SEND_ONGOING evolve to 436 // DIALOG_SEND_COMPLETE_SUCCESS/DIALOG_SEND_COMPLETE_FAIL 437 if (!mIsComplete && BluetoothShare.isStatusCompleted(mTransInfo.mStatus)) { 438 439 displayWhichDialog(); 440 441 updateButton(); 442 443 customizeViewContent(); 444 } 445 } 446 447 /** 448 * Update button when one transfer goto complete from ongoing 449 */ 450 private void updateButton() { 451 if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_SUCCESS) { 452 mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE); 453 mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setText( 454 getString(R.string.download_succ_ok)); 455 } else if (mWhichDialog == DIALOG_RECEIVE_COMPLETE_FAIL) { 456 mAlert.setIcon(android.R.drawable.ic_dialog_alert); 457 mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE); 458 mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setText( 459 getString(R.string.download_fail_ok)); 460 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_SUCCESS) { 461 mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE); 462 mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setText( 463 getString(R.string.upload_succ_ok)); 464 } else if (mWhichDialog == DIALOG_SEND_COMPLETE_FAIL) { 465 mAlert.setIcon(android.R.drawable.ic_dialog_alert); 466 mAlert.getButton(DialogInterface.BUTTON_POSITIVE).setText( 467 getString(R.string.upload_fail_ok)); 468 mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setText( 469 getString(R.string.upload_fail_cancel)); 470 } 471 } 472} 473