diff options
-rw-r--r-- | PMC/src/com/android/pmc/A2dpReceiver.java | 500 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/BleScanReceiver.java | 35 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/GattClientListener.java | 2 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/GattPMCReceiver.java | 3 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/GattServer.java | 3 | ||||
-rw-r--r-- | PMC/src/com/android/pmc/PMCStatusLogger.java | 116 |
6 files changed, 367 insertions, 292 deletions
diff --git a/PMC/src/com/android/pmc/A2dpReceiver.java b/PMC/src/com/android/pmc/A2dpReceiver.java index 7c10157..7cb4ece 100644 --- a/PMC/src/com/android/pmc/A2dpReceiver.java +++ b/PMC/src/com/android/pmc/A2dpReceiver.java @@ -35,6 +35,7 @@ import android.os.SystemClock; import android.util.Log; import java.util.ArrayList; +import java.util.Set; /** * Bluetooth A2DP Receiver functions for codec power testing. @@ -43,31 +44,21 @@ public class A2dpReceiver extends BroadcastReceiver { public static final String TAG = "A2DPPOWER"; public static final String A2DP_INTENT = "com.android.pmc.A2DP"; public static final String A2DP_ALARM = "com.android.pmc.A2DP.Alarm"; - public static final String A2DP_ACTION = "com.android.pmc.A2DP.Action"; - public static final String CURRENT_ALARM = "com.android.pmc.A2DP.CurrentAlarm"; - public static final int ALARM_MESSAGE = 1; public static final int THOUSAND = 1000; public static final int WAIT_SECONDS = 10; + public static final int ALARM_MESSAGE = 1; - public static final int START_PLAY = 1; - public static final int PAUSE_PLAY = 2; - public static final int STOP_PLAY = 3; public static final float NORMAL_VOLUME = 0.3f; public static final float ZERO_VOLUME = 0.0f; private final Context mContext; private final AlarmManager mAlarmManager; + private final BluetoothAdapter mBluetoothAdapter; - private int mPlayTime; - private int mIdleTime; - private int mNumAlarms; private MediaPlayer mPlayer; - private BluetoothAdapter mBluetoothAdapter; private BluetoothA2dp mBluetoothA2dp; - // For a baseline case when music is not play but BT is enabled. - private boolean mNotPlay = false; - // For a baseline case when BT is off but music is playing with speaker is muted - private boolean mMute = false; + + private PMCStatusLogger mPMCStatusLogger; /** * BroadcastReceiver() to get status after calling setCodecConfigPreference() @@ -114,6 +105,7 @@ public class A2dpReceiver extends BroadcastReceiver { // Prepare for setting alarm service mContext = context; mAlarmManager = alarmManager; + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { Log.e(TAG, "BluetoothAdapter is Null"); @@ -131,13 +123,48 @@ public class A2dpReceiver extends BroadcastReceiver { // Setup BroadcastReceiver for ACTION_CODEC_CONFIG_CHANGED IntentFilter filter = new IntentFilter(); if (mBluetoothAdapter != null) { - mBluetoothAdapter.getProfileProxy(context, + mBluetoothAdapter.getProfileProxy(mContext, mBluetoothA2dpServiceListener, BluetoothProfile.A2DP); + Log.d(TAG, "After getProfileProxy()"); } filter = new IntentFilter(); filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED); - context.registerReceiver(mBluetoothA2dpReceiver, filter); + mContext.registerReceiver(mBluetoothA2dpReceiver, filter); + + Log.d(TAG, "A2dpReceiver()"); + } + + /** + * initialize() to setup Bluetooth adapters and check if Bluetooth device is connected + * it is called when PMC command is received to start streaming + */ + private boolean initialize() { + Log.d(TAG, "Start initialize()"); + + mPMCStatusLogger = new PMCStatusLogger(TAG + ".log", TAG); + + // Check if any Bluetooth devices are connected + ArrayList<BluetoothDevice> results = new ArrayList<BluetoothDevice>(); + Set<BluetoothDevice> bondedDevices = mBluetoothAdapter.getBondedDevices(); + if (bondedDevices == null) { + Log.e(TAG, "Bonded devices list is null"); + return false; + } + for (BluetoothDevice bd : bondedDevices) { + if (bd.isConnected()) { + results.add(bd); + } + } + + if (results.isEmpty()) { + Log.e(TAG, "No device is connected"); + return false; + } + + Log.d(TAG, "Finish initialize()"); + + return true; } /** @@ -151,8 +178,11 @@ public class A2dpReceiver extends BroadcastReceiver { if (!intent.getAction().equals(A2DP_INTENT)) return; boolean alarm = intent.hasExtra(A2DP_ALARM); if (alarm) { - Log.d(TAG, "Received Alarm broadcast message"); - handleAlarm(intent); + Log.v(TAG, "Alarm Message to Stop playing"); + mPMCStatusLogger.logStatus("SUCCEED"); + mPlayer.stop(); + // Release the Media Player + mPlayer.release(); } else { Log.d(TAG, "Received PMC command message"); processParameters(intent); @@ -173,14 +203,12 @@ public class A2dpReceiver extends BroadcastReceiver { // Other code specific values are not used now long codecSpecific1 = 0, codecSpecific2 = 0, codecSpecific3 = 0, codecSpecific4 = 0; - int startTime = 0, playTime = 0, idleTime = 0, repetitions = 1; + int playTime = 0; String musicUrl; String tmpStr; - // Reset these values for each test cases - // For a baseline case when music is not play but BT is enabled. - mNotPlay = false; - // For a baseline case when BT is off but music is playing with speaker is muted - mMute = false; + + // For a baseline case when Blueooth is off but music is playing with speaker is muted + boolean bt_off_mute = false; Bundle extras = intent.getExtras(); @@ -188,68 +216,19 @@ public class A2dpReceiver extends BroadcastReceiver { Log.e(TAG, "No parameters specified"); return; } - - if (!extras.containsKey("CodecType")) { - Log.e(TAG, "No Codec Type specified"); - return; - } - tmpStr = extras.getString("CodecType"); - Log.d(TAG, "Codec Type= " + tmpStr); - codecType = Integer.valueOf(tmpStr); - - if (!extras.containsKey("SampleRate")) { - Log.e(TAG, "No Sample Rate specified"); - return; - } - tmpStr = extras.getString("SampleRate"); - Log.d(TAG, "Sample Rate = " + tmpStr); - sampleRate = Integer.valueOf(tmpStr); - - if (!extras.containsKey("BitsPerSample")) { - Log.e(TAG, "No BitsPerSample specified"); + // Always initialize() + if (!initialize()) { + mPMCStatusLogger.logStatus("initialize() Failed"); return; } - tmpStr = extras.getString("BitsPerSample"); - Log.d(TAG, "BitsPerSample = " + tmpStr); - bitsPerSample = Integer.valueOf(tmpStr); - - if (extras.containsKey("ChannelMode")) { - tmpStr = extras.getString("ChannelMode"); - Log.d(TAG, "ChannelMode = " + tmpStr); - channelMode = Integer.valueOf(tmpStr); - } - - if (extras.containsKey("LdacPlaybackQuality")) { - tmpStr = extras.getString("LdacPlaybackQuality"); - Log.d(TAG, "LdacPlaybackQuality = " + tmpStr); - codecSpecific1 = Integer.valueOf(tmpStr); - } - - if (extras.containsKey("CodecSpecific2")) { - tmpStr = extras.getString("CodecSpecific2"); - Log.d(TAG, "CodecSpecific2 = " + tmpStr); - codecSpecific1 = Integer.valueOf(tmpStr); - } - - if (extras.containsKey("CodecSpecific3")) { - tmpStr = extras.getString("CodecSpecific3"); - Log.d(TAG, "CodecSpecific3 = " + tmpStr); - codecSpecific1 = Integer.valueOf(tmpStr); - } - - if (extras.containsKey("CodecSpecific4")) { - tmpStr = extras.getString("CodecSpecific4"); - Log.d(TAG, "CodecSpecific4 = " + tmpStr); - codecSpecific1 = Integer.valueOf(tmpStr); - } - - if (!extras.containsKey("StartTime")) { - Log.e(TAG, "No Start Time specified"); + // Check if it is baseline Bluetooth is on but not stream + if (extras.containsKey("BT_ON_NotPlay")) { + Log.v(TAG, "NotPlay is specified for baseline case that only Bluetooth is on"); + // Do nothing further + mPMCStatusLogger.logStatus("READY"); + mPMCStatusLogger.logStatus("SUCCEED"); return; } - tmpStr = extras.getString("StartTime"); - Log.d(TAG, "Start Time = " + tmpStr); - startTime = Integer.valueOf(tmpStr); if (!extras.containsKey("PlayTime")) { Log.e(TAG, "No Play Time specified"); @@ -259,18 +238,6 @@ public class A2dpReceiver extends BroadcastReceiver { Log.d(TAG, "Play Time = " + tmpStr); playTime = Integer.valueOf(tmpStr); - if (extras.containsKey("IdleTime")) { - tmpStr = extras.getString("IdleTime"); - Log.d(TAG, "Idle Time = " + tmpStr); - idleTime = Integer.valueOf(tmpStr); - } - - if (extras.containsKey("Repetitions")) { - tmpStr = extras.getString("Repetitions"); - Log.d(TAG, "Repetitions = " + tmpStr); - repetitions = Integer.valueOf(tmpStr); - } - if (!extras.containsKey("MusicURL")) { Log.e(TAG, "No Music URL specified"); return; @@ -278,187 +245,104 @@ public class A2dpReceiver extends BroadcastReceiver { musicUrl = extras.getString("MusicURL"); Log.d(TAG, "Music URL = " + musicUrl); - if (extras.containsKey("NotPlay")) { - Log.v(TAG, "NotPlay is specified for baseline case of only BT on"); - mNotPlay = true; - } - - if (extras.containsKey("Mute")) { - Log.v(TAG, "Mute is specified for BT off baseline case"); - mMute = true; - } - - if (playTime == 0 || startTime == 0 || musicUrl.isEmpty() || musicUrl == null - || codecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID - || sampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE - || bitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) { + // playTime and musicUrl are necessary + if (playTime == 0 || musicUrl.isEmpty() || musicUrl == null) { Log.d(TAG, "Invalid paramters"); return; } + // Check if it is the baseline that Bluetooth is off but streaming with speakers muted + if (extras.containsKey("BT_OFF_Mute")) { + Log.v(TAG, "Mute is specified for Bluetooth off baseline case"); + bt_off_mute = true; + } else { - if (prepare(codecType, sampleRate, bitsPerSample, channelMode, codecSpecific1, - codecSpecific2, codecSpecific3, codecSpecific4, - playTime, idleTime, repetitions, musicUrl)) { - startAlarm(startTime, null); - } - } + if (!extras.containsKey("CodecType")) { + Log.e(TAG, "No Codec Type specified"); + return; + } + tmpStr = extras.getString("CodecType"); + Log.d(TAG, "Codec Type= " + tmpStr); + codecType = Integer.valueOf(tmpStr); - /** - * Method to start or stop playing music when Alarm is triggered - * - * @param intent - system will provide an intent to this function - */ - private void handleAlarm(Intent intent) { + if (!extras.containsKey("SampleRate")) { + Log.e(TAG, "No Sample Rate specified"); + return; + } + tmpStr = extras.getString("SampleRate"); + Log.d(TAG, "Sample Rate = " + tmpStr); + sampleRate = Integer.valueOf(tmpStr); - int action = intent.getIntExtra(A2DP_ACTION, 0); - Log.d(TAG, "handleAlarm() Action: " + action); - if (action == -1) { - Log.e(TAG, "Received Alarm with no Action"); - return; - } - if (mPlayer == null) { - Log.e(TAG, "Media Player is null"); - return; - } + if (!extras.containsKey("BitsPerSample")) { + Log.e(TAG, "No BitsPerSample specified"); + return; + } + tmpStr = extras.getString("BitsPerSample"); + Log.d(TAG, "BitsPerSample = " + tmpStr); + bitsPerSample = Integer.valueOf(tmpStr); + + if (extras.containsKey("ChannelMode")) { + tmpStr = extras.getString("ChannelMode"); + Log.d(TAG, "ChannelMode = " + tmpStr); + channelMode = Integer.valueOf(tmpStr); + } - if (mNotPlay) { - notPlayCase(intent, action); - return; - } + if (extras.containsKey("LdacPlaybackQuality")) { + tmpStr = extras.getString("LdacPlaybackQuality"); + Log.d(TAG, "LdacPlaybackQuality = " + tmpStr); + codecSpecific1 = Integer.valueOf(tmpStr); + } - if (action == START_PLAY) { - Log.v(TAG, "Before Start Play"); - mPlayer.start(); - mPlayer.setLooping(true); - if (!mPlayer.isPlaying()) { - Log.e(TAG, "Media Player is not playing"); + if (extras.containsKey("CodecSpecific2")) { + tmpStr = extras.getString("CodecSpecific2"); + Log.d(TAG, "CodecSpecific2 = " + tmpStr); + codecSpecific1 = Integer.valueOf(tmpStr); } - startAlarm(mPlayTime, intent); - } else if (action == PAUSE_PLAY) { - Log.v(TAG, "Before Pause play"); - mPlayer.pause(); - startAlarm(mIdleTime, intent); - } else if (action == STOP_PLAY) { - Log.v(TAG, "Before Stop play"); - mPlayer.stop(); - // Release the Media Player - mPlayer.release(); - } else { - Log.e(TAG, "Unknown Action"); - } - } + if (extras.containsKey("CodecSpecific3")) { + tmpStr = extras.getString("CodecSpecific3"); + Log.d(TAG, "CodecSpecific3 = " + tmpStr); + codecSpecific1 = Integer.valueOf(tmpStr); + } - /** - * Method for baseline case "Not Play" when Alarm is triggered - * - * @param intent - system will provide an intent to this function - */ - private void notPlayCase(Intent intent, int action) { - - if (action == START_PLAY) { - Log.v(TAG, "NotPlay case for PlAY action"); - startAlarm(mPlayTime, intent); - } else if (action == PAUSE_PLAY) { - Log.v(TAG, "NotPlay case for PAUSE"); - startAlarm(mIdleTime, intent); - } else if (action == STOP_PLAY) { - Log.v(TAG, "NotPlay case for Stop play"); - // Release the Media Player - mPlayer.release(); - } else { - Log.e(TAG, "Unknown Action"); - } - } + if (extras.containsKey("CodecSpecific4")) { + tmpStr = extras.getString("CodecSpecific4"); + Log.d(TAG, "CodecSpecific4 = " + tmpStr); + codecSpecific1 = Integer.valueOf(tmpStr); + } - /** - * Method to verify if the codec config values are changed - * - * @param codecType - Codec Type - * @param sampleRate - Sample Rate - * @param bitsPerSample - Bit Per Sample - * @param codecSpecific1 - LDAC playback quality - */ - private boolean verifyCodeConfig(int codecType, int sampleRate, int bitsPerSample, - int channelMode, long codecSpecific1) { - BluetoothCodecConfig codecConfig = null; - codecConfig = getCodecValue(false); - if (codecConfig == null) return false; + if (codecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID + || sampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE + || bitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) { + Log.d(TAG, "Invalid paramters"); + return; + } + } - if (codecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) { - if (codecConfig.getCodecType() == codecType - && codecConfig.getSampleRate() == sampleRate - && codecConfig.getBitsPerSample() == bitsPerSample - && codecConfig.getChannelMode() == channelMode - && codecConfig.getCodecSpecific1() == codecSpecific1) return true; + if (playMusic(musicUrl, bt_off_mute)) { + // Set the requested Codecs on the device for normal codec cases + if (!bt_off_mute) { + if (!setCodecValue(codecType, sampleRate, bitsPerSample, channelMode, + codecSpecific1, codecSpecific2, codecSpecific3, codecSpecific4)) { + mPMCStatusLogger.logStatus("setCodecValue() Failed"); + } + } + mPMCStatusLogger.logStatus("READY"); + startAlarm(playTime); } else { - if (codecConfig.getCodecType() == codecType - && codecConfig.getSampleRate() == sampleRate - && codecConfig.getBitsPerSample() == bitsPerSample - && codecConfig.getChannelMode() == channelMode) return true; + mPMCStatusLogger.logStatus("playMusic() Failed"); } - - return false; } + /** - * Function to setup MediaPlayer + * Function to setup MediaPlayer and play music * - * @param codecType - Codec Type - * @param sampleRate - Sample Rate - * @param bitsPerSample - Bit Per Sample - * @param codecSpecific1 - LDAC playback quality - * @param codecSpecific2 - codecSpecific2 - * @param codecSpecific3 - codecSpecific3 - * @param codecSpecific4 - codecSpecific4 - * @param playTime - Music playing duration - * @param idleTime - Pause time for music - * @param repetitions - number of cycles of play/pause * @param musicURL - Music URL + * @param bt_off_mute - true is to mute speakers * */ - private boolean prepare(int codecType, int sampleRate, int bitsPerSample, int channelMode, - long codecSpecific1, long codecSpecific2, long codecSpecific3, - long codecSpecific4, - int playTime, int idleTime, int repetitions, String musicURL) { - ArrayList<BluetoothDevice> results = new ArrayList<BluetoothDevice>(); - // When mMute is specific Bluetooth will be disabled by Python script - if (!mMute) { - for (BluetoothDevice bd : mBluetoothAdapter.getBondedDevices()) { - if (bd.isConnected()) { - results.add(bd); - } - } + private boolean playMusic(String musicURL, boolean btOffMute) { - if (results.isEmpty()) { - Log.e(TAG, "No device is connected"); - return false; - } - - // Set the requested Codecs on the device - setCodecValue(codecType, sampleRate, bitsPerSample, channelMode, codecSpecific1, - codecSpecific2, codecSpecific3, codecSpecific4); - // Wait here to see if the codec is changed to new value - for (int i = 0; i < WAIT_SECONDS; i++) { - if (verifyCodeConfig(codecType, sampleRate, - bitsPerSample, channelMode, codecSpecific1)) { - break; - } - try { - Thread.sleep(THOUSAND); - } catch (InterruptedException e) { - Log.d(TAG, "Sleep is interrupted"); - } - } - if (!verifyCodeConfig(codecType, sampleRate, - bitsPerSample, channelMode, codecSpecific1)) { - Log.e(TAG, "Codec config is NOT set correctly"); - return false; - } - } - mPlayTime = playTime; - mIdleTime = idleTime; - mNumAlarms = repetitions * 2; mPlayer = MediaPlayer.create(mContext, Uri.parse(musicURL)); if (mPlayer == null) { Log.e(TAG, "Failed to create Media Player"); @@ -466,14 +350,22 @@ public class A2dpReceiver extends BroadcastReceiver { } Log.d(TAG, "Media Player created: " + musicURL); - if (mMute) { - Log.v(TAG, "Mute Speakers for BT off baseline case"); + if (btOffMute) { + Log.v(TAG, "Mute Speakers for Bluetooth off baseline case"); mPlayer.setVolume(ZERO_VOLUME, ZERO_VOLUME); } else { Log.d(TAG, "Set Normal Volume for speakers"); mPlayer.setVolume(NORMAL_VOLUME, NORMAL_VOLUME); } + // Play Music now and setup looping + mPlayer.start(); + mPlayer.setLooping(true); + if (!mPlayer.isPlaying()) { + Log.e(TAG, "Media Player is not playing"); + return false; + } + return true; } @@ -481,38 +373,11 @@ public class A2dpReceiver extends BroadcastReceiver { * Function to be called to start alarm * * @param alarmStartTime - time when the music needs to be started or stopped - * @param intent - intent to content alarm number and current action */ - public void startAlarm(int alarmStartTime, Intent intent) { - int currentAlarm = 0; - int nextAction = START_PLAY; - int currentAction = 0; - - if (intent != null) { - if (currentAlarm >= mNumAlarms) { - Log.d(TAG, "All alarms are done"); - return; - } - // Get alarm number inside the intent - currentAlarm = intent.getIntExtra(CURRENT_ALARM, 0); - currentAction = intent.getIntExtra(A2DP_ACTION, 0); - if (currentAlarm == mNumAlarms - 1) { - // last alarm - nextAction = STOP_PLAY; - } else if (currentAction == START_PLAY) { - nextAction = PAUSE_PLAY; - } else { - nextAction = START_PLAY; - } - } - - Log.d(TAG, "Current Alarm: " + currentAlarm + " Action: " + currentAction - + " trigger time: " + alarmStartTime); + private void startAlarm(int alarmStartTime) { Intent alarmIntent = new Intent(A2DP_INTENT); alarmIntent.putExtra(A2DP_ALARM, ALARM_MESSAGE); - alarmIntent.putExtra(A2DP_ACTION, nextAction); - alarmIntent.putExtra(CURRENT_ALARM, ++currentAlarm); long triggerTime = SystemClock.elapsedRealtime() + alarmStartTime * THOUSAND; @@ -531,8 +396,6 @@ public class A2dpReceiver extends BroadcastReceiver { BluetoothCodecConfig codecConfig = null; BluetoothCodecConfig[] codecsLocalCapabilities = null; BluetoothCodecConfig[] codecsSelectableCapabilities = null; - // In the mute case BT is off there will be not Codec Info available - if (mMute) return null; if (mBluetoothA2dp != null) { codecStatus = mBluetoothA2dp.getCodecStatus(); @@ -570,26 +433,87 @@ public class A2dpReceiver extends BroadcastReceiver { * @param codecSpecific3 - codecSpecific3 * @param codecSpecific4 - codecSpecific4 */ - private void setCodecValue(int codecType, int sampleRate, int bitsPerSample, + private boolean setCodecValue(int codecType, int sampleRate, int bitsPerSample, int channelMode, long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4) { Log.d(TAG, "SetCodecValue: Codec Type: " + codecType + " sampleRate: " + sampleRate + " bitsPerSample: " + bitsPerSample + " Channel Mode: " + channelMode + " LDAC quality: " + codecSpecific1); - // In the mute case BT is off there will be not Codec Info available - if (mMute) return; - BluetoothCodecConfig codecConfig = new BluetoothCodecConfig(codecType, BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, sampleRate, bitsPerSample, channelMode, codecSpecific1, codecSpecific2, codecSpecific3, codecSpecific4); + // Wait here to see if mBluetoothA2dp is set + for (int i = 0; i < WAIT_SECONDS; i++) { + Log.d(TAG, "Wait for BluetoothA2dp"); + if (mBluetoothA2dp != null) { + break; + } + + try { + Thread.sleep(THOUSAND); + } catch (InterruptedException e) { + Log.d(TAG, "Sleep is interrupted"); + } + } + if (mBluetoothA2dp != null) { Log.d(TAG, "setCodecConfigPreference()"); mBluetoothA2dp.setCodecConfigPreference(codecConfig); } else { Log.e(TAG, "mBluetoothA2dp is null. Codec is not set"); + return false; + } + // Wait here to see if the codec is changed to new value + for (int i = 0; i < WAIT_SECONDS; i++) { + if (verifyCodeConfig(codecType, sampleRate, + bitsPerSample, channelMode, codecSpecific1)) { + break; + } + try { + Thread.sleep(THOUSAND); + } catch (InterruptedException e) { + Log.d(TAG, "Sleep is interrupted"); + } + } + if (!verifyCodeConfig(codecType, sampleRate, + bitsPerSample, channelMode, codecSpecific1)) { + Log.e(TAG, "Codec config is NOT set correctly"); + return false; } + return true; } + + /** + * Method to verify if the codec config values are changed + * + * @param codecType - Codec Type + * @param sampleRate - Sample Rate + * @param bitsPerSample - Bit Per Sample + * @param codecSpecific1 - LDAC playback quality + */ + private boolean verifyCodeConfig(int codecType, int sampleRate, int bitsPerSample, + int channelMode, long codecSpecific1) { + BluetoothCodecConfig codecConfig = null; + codecConfig = getCodecValue(false); + if (codecConfig == null) return false; + + if (codecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) { + if (codecConfig.getCodecType() == codecType + && codecConfig.getSampleRate() == sampleRate + && codecConfig.getBitsPerSample() == bitsPerSample + && codecConfig.getChannelMode() == channelMode + && codecConfig.getCodecSpecific1() == codecSpecific1) return true; + } else { + if (codecConfig.getCodecType() == codecType + && codecConfig.getSampleRate() == sampleRate + && codecConfig.getBitsPerSample() == bitsPerSample + && codecConfig.getChannelMode() == channelMode) return true; + } + + return false; + } + } diff --git a/PMC/src/com/android/pmc/BleScanReceiver.java b/PMC/src/com/android/pmc/BleScanReceiver.java index bd090a2..56532dd 100644 --- a/PMC/src/com/android/pmc/BleScanReceiver.java +++ b/PMC/src/com/android/pmc/BleScanReceiver.java @@ -50,6 +50,10 @@ public class BleScanReceiver extends BroadcastReceiver { private BluetoothLeScanner mBleScanner; private ScanSettings mScanSettings; private List<ScanFilter> mScanFilterList; + // Use PMCStatusLogger to send status and start & end times back to Python client + private PMCStatusLogger mPMCStatusLogger; + // Test start time is set when receiving the broadcast message from Python client + private long mStartTestTime; private ScanCallback mScanCallback = new ScanCallback() { @Override @@ -74,12 +78,16 @@ public class BleScanReceiver extends BroadcastReceiver { private int mScanTime; private int mNoScanTime; private int mNumAlarms; + private int mFirstScanTime; + private long mScanStartTime; + private long mScanEndTime; /** * Constructor * */ public BleScanListener() { + Log.d(TAG, "Start BleScanListener()"); BluetoothAdapter bleAdaptor = BluetoothAdapter.getDefaultAdapter(); if (bleAdaptor == null) { @@ -98,6 +106,7 @@ public class BleScanReceiver extends BroadcastReceiver { mBleScanner = bleAdaptor.getBluetoothLeScanner(); mScanFilterList = new ArrayList<ScanFilter>(); + Log.d(TAG, "End BleScanListener()"); } /** @@ -117,14 +126,15 @@ public class BleScanReceiver extends BroadcastReceiver { mScanTime = scanTime; mNoScanTime = noScanTime; mNumAlarms = numAlarms; + mFirstScanTime = startTime; + mScanSettings = new ScanSettings.Builder().setScanMode( scanMode).build(); Intent alarmIntent = new Intent(BleScanListener.BLESCAN); alarmIntent.putExtra("com.android.pmc.BLESCAN.Action", START_SCAN); alarmIntent.putExtra("com.android.pmc.BLESCAN.CurrentAlarm", INIT_ALARM_NO); - long triggerTime = SystemClock.elapsedRealtime() - + startTime * 1000; + long triggerTime = SystemClock.elapsedRealtime() + startTime * 1000; mAlarmManager.setExactAndAllowWhileIdle( AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, PendingIntent.getBroadcast(mContext, 0, @@ -149,6 +159,7 @@ public class BleScanReceiver extends BroadcastReceiver { return; } if (currentAlarm >= mNumAlarms) { + mPMCStatusLogger.flash(); // To flash out timestamps into log file Log.d(TAG, "All alarms are done"); return; } @@ -183,13 +194,22 @@ public class BleScanReceiver extends BroadcastReceiver { } if (action == START_SCAN) { Log.v(TAG, "Before Start Scan"); + mScanStartTime = System.currentTimeMillis(); mBleScanner.startScan(mScanFilterList, mScanSettings, mScanCallback); repeatAlarm(intent, mScanTime, STOP_SCAN); } else if (action == STOP_SCAN) { Log.v(TAG, "Before Stop scan"); + mScanEndTime = System.currentTimeMillis(); + mPMCStatusLogger.logAlarmTimes(mScanStartTime / 1000.0, mScanEndTime / 1000.0); mBleScanner.stopScan(mScanCallback); - repeatAlarm(intent, mNoScanTime, START_SCAN); + if ((mScanEndTime - mStartTestTime) + < ((mScanTime + mNoScanTime) * mNumAlarms / 2 + mFirstScanTime) * 1000) { + repeatAlarm(intent, mNoScanTime, START_SCAN); + } else { + mPMCStatusLogger.flash(); // To flash out timestamps into log file + Log.d(TAG, "Time is up to end"); + } } else { Log.e(TAG, "Unknown Action"); } @@ -228,6 +248,9 @@ public class BleScanReceiver extends BroadcastReceiver { int repetitions = 1; String str; + mStartTestTime = System.currentTimeMillis(); + mPMCStatusLogger = new PMCStatusLogger(TAG + ".log", TAG); + if (extras == null) { Log.e(TAG, "No parameters specified"); return; @@ -277,6 +300,12 @@ public class BleScanReceiver extends BroadcastReceiver { } mAlarmScanListener.firstAlarm(scanMode, startTime, scanTime, noScanTime, repetitions * 2); + if (mBleScanner != null && mScanFilterList != null && mScanSettings != null + && mScanCallback != null) { + mPMCStatusLogger.logStatus("READY"); + } else { + Log.e(TAG, "BLE scanner is not ready to start test"); + } } } } diff --git a/PMC/src/com/android/pmc/GattClientListener.java b/PMC/src/com/android/pmc/GattClientListener.java index 428149c..a99f41c 100644 --- a/PMC/src/com/android/pmc/GattClientListener.java +++ b/PMC/src/com/android/pmc/GattClientListener.java @@ -72,6 +72,7 @@ public class GattClientListener extends BroadcastReceiver { * @param alarmManager - system will provide a AlarmManager to this function */ public GattClientListener(Context context, AlarmManager alarmManager) { + Log.d(TAG, "Start GattClientListener()"); mContext = context; mAlarmManager = alarmManager; mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -95,6 +96,7 @@ public class GattClientListener extends BroadcastReceiver { mBluetoothGatt = null; mMacAddress = null; mDevice = null; + Log.d(TAG, "End GattClientListener"); } /** diff --git a/PMC/src/com/android/pmc/GattPMCReceiver.java b/PMC/src/com/android/pmc/GattPMCReceiver.java index 5044a9a..4a29dbb 100644 --- a/PMC/src/com/android/pmc/GattPMCReceiver.java +++ b/PMC/src/com/android/pmc/GattPMCReceiver.java @@ -40,6 +40,8 @@ public class GattPMCReceiver extends BroadcastReceiver { * @param alarmManager - PMC will provide alarmManager */ public GattPMCReceiver(Context context, AlarmManager alarmManager) { + Log.d(TAG, "Start GattPMCReceiver()"); + // Prepare for setting alarm service mGattClientListener = new GattClientListener(context, alarmManager); mGattServer = new GattServer(context); @@ -47,6 +49,7 @@ public class GattPMCReceiver extends BroadcastReceiver { // RegisterAlarmReceiver for GattListener context.registerReceiver(mGattClientListener, new IntentFilter(GattClientListener.GATTCLIENT_ALARM)); + Log.d(TAG, "Start GattPMCReceiver()"); } /** diff --git a/PMC/src/com/android/pmc/GattServer.java b/PMC/src/com/android/pmc/GattServer.java index 9e88364..c84861d 100644 --- a/PMC/src/com/android/pmc/GattServer.java +++ b/PMC/src/com/android/pmc/GattServer.java @@ -59,6 +59,7 @@ public class GattServer { * @param context - System will provide a context */ public GattServer(Context context) { + Log.d(TAG, "Start GattServer()"); mContext = context; // Check if Bluetooth is enabled BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); @@ -102,7 +103,7 @@ public class GattServer { // Create BLE Advertiser object mBleAdvertiser = new MyBleAdvertiser(bluetoothAdapter); - Log.d(TAG, "Construstor finished"); + Log.d(TAG, "End GattServer()"); } /** diff --git a/PMC/src/com/android/pmc/PMCStatusLogger.java b/PMC/src/com/android/pmc/PMCStatusLogger.java new file mode 100644 index 0000000..500780e --- /dev/null +++ b/PMC/src/com/android/pmc/PMCStatusLogger.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2017 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.pmc; + +import android.util.Log; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + + +/** + * Logging class to log status so PMC can communicate the status back to client + */ +public class PMCStatusLogger { + private File mFile; + public static String TAG; + public static String LOG_DIR = "/mnt/sdcard/Download"; + public static JSONObject mJObject; + public static JSONArray mJArray; + + /** + * Construtor - check if the file exist. If it is delete and create a new. + * + * @param message - message to be logged + */ + public PMCStatusLogger(String fileName, String tag) { + TAG = tag; + + try { + mFile = new File(LOG_DIR + "/" + fileName); + if (mFile.exists()) mFile.delete(); + mFile.createNewFile(); + } catch (IOException e) { + Log.e(TAG, "Exception creating log file: " + fileName + " " + e); + } + mJObject = new JSONObject(); + mJArray = new JSONArray(); + } + + /** + * Function to log status message into log file + * + * @param message - message to be logged + */ + public void logStatus(String message) { + try { + FileWriter fos = new FileWriter(mFile); + BufferedWriter bw = new BufferedWriter(fos); + bw.write(message); + bw.newLine(); + bw.close(); + } catch (IOException e) { + Log.e(TAG, "Exception writing log: " + message + " " + e); + } + } + + /** + * Function to add alarm times into JSONArray object + * + * @param startTime - Start time for the cycle + * @param endTime - End time for the cycle + */ + public void logAlarmTimes(double startTime, double endTime) { + JSONObject obj = new JSONObject(); + try { + obj.put("StartTime", startTime); + obj.put("EndTime", endTime); + mJArray.put(obj); + } catch (JSONException e) { + Log.e(TAG, "Exception to put Alarm Times into JSONArray: " + e); + } + } + + /** + * Function to save Json object into log file + * + */ + public void flash() { + try { + mJObject.put("AlarmTimes", mJArray); + + FileWriter fos = new FileWriter(mFile); + BufferedWriter bw = new BufferedWriter(fos); + Log.v(TAG, "JSON: " + mJObject.toString()); + bw.write(mJObject.toString()); + bw.newLine(); + bw.close(); + } catch (JSONException e) { + Log.e(TAG, "Exception to put JSONArray into main JSON object: " + e); + } catch (IOException e) { + Log.e(TAG, "Exception writing JSON to log file: " + e); + } + } + +} + |