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