Loading android/app/AndroidManifest.xml +22 −1 Original line number Original line Diff line number Diff line Loading @@ -10,6 +10,19 @@ android:label="@string/permlab_bluetoothShareManager" android:label="@string/permlab_bluetoothShareManager" android:description="@string/permdesc_bluetoothShareManager" android:description="@string/permdesc_bluetoothShareManager" android:protectionLevel="signature" /> android:protectionLevel="signature" /> <!-- Allows temporarily whitelisting Bluetooth addresses for sharing --> <permission android:name="com.android.permission.WHITELIST_BLUETOOTH_DEVICE" android:label="@string/permlab_bluetoothWhitelist" android:description="@string/permdesc_bluetoothWhitelist" android:protectionLevel="signature" /> <!-- Allows receiving handover status broadcasts from Bluetooth -->, <permission android:name="com.android.permission.HANDOVER_STATUS" android:label="@string/permlab_handoverStatus" android:description="@string/permdesc_handoverStatus" android:protectionLevel="signature" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" /> <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" /> Loading @@ -21,6 +34,7 @@ <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="com.android.permission.HANDOVER_STATUS" /> <application <application android:icon="@drawable/bt_share" android:icon="@drawable/bt_share" android:label="@string/app_name"> android:label="@string/app_name"> Loading @@ -43,7 +57,14 @@ <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" /> <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" /> <!--action android:name="android.intent.action.BOOT_COMPLETED" /--> <!--action android:name="android.intent.action.BOOT_COMPLETED" /--> <action android:name="android.btopp.intent.action.OPEN_RECEIVED_FILES" /> <action android:name="android.btopp.intent.action.OPEN_RECEIVED_FILES" /> <action android:name="todo-whitelist" /> </intent-filter> </receiver> <receiver android:process="@string/process" android:name=".opp.BluetoothOppHandoverReceiver" android:permission="com.android.permission.WHITELIST_BLUETOOTH_DEVICE"> <intent-filter> <action android:name="android.btopp.intent.action.WHITELIST_DEVICE" /> </intent-filter> </intent-filter> </receiver> </receiver> <activity android:name=".opp.BluetoothOppLauncherActivity" <activity android:name=".opp.BluetoothOppLauncherActivity" Loading android/app/res/values/strings.xml +11 −0 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,17 @@ <string name="permdesc_bluetoothShareManager">Allows the app to access the <string name="permdesc_bluetoothShareManager">Allows the app to access the BluetoothShare manager and use it to transfer files. </string> BluetoothShare manager and use it to transfer files. </string> <string name="permlab_bluetoothWhitelist">Whitelist bluetooth device access.</string> <string name="permdesc_bluetoothWhitelist">Allows the app to temporarily whitelist a Bluetooth device, allowing that device to send files to this device without user confirmation.</string> <!-- Strings used for a (system only) permission --> <string name="permlab_handoverStatus">Receive BT handover transfer broadcasts.</string> <string name="permdesc_handoverStatus">Allows receiving handover transfer status information from Bluetooth.</string> <!-- string showed on "Share picutre via" dialog --> <!-- string showed on "Share picutre via" dialog --> <string name="bt_share_picker_label">Bluetooth</string> <string name="bt_share_picker_label">Bluetooth</string> Loading android/app/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java 0 → 100644 +44 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.opp; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class BluetoothOppHandoverReceiver extends BroadcastReceiver { public static final String TAG ="BluetoothOppHandoverReceiver"; private static final boolean D = Constants.DEBUG; private static final boolean V = Constants.VERBOSE; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Constants.ACTION_WHITELIST_DEVICE)) { BluetoothDevice device = (BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (D) Log.d(TAG, "Adding " + device + " to whitelist"); if (device == null) return; BluetoothOppManager.getInstance(context).addToWhitelist(device.getAddress()); } else { if (D) Log.d(TAG, "Unknown action: " + action); } } } android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,7 @@ public class BluetoothOppLauncherActivity extends Activity { Intent intent = getIntent(); Intent intent = getIntent(); String action = intent.getAction(); String action = intent.getAction(); BluetoothDevice device = null; BluetoothDevice device = null; boolean isHandover = true; if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) { if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) { /* /* Loading @@ -75,14 +76,15 @@ public class BluetoothOppLauncherActivity extends Activity { * probably Pictures, videos, or vCards. The Intent should contain * probably Pictures, videos, or vCards. The Intent should contain * an EXTRA_STREAM with the data to attach. * an EXTRA_STREAM with the data to attach. */ */ if (intent.getBooleanExtra(Constants.EXTRA_CONNECTION_HANDOVER, false)) { device = (BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); isHandover = true; } if (action.equals(Intent.ACTION_SEND)) { if (action.equals(Intent.ACTION_SEND)) { // TODO: handle type == null case // TODO: handle type == null case String type = intent.getType(); String type = intent.getType(); Uri stream = (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM); Uri stream = (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM); CharSequence extra_text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT); CharSequence extra_text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT); //TODO: consider only checking EXTRA_DEVICE if it came from NFC device = (BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // If we get ACTION_SEND intent with EXTRA_STREAM, we'll use the // If we get ACTION_SEND intent with EXTRA_STREAM, we'll use the // uri data; // uri data; // If we get ACTION_SEND intent without EXTRA_STREAM, but with // If we get ACTION_SEND intent without EXTRA_STREAM, but with Loading @@ -94,7 +96,7 @@ public class BluetoothOppLauncherActivity extends Activity { // Save type/stream, will be used when adding transfer // Save type/stream, will be used when adding transfer // session to DB. // session to DB. BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, stream.toString()); stream.toString(), isHandover); } else if (extra_text != null && type != null) { } else if (extra_text != null && type != null) { if (V) Log.v(TAG, "Get ACTION_SEND intent with Extra_text = " if (V) Log.v(TAG, "Get ACTION_SEND intent with Extra_text = " + extra_text.toString() + "; mimetype = " + type); + extra_text.toString() + "; mimetype = " + type); Loading @@ -102,7 +104,7 @@ public class BluetoothOppLauncherActivity extends Activity { if (fileUri != null) { if (fileUri != null) { BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, fileUri.toString()); fileUri.toString(), isHandover); } } } else { } else { Log.e(TAG, "type is null; or sending file URI is null"); Log.e(TAG, "type is null; or sending file URI is null"); Loading @@ -116,7 +118,8 @@ public class BluetoothOppLauncherActivity extends Activity { if (mimeType != null && uris != null) { if (mimeType != null && uris != null) { if (V) Log.v(TAG, "Get ACTION_SHARE_MULTIPLE intent: uris " + uris + "\n Type= " if (V) Log.v(TAG, "Get ACTION_SHARE_MULTIPLE intent: uris " + uris + "\n Type= " + mimeType); + mimeType); BluetoothOppManager.getInstance(this).saveSendingFileInfo(mimeType, uris); BluetoothOppManager.getInstance(this).saveSendingFileInfo(mimeType, uris, isHandover); } else { } else { Log.e(TAG, "type is null; or sending files URIs are null"); Log.e(TAG, "type is null; or sending files URIs are null"); finish(); finish(); Loading android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java +51 −10 Original line number Original line Diff line number Diff line Loading @@ -43,10 +43,13 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.net.Uri; import android.net.Uri; import android.os.Process; import android.os.Process; import android.os.SystemClock; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.util.Pair; import java.util.ArrayList; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.List; /** /** Loading Loading @@ -77,6 +80,8 @@ public class BluetoothOppManager { private ArrayList<Uri> mUrisOfSendingFiles; private ArrayList<Uri> mUrisOfSendingFiles; private boolean mIsHandoverInitiated; private static final String OPP_PREFERENCE_FILE = "OPPMGR"; private static final String OPP_PREFERENCE_FILE = "OPPMGR"; private static final String SENDING_FLAG = "SENDINGFLAG"; private static final String SENDING_FLAG = "SENDINGFLAG"; Loading Loading @@ -105,6 +110,13 @@ public class BluetoothOppManager { private int mInsertShareThreadNum = 0; private int mInsertShareThreadNum = 0; // A list of devices that may send files over OPP to this device // without user confirmation. Used for connection handover from forex NFC. private List<Pair<String,Long> > mWhitelist = new ArrayList<Pair<String, Long> >(); // The time for which the whitelist entries remain valid. private static final int WHITELIST_DURATION_MS = 15000; /** /** * Get singleton instance. * Get singleton instance. */ */ Loading Loading @@ -140,15 +152,31 @@ public class BluetoothOppManager { return true; return true; } } List<String> mWhitelist = new ArrayList<String>(); private void cleanupWhitelist() { // Removes expired entries long curTime = SystemClock.elapsedRealtime(); for (Iterator<Pair<String,Long>> iter = mWhitelist.iterator(); iter.hasNext(); ) { Pair<String,Long> entry = iter.next(); if (curTime - entry.second > WHITELIST_DURATION_MS) { if (V) Log.v(TAG, "Cleaning out whitelist entry " + entry.first); iter.remove(); } } } public void addToWhitelist(String address) { public void addToWhitelist(String address) { //TODO: timeout whitelist if (address == null) return; mWhitelist.add(address); mWhitelist.add(new Pair<String, Long>(address, SystemClock.elapsedRealtime())); } } public boolean isWhitelisted(String address) { public boolean isWhitelisted(String address) { return mWhitelist.contains(address); cleanupWhitelist(); for (Pair<String,Long> entry : mWhitelist) { if (entry.first.equals(address)) return true; } return false; } } /** /** Loading Loading @@ -212,20 +240,22 @@ public class BluetoothOppManager { if (V) Log.v(TAG, "Application data stored to SharedPreference! "); if (V) Log.v(TAG, "Application data stored to SharedPreference! "); } } public void saveSendingFileInfo(String mimeType, String uri) { public void saveSendingFileInfo(String mimeType, String uri, boolean isHandover) { synchronized (BluetoothOppManager.this) { synchronized (BluetoothOppManager.this) { mMultipleFlag = false; mMultipleFlag = false; mMimeTypeOfSendingFile = mimeType; mMimeTypeOfSendingFile = mimeType; mUriOfSendingFile = uri; mUriOfSendingFile = uri; mIsHandoverInitiated = isHandover; storeApplicationData(); storeApplicationData(); } } } } public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris) { public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover) { synchronized (BluetoothOppManager.this) { synchronized (BluetoothOppManager.this) { mMultipleFlag = true; mMultipleFlag = true; mMimeTypeOfSendingFiles = mimeType; mMimeTypeOfSendingFiles = mimeType; mUrisOfSendingFiles = uris; mUrisOfSendingFiles = uris; mIsHandoverInitiated = isHandover; storeApplicationData(); storeApplicationData(); } } } } Loading Loading @@ -306,7 +336,8 @@ public class BluetoothOppManager { return; return; } } insertThread = new InsertShareInfoThread(device, mMultipleFlag, mMimeTypeOfSendingFile, insertThread = new InsertShareInfoThread(device, mMultipleFlag, mMimeTypeOfSendingFile, mUriOfSendingFile, mMimeTypeOfSendingFiles, mUrisOfSendingFiles); mUriOfSendingFile, mMimeTypeOfSendingFiles, mUrisOfSendingFiles, mIsHandoverInitiated); if (mMultipleFlag) { if (mMultipleFlag) { mfileNumInBatch = mUrisOfSendingFiles.size(); mfileNumInBatch = mUrisOfSendingFiles.size(); } } Loading Loading @@ -336,8 +367,11 @@ public class BluetoothOppManager { private final boolean mIsMultiple; private final boolean mIsMultiple; private final boolean mIsHandoverInitiated; public InsertShareInfoThread(BluetoothDevice device, boolean multiple, public InsertShareInfoThread(BluetoothDevice device, boolean multiple, String typeOfSingleFile, String uri, String typeOfMultipleFiles, ArrayList<Uri> uris) { String typeOfSingleFile, String uri, String typeOfMultipleFiles, ArrayList<Uri> uris, boolean handoverInitiated) { super("Insert ShareInfo Thread"); super("Insert ShareInfo Thread"); this.mRemoteDevice = device; this.mRemoteDevice = device; this.mIsMultiple = multiple; this.mIsMultiple = multiple; Loading @@ -345,6 +379,7 @@ public class BluetoothOppManager { this.mUri = uri; this.mUri = uri; this.mTypeOfMultipleFiles = typeOfMultipleFiles; this.mTypeOfMultipleFiles = typeOfMultipleFiles; this.mUris = uris; this.mUris = uris; this.mIsHandoverInitiated = handoverInitiated; synchronized (BluetoothOppManager.this) { synchronized (BluetoothOppManager.this) { mInsertShareThreadNum++; mInsertShareThreadNum++; Loading Loading @@ -390,7 +425,10 @@ public class BluetoothOppManager { values.put(BluetoothShare.MIMETYPE, contentType); values.put(BluetoothShare.MIMETYPE, contentType); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); values.put(BluetoothShare.TIMESTAMP, ts); values.put(BluetoothShare.TIMESTAMP, ts); if (mIsHandoverInitiated) { values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); } final Uri contentUri = mContext.getContentResolver().insert( final Uri contentUri = mContext.getContentResolver().insert( BluetoothShare.CONTENT_URI, values); BluetoothShare.CONTENT_URI, values); if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " Loading @@ -406,7 +444,10 @@ public class BluetoothOppManager { values.put(BluetoothShare.URI, mUri); values.put(BluetoothShare.URI, mUri); values.put(BluetoothShare.MIMETYPE, mTypeOfSingleFile); values.put(BluetoothShare.MIMETYPE, mTypeOfSingleFile); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); if (mIsHandoverInitiated) { values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); } final Uri contentUri = mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, final Uri contentUri = mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values); values); if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " Loading Loading
android/app/AndroidManifest.xml +22 −1 Original line number Original line Diff line number Diff line Loading @@ -10,6 +10,19 @@ android:label="@string/permlab_bluetoothShareManager" android:label="@string/permlab_bluetoothShareManager" android:description="@string/permdesc_bluetoothShareManager" android:description="@string/permdesc_bluetoothShareManager" android:protectionLevel="signature" /> android:protectionLevel="signature" /> <!-- Allows temporarily whitelisting Bluetooth addresses for sharing --> <permission android:name="com.android.permission.WHITELIST_BLUETOOTH_DEVICE" android:label="@string/permlab_bluetoothWhitelist" android:description="@string/permdesc_bluetoothWhitelist" android:protectionLevel="signature" /> <!-- Allows receiving handover status broadcasts from Bluetooth -->, <permission android:name="com.android.permission.HANDOVER_STATUS" android:label="@string/permlab_handoverStatus" android:description="@string/permdesc_handoverStatus" android:protectionLevel="signature" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" /> <uses-permission android:name="android.permission.ACCESS_BLUETOOTH_SHARE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" /> Loading @@ -21,6 +34,7 @@ <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="com.android.permission.HANDOVER_STATUS" /> <application <application android:icon="@drawable/bt_share" android:icon="@drawable/bt_share" android:label="@string/app_name"> android:label="@string/app_name"> Loading @@ -43,7 +57,14 @@ <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" /> <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" /> <!--action android:name="android.intent.action.BOOT_COMPLETED" /--> <!--action android:name="android.intent.action.BOOT_COMPLETED" /--> <action android:name="android.btopp.intent.action.OPEN_RECEIVED_FILES" /> <action android:name="android.btopp.intent.action.OPEN_RECEIVED_FILES" /> <action android:name="todo-whitelist" /> </intent-filter> </receiver> <receiver android:process="@string/process" android:name=".opp.BluetoothOppHandoverReceiver" android:permission="com.android.permission.WHITELIST_BLUETOOTH_DEVICE"> <intent-filter> <action android:name="android.btopp.intent.action.WHITELIST_DEVICE" /> </intent-filter> </intent-filter> </receiver> </receiver> <activity android:name=".opp.BluetoothOppLauncherActivity" <activity android:name=".opp.BluetoothOppLauncherActivity" Loading
android/app/res/values/strings.xml +11 −0 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,17 @@ <string name="permdesc_bluetoothShareManager">Allows the app to access the <string name="permdesc_bluetoothShareManager">Allows the app to access the BluetoothShare manager and use it to transfer files. </string> BluetoothShare manager and use it to transfer files. </string> <string name="permlab_bluetoothWhitelist">Whitelist bluetooth device access.</string> <string name="permdesc_bluetoothWhitelist">Allows the app to temporarily whitelist a Bluetooth device, allowing that device to send files to this device without user confirmation.</string> <!-- Strings used for a (system only) permission --> <string name="permlab_handoverStatus">Receive BT handover transfer broadcasts.</string> <string name="permdesc_handoverStatus">Allows receiving handover transfer status information from Bluetooth.</string> <!-- string showed on "Share picutre via" dialog --> <!-- string showed on "Share picutre via" dialog --> <string name="bt_share_picker_label">Bluetooth</string> <string name="bt_share_picker_label">Bluetooth</string> Loading
android/app/src/com/android/bluetooth/opp/BluetoothOppHandoverReceiver.java 0 → 100644 +44 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.bluetooth.opp; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class BluetoothOppHandoverReceiver extends BroadcastReceiver { public static final String TAG ="BluetoothOppHandoverReceiver"; private static final boolean D = Constants.DEBUG; private static final boolean V = Constants.VERBOSE; @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Constants.ACTION_WHITELIST_DEVICE)) { BluetoothDevice device = (BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (D) Log.d(TAG, "Adding " + device + " to whitelist"); if (device == null) return; BluetoothOppManager.getInstance(context).addToWhitelist(device.getAddress()); } else { if (D) Log.d(TAG, "Unknown action: " + action); } } }
android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -68,6 +68,7 @@ public class BluetoothOppLauncherActivity extends Activity { Intent intent = getIntent(); Intent intent = getIntent(); String action = intent.getAction(); String action = intent.getAction(); BluetoothDevice device = null; BluetoothDevice device = null; boolean isHandover = true; if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) { if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) { /* /* Loading @@ -75,14 +76,15 @@ public class BluetoothOppLauncherActivity extends Activity { * probably Pictures, videos, or vCards. The Intent should contain * probably Pictures, videos, or vCards. The Intent should contain * an EXTRA_STREAM with the data to attach. * an EXTRA_STREAM with the data to attach. */ */ if (intent.getBooleanExtra(Constants.EXTRA_CONNECTION_HANDOVER, false)) { device = (BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); isHandover = true; } if (action.equals(Intent.ACTION_SEND)) { if (action.equals(Intent.ACTION_SEND)) { // TODO: handle type == null case // TODO: handle type == null case String type = intent.getType(); String type = intent.getType(); Uri stream = (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM); Uri stream = (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM); CharSequence extra_text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT); CharSequence extra_text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT); //TODO: consider only checking EXTRA_DEVICE if it came from NFC device = (BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // If we get ACTION_SEND intent with EXTRA_STREAM, we'll use the // If we get ACTION_SEND intent with EXTRA_STREAM, we'll use the // uri data; // uri data; // If we get ACTION_SEND intent without EXTRA_STREAM, but with // If we get ACTION_SEND intent without EXTRA_STREAM, but with Loading @@ -94,7 +96,7 @@ public class BluetoothOppLauncherActivity extends Activity { // Save type/stream, will be used when adding transfer // Save type/stream, will be used when adding transfer // session to DB. // session to DB. BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, stream.toString()); stream.toString(), isHandover); } else if (extra_text != null && type != null) { } else if (extra_text != null && type != null) { if (V) Log.v(TAG, "Get ACTION_SEND intent with Extra_text = " if (V) Log.v(TAG, "Get ACTION_SEND intent with Extra_text = " + extra_text.toString() + "; mimetype = " + type); + extra_text.toString() + "; mimetype = " + type); Loading @@ -102,7 +104,7 @@ public class BluetoothOppLauncherActivity extends Activity { if (fileUri != null) { if (fileUri != null) { BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, BluetoothOppManager.getInstance(this).saveSendingFileInfo(type, fileUri.toString()); fileUri.toString(), isHandover); } } } else { } else { Log.e(TAG, "type is null; or sending file URI is null"); Log.e(TAG, "type is null; or sending file URI is null"); Loading @@ -116,7 +118,8 @@ public class BluetoothOppLauncherActivity extends Activity { if (mimeType != null && uris != null) { if (mimeType != null && uris != null) { if (V) Log.v(TAG, "Get ACTION_SHARE_MULTIPLE intent: uris " + uris + "\n Type= " if (V) Log.v(TAG, "Get ACTION_SHARE_MULTIPLE intent: uris " + uris + "\n Type= " + mimeType); + mimeType); BluetoothOppManager.getInstance(this).saveSendingFileInfo(mimeType, uris); BluetoothOppManager.getInstance(this).saveSendingFileInfo(mimeType, uris, isHandover); } else { } else { Log.e(TAG, "type is null; or sending files URIs are null"); Log.e(TAG, "type is null; or sending files URIs are null"); finish(); finish(); Loading
android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java +51 −10 Original line number Original line Diff line number Diff line Loading @@ -43,10 +43,13 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences; import android.net.Uri; import android.net.Uri; import android.os.Process; import android.os.Process; import android.os.SystemClock; import android.text.TextUtils; import android.text.TextUtils; import android.util.Log; import android.util.Log; import android.util.Pair; import java.util.ArrayList; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.List; /** /** Loading Loading @@ -77,6 +80,8 @@ public class BluetoothOppManager { private ArrayList<Uri> mUrisOfSendingFiles; private ArrayList<Uri> mUrisOfSendingFiles; private boolean mIsHandoverInitiated; private static final String OPP_PREFERENCE_FILE = "OPPMGR"; private static final String OPP_PREFERENCE_FILE = "OPPMGR"; private static final String SENDING_FLAG = "SENDINGFLAG"; private static final String SENDING_FLAG = "SENDINGFLAG"; Loading Loading @@ -105,6 +110,13 @@ public class BluetoothOppManager { private int mInsertShareThreadNum = 0; private int mInsertShareThreadNum = 0; // A list of devices that may send files over OPP to this device // without user confirmation. Used for connection handover from forex NFC. private List<Pair<String,Long> > mWhitelist = new ArrayList<Pair<String, Long> >(); // The time for which the whitelist entries remain valid. private static final int WHITELIST_DURATION_MS = 15000; /** /** * Get singleton instance. * Get singleton instance. */ */ Loading Loading @@ -140,15 +152,31 @@ public class BluetoothOppManager { return true; return true; } } List<String> mWhitelist = new ArrayList<String>(); private void cleanupWhitelist() { // Removes expired entries long curTime = SystemClock.elapsedRealtime(); for (Iterator<Pair<String,Long>> iter = mWhitelist.iterator(); iter.hasNext(); ) { Pair<String,Long> entry = iter.next(); if (curTime - entry.second > WHITELIST_DURATION_MS) { if (V) Log.v(TAG, "Cleaning out whitelist entry " + entry.first); iter.remove(); } } } public void addToWhitelist(String address) { public void addToWhitelist(String address) { //TODO: timeout whitelist if (address == null) return; mWhitelist.add(address); mWhitelist.add(new Pair<String, Long>(address, SystemClock.elapsedRealtime())); } } public boolean isWhitelisted(String address) { public boolean isWhitelisted(String address) { return mWhitelist.contains(address); cleanupWhitelist(); for (Pair<String,Long> entry : mWhitelist) { if (entry.first.equals(address)) return true; } return false; } } /** /** Loading Loading @@ -212,20 +240,22 @@ public class BluetoothOppManager { if (V) Log.v(TAG, "Application data stored to SharedPreference! "); if (V) Log.v(TAG, "Application data stored to SharedPreference! "); } } public void saveSendingFileInfo(String mimeType, String uri) { public void saveSendingFileInfo(String mimeType, String uri, boolean isHandover) { synchronized (BluetoothOppManager.this) { synchronized (BluetoothOppManager.this) { mMultipleFlag = false; mMultipleFlag = false; mMimeTypeOfSendingFile = mimeType; mMimeTypeOfSendingFile = mimeType; mUriOfSendingFile = uri; mUriOfSendingFile = uri; mIsHandoverInitiated = isHandover; storeApplicationData(); storeApplicationData(); } } } } public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris) { public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover) { synchronized (BluetoothOppManager.this) { synchronized (BluetoothOppManager.this) { mMultipleFlag = true; mMultipleFlag = true; mMimeTypeOfSendingFiles = mimeType; mMimeTypeOfSendingFiles = mimeType; mUrisOfSendingFiles = uris; mUrisOfSendingFiles = uris; mIsHandoverInitiated = isHandover; storeApplicationData(); storeApplicationData(); } } } } Loading Loading @@ -306,7 +336,8 @@ public class BluetoothOppManager { return; return; } } insertThread = new InsertShareInfoThread(device, mMultipleFlag, mMimeTypeOfSendingFile, insertThread = new InsertShareInfoThread(device, mMultipleFlag, mMimeTypeOfSendingFile, mUriOfSendingFile, mMimeTypeOfSendingFiles, mUrisOfSendingFiles); mUriOfSendingFile, mMimeTypeOfSendingFiles, mUrisOfSendingFiles, mIsHandoverInitiated); if (mMultipleFlag) { if (mMultipleFlag) { mfileNumInBatch = mUrisOfSendingFiles.size(); mfileNumInBatch = mUrisOfSendingFiles.size(); } } Loading Loading @@ -336,8 +367,11 @@ public class BluetoothOppManager { private final boolean mIsMultiple; private final boolean mIsMultiple; private final boolean mIsHandoverInitiated; public InsertShareInfoThread(BluetoothDevice device, boolean multiple, public InsertShareInfoThread(BluetoothDevice device, boolean multiple, String typeOfSingleFile, String uri, String typeOfMultipleFiles, ArrayList<Uri> uris) { String typeOfSingleFile, String uri, String typeOfMultipleFiles, ArrayList<Uri> uris, boolean handoverInitiated) { super("Insert ShareInfo Thread"); super("Insert ShareInfo Thread"); this.mRemoteDevice = device; this.mRemoteDevice = device; this.mIsMultiple = multiple; this.mIsMultiple = multiple; Loading @@ -345,6 +379,7 @@ public class BluetoothOppManager { this.mUri = uri; this.mUri = uri; this.mTypeOfMultipleFiles = typeOfMultipleFiles; this.mTypeOfMultipleFiles = typeOfMultipleFiles; this.mUris = uris; this.mUris = uris; this.mIsHandoverInitiated = handoverInitiated; synchronized (BluetoothOppManager.this) { synchronized (BluetoothOppManager.this) { mInsertShareThreadNum++; mInsertShareThreadNum++; Loading Loading @@ -390,7 +425,10 @@ public class BluetoothOppManager { values.put(BluetoothShare.MIMETYPE, contentType); values.put(BluetoothShare.MIMETYPE, contentType); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); values.put(BluetoothShare.TIMESTAMP, ts); values.put(BluetoothShare.TIMESTAMP, ts); if (mIsHandoverInitiated) { values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); } final Uri contentUri = mContext.getContentResolver().insert( final Uri contentUri = mContext.getContentResolver().insert( BluetoothShare.CONTENT_URI, values); BluetoothShare.CONTENT_URI, values); if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " Loading @@ -406,7 +444,10 @@ public class BluetoothOppManager { values.put(BluetoothShare.URI, mUri); values.put(BluetoothShare.URI, mUri); values.put(BluetoothShare.MIMETYPE, mTypeOfSingleFile); values.put(BluetoothShare.MIMETYPE, mTypeOfSingleFile); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); values.put(BluetoothShare.DESTINATION, mRemoteDevice.getAddress()); if (mIsHandoverInitiated) { values.put(BluetoothShare.USER_CONFIRMATION, BluetoothShare.USER_CONFIRMATION_HANDOVER_CONFIRMED); } final Uri contentUri = mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, final Uri contentUri = mContext.getContentResolver().insert(BluetoothShare.CONTENT_URI, values); values); if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " if (V) Log.v(TAG, "Insert contentUri: " + contentUri + " to device: " Loading