BluetoothOppManager.java revision 41ef8d494511c040451f2f887cb31c3100746b61
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.bluetooth.BluetoothAdapter; 38import android.bluetooth.BluetoothDevice; 39import android.content.ContentResolver; 40import android.content.ContentValues; 41import android.content.Context; 42import android.content.SharedPreferences; 43import android.net.Uri; 44import android.util.Log; 45 46import java.util.ArrayList; 47 48/** 49 * This class provides a simplified interface on top of other Bluetooth service 50 * layer components; Also it handles some Opp application level variables. It's 51 * a singleton got from BluetoothOppManager.getInstance(context); 52 */ 53public class BluetoothOppManager { 54 private static final String TAG = "BluetoothOppManager"; 55 56 private static BluetoothOppManager INSTANCE; 57 58 /** Used when obtaining a reference to the singleton instance. */ 59 private static Object INSTANCE_LOCK = new Object(); 60 61 private boolean mInitialized; 62 63 private Context mContext; 64 65 private BluetoothAdapter mAdapter; 66 67 private String mMimeTypeOfSendigFile; 68 69 private String mUriOfSendingFile; 70 71 private String mMimeTypeOfSendigFiles; 72 73 private ArrayList<String> mUrisOfSendingFiles; 74 75 private boolean mCanStartTransfer = false; 76 77 private static final String OPP_PREFERENCE_FILE = "OPPMGR"; 78 79 private static final String SENDING_FLAG = "SENDINGFLAG"; 80 81 private static final String MIME_TYPE = "MIMETYPE"; 82 83 private static final String FILE_URI = "FILE_URI"; 84 85 private static final String MIME_TYPE_MULTIPLE = "MIMETYPE_MULTIPLE"; 86 87 private static final String FILE_URIS = "FILE_URIS"; 88 89 private static final String MULTIPLE_FLAG = "MULTIPLE_FLAG"; 90 91 private static final String ARRAYLIST_ITEM_SEPERATOR = "!"; 92 93 // used to judge if need continue sending process after received a 94 // ENABLED_ACTION 95 public boolean mSendingFlag; 96 97 public boolean mMultipleFlag; 98 99 public int mfileNumInBatch; 100 101 /** 102 * Get singleton instance. 103 */ 104 public static BluetoothOppManager getInstance(Context context) { 105 synchronized (INSTANCE_LOCK) { 106 if (INSTANCE == null) { 107 INSTANCE = new BluetoothOppManager(); 108 } 109 INSTANCE.init(context); 110 111 return INSTANCE; 112 } 113 } 114 115 /** 116 * init 117 */ 118 private boolean init(Context context) { 119 if (mInitialized) 120 return true; 121 mInitialized = true; 122 123 // This will be around as long as this process is 124 mContext = context.getApplicationContext(); 125 126 mAdapter = (BluetoothAdapter) context.getSystemService(Context.BLUETOOTH_SERVICE); 127 if (mAdapter == null) { 128 if (Constants.LOGVV) { 129 Log.v(TAG, "BLUETOOTH_SERVICE is not started! "); 130 } 131 } 132 133 // Restore data from preference 134 restoreApplicationData(); 135 136 return true; 137 } 138 139 /** 140 * Restore data from preference 141 */ 142 private void restoreApplicationData() { 143 SharedPreferences settings = mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0); 144 145 mSendingFlag = settings.getBoolean(SENDING_FLAG, false); 146 mMimeTypeOfSendigFile = settings.getString(MIME_TYPE, null); 147 mUriOfSendingFile = settings.getString(FILE_URI, null); 148 mMimeTypeOfSendigFiles = settings.getString(MIME_TYPE_MULTIPLE, null); 149 mMultipleFlag = settings.getBoolean(MULTIPLE_FLAG, false); 150 151 if (Constants.LOGVV) { 152 Log.v(TAG, "restoreApplicationData! " + mSendingFlag + mMultipleFlag 153 + mMimeTypeOfSendigFile + mUriOfSendingFile); 154 } 155 156 String strUris = settings.getString(FILE_URIS, null); 157 // TODO(Moto): restore mUrisOfSendingFiles from strUris. 158 } 159 160 /** 161 * Save application data to preference, need restore these data later 162 */ 163 private void onDestroy() { 164 SharedPreferences.Editor editor = mContext.getSharedPreferences(OPP_PREFERENCE_FILE, 0) 165 .edit(); 166 editor.putBoolean(SENDING_FLAG, mSendingFlag).commit(); 167 editor.putString(MIME_TYPE, mMimeTypeOfSendigFile).commit(); 168 editor.putString(FILE_URI, mUriOfSendingFile).commit(); 169 editor.putString(MIME_TYPE_MULTIPLE, mMimeTypeOfSendigFiles).commit(); 170 editor.putBoolean(MULTIPLE_FLAG, mMultipleFlag).commit(); 171 String strUris; 172 StringBuilder sb = new StringBuilder(); 173 for (int i = 0, count = mUrisOfSendingFiles.size(); i < count; i++) { 174 String uriContent = mUrisOfSendingFiles.get(i); 175 sb.append(uriContent); 176 sb.append(ARRAYLIST_ITEM_SEPERATOR); 177 } 178 strUris = sb.toString(); 179 editor.putString(FILE_URIS, strUris).commit(); 180 if (Constants.LOGVV) { 181 Log.v(TAG, "finalize is called and application data saved by SharedPreference! "); 182 } 183 } 184 185 /** 186 * Save data to preference when this class is destroyed by system due to 187 * memory lack 188 */ 189 protected void finalize() throws Throwable { 190 try { 191 onDestroy(); 192 } finally { 193 super.finalize(); 194 } 195 } 196 197 public void saveSendingFileInfo(String mimeType, String uri) { 198 mMultipleFlag = false; 199 mMimeTypeOfSendigFile = mimeType; 200 mUriOfSendingFile = uri; 201 mCanStartTransfer = true; 202 } 203 204 public void saveSendingFileInfo(String mimeType, ArrayList<String> uris) { 205 mMultipleFlag = true; 206 mMimeTypeOfSendigFiles = mimeType; 207 mUrisOfSendingFiles = uris; 208 mCanStartTransfer = true; 209 } 210 211 /** 212 * Get the current status of Bluetooth hardware. 213 * @return true if Bluetooth enabled, false otherwise. 214 */ 215 public boolean isEnabled() { 216 if (mAdapter != null) { 217 return mAdapter.isEnabled(); 218 } else { 219 if (Constants.LOGVV) { 220 Log.v(TAG, "BLUETOOTH_SERVICE is not available! "); 221 } 222 return false; 223 } 224 } 225 226 /** 227 * Enable Bluetooth hardware. 228 */ 229 public void enableBluetooth() { 230 if (mAdapter != null) { 231 mAdapter.enable(); 232 } 233 } 234 235 /** 236 * Disable Bluetooth hardware. 237 */ 238 public void disableBluetooth() { 239 if (mAdapter != null) { 240 mAdapter.disable(); 241 } 242 } 243 244 /** 245 * Get device name per bluetooth address. 246 */ 247 public String getDeviceName(BluetoothDevice device) { 248 String deviceName; 249 250 deviceName = BluetoothOppPreference.getInstance(mContext).getName(device); 251 252 if (deviceName == null && mAdapter != null) { 253 deviceName = device.getName(); 254 } 255 256 if (deviceName == null) { 257 deviceName = mContext.getString(R.string.unknown_device); 258 } 259 260 return deviceName; 261 } 262 263 /** 264 * insert sending sessions to db, only used by Opp application. 265 */ 266 public void startTransfer(BluetoothDevice device) { 267 if (device == null) { 268 Log.e(TAG, "Target bt device is null!"); 269 return; 270 } 271 272 if (!mCanStartTransfer) { 273 if (Constants.LOGVV) { 274 Log.v(TAG, "No transfer info restored: fileType&fileName"); 275 } 276 return; 277 } 278 279 if (mMultipleFlag == true) { 280 int count = mUrisOfSendingFiles.size(); 281 mfileNumInBatch = count; 282 283 Long ts = System.currentTimeMillis(); 284 for (int i = 0; i < count; i++) { 285 String uriContent = mUrisOfSendingFiles.get(i); 286 int index = uriContent.indexOf(";"); 287 if (index == -1) { 288 if (Constants.LOGVV) { 289 Log.v(TAG, "Not found ';' in uriContent!"); 290 } 291 return; 292 } 293 String fileType = uriContent.substring(0, index); 294 String fileUri = uriContent.substring(index + 1); 295 296 ContentResolver contentResolver = mContext.getContentResolver(); 297 Uri u = Uri.parse(fileUri); 298 String contentType = contentResolver.getType(u); 299 if (contentType == null) { 300 contentType = fileType; 301 } 302 303 if (Constants.LOGVV) { 304 Log.v(TAG, "Got mimetype: " + contentType + " Got uri: " + fileUri); 305 } 306 307 ContentValues values = new ContentValues(); 308 values.put(BluetoothShare.URI, fileUri); 309 values.put(BluetoothShare.MIMETYPE, contentType); 310 values.put(BluetoothShare.DESTINATION, device.getAddress()); 311 values.put(BluetoothShare.TIMESTAMP, ts); 312 313 final Uri contentUri = mContext.getContentResolver().insert( 314 BluetoothShare.CONTENT_URI, values); 315 if (Constants.LOGVV) { 316 Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " 317 + getDeviceName(device)); 318 } 319 } 320 } else { 321 ContentValues values = new ContentValues(); 322 values.put(BluetoothShare.URI, mUriOfSendingFile); 323 values.put(BluetoothShare.MIMETYPE, mMimeTypeOfSendigFile); 324 values.put(BluetoothShare.DESTINATION, device.getAddress()); 325 326 final Uri contentUri = mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, 327 values); 328 if (Constants.LOGVV) { 329 Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " 330 + getDeviceName(device)); 331 } 332 } 333 334 // reset vars 335 mMimeTypeOfSendigFile = null; 336 mUriOfSendingFile = null; 337 mUrisOfSendingFiles = null; 338 mMultipleFlag = false; 339 mCanStartTransfer = false; 340 } 341} 342