summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--PMC/src/com/android/pmc/A2dpReceiver.java500
-rw-r--r--PMC/src/com/android/pmc/BleScanReceiver.java35
-rw-r--r--PMC/src/com/android/pmc/GattClientListener.java2
-rw-r--r--PMC/src/com/android/pmc/GattPMCReceiver.java3
-rw-r--r--PMC/src/com/android/pmc/GattServer.java3
-rw-r--r--PMC/src/com/android/pmc/PMCStatusLogger.java116
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);
+ }
+ }
+
+}
+