10eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan/* 20eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Copyright (C) 2017 The Android Open Source Project 30eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 40eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Licensed under the Apache License, Version 2.0 (the "License"); 50eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * you may not use this file except in compliance with the License. 60eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * You may obtain a copy of the License at 70eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 80eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * http://www.apache.org/licenses/LICENSE-2.0 90eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 100eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Unless required by applicable law or agreed to in writing, software 110eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * distributed under the License is distributed on an "AS IS" BASIS, 120eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * See the License for the specific language governing permissions and 140eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * limitations under the License. 150eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 160eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 170eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanpackage com.android.pmc; 180eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 190eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.app.AlarmManager; 200eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.app.PendingIntent; 210eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.bluetooth.BluetoothA2dp; 220eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.bluetooth.BluetoothAdapter; 230eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.bluetooth.BluetoothCodecConfig; 240eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.bluetooth.BluetoothCodecStatus; 250eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.bluetooth.BluetoothDevice; 260eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.bluetooth.BluetoothProfile; 270eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.content.BroadcastReceiver; 280eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.content.Context; 290eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.content.Intent; 300eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.content.IntentFilter; 310eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.media.MediaPlayer; 320eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.net.Uri; 330eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.os.Bundle; 340eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.os.SystemClock; 350eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport android.util.Log; 360eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 370eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanimport java.util.ArrayList; 383aad68c052667ec9b4c833f44432906359530da1Jim Tanimport java.util.Set; 390eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 400eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan/** 410eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Bluetooth A2DP Receiver functions for codec power testing. 420eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 430eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tanpublic class A2dpReceiver extends BroadcastReceiver { 440eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public static final String TAG = "A2DPPOWER"; 450eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public static final String A2DP_INTENT = "com.android.pmc.A2DP"; 460eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public static final String A2DP_ALARM = "com.android.pmc.A2DP.Alarm"; 470eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public static final int THOUSAND = 1000; 480eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public static final int WAIT_SECONDS = 10; 493aad68c052667ec9b4c833f44432906359530da1Jim Tan public static final int ALARM_MESSAGE = 1; 500eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 51ca0b3497c93456c547da1b472d9e221ab8a13cbeJim Tan public static final float NORMAL_VOLUME = 0.3f; 520eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public static final float ZERO_VOLUME = 0.0f; 530eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 540eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private final Context mContext; 550eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private final AlarmManager mAlarmManager; 563aad68c052667ec9b4c833f44432906359530da1Jim Tan private final BluetoothAdapter mBluetoothAdapter; 570eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 580eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private MediaPlayer mPlayer; 590eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private BluetoothA2dp mBluetoothA2dp; 603aad68c052667ec9b4c833f44432906359530da1Jim Tan 613aad68c052667ec9b4c833f44432906359530da1Jim Tan private PMCStatusLogger mPMCStatusLogger; 620eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 630eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 640eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * BroadcastReceiver() to get status after calling setCodecConfigPreference() 650eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 660eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 670eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private BroadcastReceiver mBluetoothA2dpReceiver = new BroadcastReceiver() { 680eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan @Override 690eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public void onReceive(Context context, Intent intent) { 700eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "mBluetoothA2dpReceiver.onReceive() intent=" + intent); 710eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan String action = intent.getAction(); 720eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 730eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED.equals(action)) { 740eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan getCodecValue(true); 750eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 760eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 770eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan }; 780eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 790eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 800eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * ServiceListener for A2DP connection/disconnection event 810eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 820eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 830eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private BluetoothProfile.ServiceListener mBluetoothA2dpServiceListener = 840eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan new BluetoothProfile.ServiceListener() { 850eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public void onServiceConnected(int profile, 860eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan BluetoothProfile proxy) { 870eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "BluetoothA2dpServiceListener.onServiceConnected"); 880eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mBluetoothA2dp = (BluetoothA2dp) proxy; 890eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan getCodecValue(true); 900eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 910eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 920eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public void onServiceDisconnected(int profile) { 930eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "BluetoothA2dpServiceListener.onServiceDisconnected"); 940eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mBluetoothA2dp = null; 950eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 960eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan }; 970eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 980eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 990eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Constructor to be called by PMC 1000eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 1010eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param context - PMC will provide a context 1020eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param alarmManager - PMC will provide alarmManager 1030eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 1040eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public A2dpReceiver(Context context, AlarmManager alarmManager) { 1050eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan // Prepare for setting alarm service 1060eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mContext = context; 1070eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mAlarmManager = alarmManager; 1083aad68c052667ec9b4c833f44432906359530da1Jim Tan 1090eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 1100eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (mBluetoothAdapter == null) { 1110eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.e(TAG, "BluetoothAdapter is Null"); 1120eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return; 1130eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } else { 1140eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (!mBluetoothAdapter.isEnabled()) { 1150eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "BluetoothAdapter is NOT enabled, enable now"); 1160eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mBluetoothAdapter.enable(); 1170eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (!mBluetoothAdapter.isEnabled()) { 1180eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.e(TAG, "Can't enable Bluetooth"); 1190eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return; 1200eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 1210eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 1220eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 1230eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan // Setup BroadcastReceiver for ACTION_CODEC_CONFIG_CHANGED 1240eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan IntentFilter filter = new IntentFilter(); 1250eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (mBluetoothAdapter != null) { 1263aad68c052667ec9b4c833f44432906359530da1Jim Tan mBluetoothAdapter.getProfileProxy(mContext, 1270eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mBluetoothA2dpServiceListener, 1280eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan BluetoothProfile.A2DP); 1293aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "After getProfileProxy()"); 1300eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 1310eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan filter = new IntentFilter(); 1320eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan filter.addAction(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED); 1333aad68c052667ec9b4c833f44432906359530da1Jim Tan mContext.registerReceiver(mBluetoothA2dpReceiver, filter); 1343aad68c052667ec9b4c833f44432906359530da1Jim Tan 1353aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "A2dpReceiver()"); 1363aad68c052667ec9b4c833f44432906359530da1Jim Tan } 1373aad68c052667ec9b4c833f44432906359530da1Jim Tan 1383aad68c052667ec9b4c833f44432906359530da1Jim Tan /** 1393aad68c052667ec9b4c833f44432906359530da1Jim Tan * initialize() to setup Bluetooth adapters and check if Bluetooth device is connected 1403aad68c052667ec9b4c833f44432906359530da1Jim Tan * it is called when PMC command is received to start streaming 1413aad68c052667ec9b4c833f44432906359530da1Jim Tan */ 1423aad68c052667ec9b4c833f44432906359530da1Jim Tan private boolean initialize() { 1433aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "Start initialize()"); 1443aad68c052667ec9b4c833f44432906359530da1Jim Tan 1453aad68c052667ec9b4c833f44432906359530da1Jim Tan // Check if any Bluetooth devices are connected 1463aad68c052667ec9b4c833f44432906359530da1Jim Tan ArrayList<BluetoothDevice> results = new ArrayList<BluetoothDevice>(); 1473aad68c052667ec9b4c833f44432906359530da1Jim Tan Set<BluetoothDevice> bondedDevices = mBluetoothAdapter.getBondedDevices(); 1483aad68c052667ec9b4c833f44432906359530da1Jim Tan if (bondedDevices == null) { 1493aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.e(TAG, "Bonded devices list is null"); 1503aad68c052667ec9b4c833f44432906359530da1Jim Tan return false; 1513aad68c052667ec9b4c833f44432906359530da1Jim Tan } 1523aad68c052667ec9b4c833f44432906359530da1Jim Tan for (BluetoothDevice bd : bondedDevices) { 1533aad68c052667ec9b4c833f44432906359530da1Jim Tan if (bd.isConnected()) { 1543aad68c052667ec9b4c833f44432906359530da1Jim Tan results.add(bd); 1553aad68c052667ec9b4c833f44432906359530da1Jim Tan } 1563aad68c052667ec9b4c833f44432906359530da1Jim Tan } 1573aad68c052667ec9b4c833f44432906359530da1Jim Tan 1583aad68c052667ec9b4c833f44432906359530da1Jim Tan if (results.isEmpty()) { 1593aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.e(TAG, "No device is connected"); 1603aad68c052667ec9b4c833f44432906359530da1Jim Tan return false; 1613aad68c052667ec9b4c833f44432906359530da1Jim Tan } 1623aad68c052667ec9b4c833f44432906359530da1Jim Tan 1633aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "Finish initialize()"); 1643aad68c052667ec9b4c833f44432906359530da1Jim Tan 1653aad68c052667ec9b4c833f44432906359530da1Jim Tan return true; 1660eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 1670eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 1680eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 1690eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Method to receive the broadcast from Python client or AlarmManager 1700eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 1710eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param context - system will provide a context to this function 1720eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param intent - system will provide an intent to this function 1730eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 1740eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan @Override 1750eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan public void onReceive(Context context, Intent intent) { 1760eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (!intent.getAction().equals(A2DP_INTENT)) return; 1770eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan boolean alarm = intent.hasExtra(A2DP_ALARM); 1780eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (alarm) { 1793aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.v(TAG, "Alarm Message to Stop playing"); 1803aad68c052667ec9b4c833f44432906359530da1Jim Tan mPMCStatusLogger.logStatus("SUCCEED"); 1813aad68c052667ec9b4c833f44432906359530da1Jim Tan mPlayer.stop(); 1823aad68c052667ec9b4c833f44432906359530da1Jim Tan // Release the Media Player 1833aad68c052667ec9b4c833f44432906359530da1Jim Tan mPlayer.release(); 1840eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } else { 1850eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Received PMC command message"); 1860eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan processParameters(intent); 1870eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 1880eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 1890eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 1900eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 1910eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Method to process parameters from Python client 1920eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 1930eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param intent - system will provide an intent to this function 1940eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 1950eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private void processParameters(Intent intent) { 1960eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan int codecType = BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID; 1970eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan int sampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE; 1980eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan int bitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE; 1990eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan int channelMode = BluetoothCodecConfig.CHANNEL_MODE_STEREO; 2000eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan // codecSpecific1 is for LDAC quality so far 2010eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan // Other code specific values are not used now 2020eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan long codecSpecific1 = 0, codecSpecific2 = 0, codecSpecific3 = 0, 2030eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan codecSpecific4 = 0; 2043aad68c052667ec9b4c833f44432906359530da1Jim Tan int playTime = 0; 2050eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan String musicUrl; 2060eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan String tmpStr; 2073aad68c052667ec9b4c833f44432906359530da1Jim Tan 208dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti // Create the logger object 209dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti mPMCStatusLogger = new PMCStatusLogger(TAG + ".log", TAG); 210dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti 2113aad68c052667ec9b4c833f44432906359530da1Jim Tan // For a baseline case when Blueooth is off but music is playing with speaker is muted 2123aad68c052667ec9b4c833f44432906359530da1Jim Tan boolean bt_off_mute = false; 2130eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2140eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Bundle extras = intent.getExtras(); 2150eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2160eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (extras == null) { 2170eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.e(TAG, "No parameters specified"); 2180eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return; 2190eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 220dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti 221dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti if (extras.containsKey("BT_OFF_Mute")) { 222dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti Log.v(TAG, "Mute is specified for Bluetooth off baseline case"); 223dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti bt_off_mute = true; 224dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti } 225dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti 226dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti // initialize() if we are testing over Bluetooth, we do NOT test 227dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti // over bluetooth for the play music with Bluetooth off test case. 228dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti if (!bt_off_mute) { 229dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti if (!initialize()) { 230dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti mPMCStatusLogger.logStatus("initialize() Failed"); 231dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti return; 232dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti } 2330eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 2343aad68c052667ec9b4c833f44432906359530da1Jim Tan // Check if it is baseline Bluetooth is on but not stream 2353aad68c052667ec9b4c833f44432906359530da1Jim Tan if (extras.containsKey("BT_ON_NotPlay")) { 2363aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.v(TAG, "NotPlay is specified for baseline case that only Bluetooth is on"); 2373aad68c052667ec9b4c833f44432906359530da1Jim Tan // Do nothing further 2383aad68c052667ec9b4c833f44432906359530da1Jim Tan mPMCStatusLogger.logStatus("READY"); 2393aad68c052667ec9b4c833f44432906359530da1Jim Tan mPMCStatusLogger.logStatus("SUCCEED"); 2400eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return; 2410eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 2420eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2430eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (!extras.containsKey("PlayTime")) { 2440eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.e(TAG, "No Play Time specified"); 2450eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return; 2460eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 2470eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan tmpStr = extras.getString("PlayTime"); 2480eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Play Time = " + tmpStr); 2490eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan playTime = Integer.valueOf(tmpStr); 2500eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2510eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (!extras.containsKey("MusicURL")) { 2520eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.e(TAG, "No Music URL specified"); 2530eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return; 2540eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 2550eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan musicUrl = extras.getString("MusicURL"); 2560eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Music URL = " + musicUrl); 2570eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2583aad68c052667ec9b4c833f44432906359530da1Jim Tan // playTime and musicUrl are necessary 2593aad68c052667ec9b4c833f44432906359530da1Jim Tan if (playTime == 0 || musicUrl.isEmpty() || musicUrl == null) { 2600eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Invalid paramters"); 2610eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return; 2620eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 2633aad68c052667ec9b4c833f44432906359530da1Jim Tan // Check if it is the baseline that Bluetooth is off but streaming with speakers muted 264dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti if (!bt_off_mute) { 2653aad68c052667ec9b4c833f44432906359530da1Jim Tan if (!extras.containsKey("CodecType")) { 2663aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.e(TAG, "No Codec Type specified"); 2673aad68c052667ec9b4c833f44432906359530da1Jim Tan return; 2683aad68c052667ec9b4c833f44432906359530da1Jim Tan } 2693aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("CodecType"); 2703aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "Codec Type= " + tmpStr); 2713aad68c052667ec9b4c833f44432906359530da1Jim Tan codecType = Integer.valueOf(tmpStr); 2720eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2733aad68c052667ec9b4c833f44432906359530da1Jim Tan if (!extras.containsKey("SampleRate")) { 2743aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.e(TAG, "No Sample Rate specified"); 2753aad68c052667ec9b4c833f44432906359530da1Jim Tan return; 2763aad68c052667ec9b4c833f44432906359530da1Jim Tan } 2773aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("SampleRate"); 2783aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "Sample Rate = " + tmpStr); 2793aad68c052667ec9b4c833f44432906359530da1Jim Tan sampleRate = Integer.valueOf(tmpStr); 2800eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2813aad68c052667ec9b4c833f44432906359530da1Jim Tan if (!extras.containsKey("BitsPerSample")) { 2823aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.e(TAG, "No BitsPerSample specified"); 2833aad68c052667ec9b4c833f44432906359530da1Jim Tan return; 2843aad68c052667ec9b4c833f44432906359530da1Jim Tan } 2853aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("BitsPerSample"); 2863aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "BitsPerSample = " + tmpStr); 2873aad68c052667ec9b4c833f44432906359530da1Jim Tan bitsPerSample = Integer.valueOf(tmpStr); 2883aad68c052667ec9b4c833f44432906359530da1Jim Tan 2893aad68c052667ec9b4c833f44432906359530da1Jim Tan if (extras.containsKey("ChannelMode")) { 2903aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("ChannelMode"); 2913aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "ChannelMode = " + tmpStr); 2923aad68c052667ec9b4c833f44432906359530da1Jim Tan channelMode = Integer.valueOf(tmpStr); 2933aad68c052667ec9b4c833f44432906359530da1Jim Tan } 2940eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 2953aad68c052667ec9b4c833f44432906359530da1Jim Tan if (extras.containsKey("LdacPlaybackQuality")) { 2963aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("LdacPlaybackQuality"); 2973aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "LdacPlaybackQuality = " + tmpStr); 2983aad68c052667ec9b4c833f44432906359530da1Jim Tan codecSpecific1 = Integer.valueOf(tmpStr); 2993aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3000eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3013aad68c052667ec9b4c833f44432906359530da1Jim Tan if (extras.containsKey("CodecSpecific2")) { 3023aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("CodecSpecific2"); 3033aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "CodecSpecific2 = " + tmpStr); 3043aad68c052667ec9b4c833f44432906359530da1Jim Tan codecSpecific1 = Integer.valueOf(tmpStr); 305ca0b3497c93456c547da1b472d9e221ab8a13cbeJim Tan } 3060eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3073aad68c052667ec9b4c833f44432906359530da1Jim Tan if (extras.containsKey("CodecSpecific3")) { 3083aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("CodecSpecific3"); 3093aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "CodecSpecific3 = " + tmpStr); 3103aad68c052667ec9b4c833f44432906359530da1Jim Tan codecSpecific1 = Integer.valueOf(tmpStr); 3113aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3120eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3133aad68c052667ec9b4c833f44432906359530da1Jim Tan if (extras.containsKey("CodecSpecific4")) { 3143aad68c052667ec9b4c833f44432906359530da1Jim Tan tmpStr = extras.getString("CodecSpecific4"); 3153aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "CodecSpecific4 = " + tmpStr); 3163aad68c052667ec9b4c833f44432906359530da1Jim Tan codecSpecific1 = Integer.valueOf(tmpStr); 3173aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3180eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3193aad68c052667ec9b4c833f44432906359530da1Jim Tan if (codecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID 3203aad68c052667ec9b4c833f44432906359530da1Jim Tan || sampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE 3213aad68c052667ec9b4c833f44432906359530da1Jim Tan || bitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) { 322dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti Log.d(TAG, "Invalid parameters"); 3233aad68c052667ec9b4c833f44432906359530da1Jim Tan return; 3243aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3253aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3260eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3273aad68c052667ec9b4c833f44432906359530da1Jim Tan if (playMusic(musicUrl, bt_off_mute)) { 3283aad68c052667ec9b4c833f44432906359530da1Jim Tan // Set the requested Codecs on the device for normal codec cases 3293aad68c052667ec9b4c833f44432906359530da1Jim Tan if (!bt_off_mute) { 3303aad68c052667ec9b4c833f44432906359530da1Jim Tan if (!setCodecValue(codecType, sampleRate, bitsPerSample, channelMode, 3313aad68c052667ec9b4c833f44432906359530da1Jim Tan codecSpecific1, codecSpecific2, codecSpecific3, codecSpecific4)) { 3323aad68c052667ec9b4c833f44432906359530da1Jim Tan mPMCStatusLogger.logStatus("setCodecValue() Failed"); 3333aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3343aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3353aad68c052667ec9b4c833f44432906359530da1Jim Tan mPMCStatusLogger.logStatus("READY"); 3363aad68c052667ec9b4c833f44432906359530da1Jim Tan startAlarm(playTime); 3370eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } else { 3383aad68c052667ec9b4c833f44432906359530da1Jim Tan mPMCStatusLogger.logStatus("playMusic() Failed"); 3390eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 3400eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 3410eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3423aad68c052667ec9b4c833f44432906359530da1Jim Tan 3430eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 3443aad68c052667ec9b4c833f44432906359530da1Jim Tan * Function to setup MediaPlayer and play music 3450eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 3460eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param musicURL - Music URL 347dcf6ecc947983a92f6a4b1e5028c33780b58307cAndi Janti * @param btOffMute - true is to mute speakers 3480eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 3490eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 3503aad68c052667ec9b4c833f44432906359530da1Jim Tan private boolean playMusic(String musicURL, boolean btOffMute) { 3510eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3520eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mPlayer = MediaPlayer.create(mContext, Uri.parse(musicURL)); 3530eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (mPlayer == null) { 3540eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.e(TAG, "Failed to create Media Player"); 3550eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return false; 3560eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 3570eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Media Player created: " + musicURL); 3580eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3593aad68c052667ec9b4c833f44432906359530da1Jim Tan if (btOffMute) { 3603aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.v(TAG, "Mute Speakers for Bluetooth off baseline case"); 3610eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mPlayer.setVolume(ZERO_VOLUME, ZERO_VOLUME); 3620eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } else { 3630eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Set Normal Volume for speakers"); 3640eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mPlayer.setVolume(NORMAL_VOLUME, NORMAL_VOLUME); 3650eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 3663aad68c052667ec9b4c833f44432906359530da1Jim Tan // Play Music now and setup looping 3673aad68c052667ec9b4c833f44432906359530da1Jim Tan mPlayer.start(); 3683aad68c052667ec9b4c833f44432906359530da1Jim Tan mPlayer.setLooping(true); 3693aad68c052667ec9b4c833f44432906359530da1Jim Tan if (!mPlayer.isPlaying()) { 3703aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.e(TAG, "Media Player is not playing"); 3713aad68c052667ec9b4c833f44432906359530da1Jim Tan return false; 3723aad68c052667ec9b4c833f44432906359530da1Jim Tan } 3733aad68c052667ec9b4c833f44432906359530da1Jim Tan 3740eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return true; 3750eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 3760eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3770eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 3780eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Function to be called to start alarm 3790eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 3800eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param alarmStartTime - time when the music needs to be started or stopped 3810eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 3823aad68c052667ec9b4c833f44432906359530da1Jim Tan private void startAlarm(int alarmStartTime) { 3830eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3840eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Intent alarmIntent = new Intent(A2DP_INTENT); 3850eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan alarmIntent.putExtra(A2DP_ALARM, ALARM_MESSAGE); 3860eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3870eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan long triggerTime = SystemClock.elapsedRealtime() 3880eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan + alarmStartTime * THOUSAND; 3890eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mAlarmManager.setExactAndAllowWhileIdle( 3900eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerTime, 3910eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan PendingIntent.getBroadcast(mContext, 0, 3920eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT)); 3930eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 3940eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 3950eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 3960eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Function to get current codec config 3970eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param printCapabilities - Flag to indicate if to print local and selectable capabilities 3980eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 3990eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan private BluetoothCodecConfig getCodecValue(boolean printCapabilities) { 4000eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan BluetoothCodecStatus codecStatus = null; 4010eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan BluetoothCodecConfig codecConfig = null; 4020eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan BluetoothCodecConfig[] codecsLocalCapabilities = null; 4030eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan BluetoothCodecConfig[] codecsSelectableCapabilities = null; 4040eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 4050eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (mBluetoothA2dp != null) { 4060eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan codecStatus = mBluetoothA2dp.getCodecStatus(); 4070eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (codecStatus != null) { 4080eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan codecConfig = codecStatus.getCodecConfig(); 4090eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan codecsLocalCapabilities = codecStatus.getCodecsLocalCapabilities(); 4100eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan codecsSelectableCapabilities = codecStatus.getCodecsSelectableCapabilities(); 4110eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4120eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4130eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (codecConfig == null) return null; 4140eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 4150eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "GetCodecValue: " + codecConfig.toString()); 4160eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 4170eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (printCapabilities) { 4180eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Local Codec Capabilities "); 4190eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan for (BluetoothCodecConfig config : codecsLocalCapabilities) { 4200eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, config.toString()); 4210eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4220eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "Codec Selectable Capabilities: "); 4230eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan for (BluetoothCodecConfig config : codecsSelectableCapabilities) { 4240eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, config.toString()); 4250eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4260eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4270eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan return codecConfig; 4280eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4290eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 4300eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan /** 4310eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * Function to set new codec config 4320eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * 4330eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param codecType - Codec Type 4340eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param sampleRate - Sample Rate 4350eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param bitsPerSample - Bit Per Sample 4360eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param codecSpecific1 - LDAC playback quality 4370eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param codecSpecific2 - codecSpecific2 4380eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param codecSpecific3 - codecSpecific3 4390eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan * @param codecSpecific4 - codecSpecific4 4400eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan */ 4413aad68c052667ec9b4c833f44432906359530da1Jim Tan private boolean setCodecValue(int codecType, int sampleRate, int bitsPerSample, 4420eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan int channelMode, long codecSpecific1, long codecSpecific2, 4430eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan long codecSpecific3, long codecSpecific4) { 4440eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "SetCodecValue: Codec Type: " + codecType + " sampleRate: " + sampleRate 4450eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan + " bitsPerSample: " + bitsPerSample + " Channel Mode: " + channelMode 4460eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan + " LDAC quality: " + codecSpecific1); 4470eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 4480eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan BluetoothCodecConfig codecConfig = 4490eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan new BluetoothCodecConfig(codecType, BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, 4500eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan sampleRate, bitsPerSample, channelMode, 4510eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan codecSpecific1, codecSpecific2, codecSpecific3, codecSpecific4); 4520eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan 4533aad68c052667ec9b4c833f44432906359530da1Jim Tan // Wait here to see if mBluetoothA2dp is set 4543aad68c052667ec9b4c833f44432906359530da1Jim Tan for (int i = 0; i < WAIT_SECONDS; i++) { 4553aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "Wait for BluetoothA2dp"); 4563aad68c052667ec9b4c833f44432906359530da1Jim Tan if (mBluetoothA2dp != null) { 4573aad68c052667ec9b4c833f44432906359530da1Jim Tan break; 4583aad68c052667ec9b4c833f44432906359530da1Jim Tan } 4593aad68c052667ec9b4c833f44432906359530da1Jim Tan 4603aad68c052667ec9b4c833f44432906359530da1Jim Tan try { 4613aad68c052667ec9b4c833f44432906359530da1Jim Tan Thread.sleep(THOUSAND); 4623aad68c052667ec9b4c833f44432906359530da1Jim Tan } catch (InterruptedException e) { 4633aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "Sleep is interrupted"); 4643aad68c052667ec9b4c833f44432906359530da1Jim Tan } 4653aad68c052667ec9b4c833f44432906359530da1Jim Tan } 4663aad68c052667ec9b4c833f44432906359530da1Jim Tan 4670eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan if (mBluetoothA2dp != null) { 4680eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.d(TAG, "setCodecConfigPreference()"); 4690eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan mBluetoothA2dp.setCodecConfigPreference(codecConfig); 4700eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } else { 4710eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan Log.e(TAG, "mBluetoothA2dp is null. Codec is not set"); 4723aad68c052667ec9b4c833f44432906359530da1Jim Tan return false; 4733aad68c052667ec9b4c833f44432906359530da1Jim Tan } 4743aad68c052667ec9b4c833f44432906359530da1Jim Tan // Wait here to see if the codec is changed to new value 4753aad68c052667ec9b4c833f44432906359530da1Jim Tan for (int i = 0; i < WAIT_SECONDS; i++) { 4763aad68c052667ec9b4c833f44432906359530da1Jim Tan if (verifyCodeConfig(codecType, sampleRate, 4773aad68c052667ec9b4c833f44432906359530da1Jim Tan bitsPerSample, channelMode, codecSpecific1)) { 4783aad68c052667ec9b4c833f44432906359530da1Jim Tan break; 4793aad68c052667ec9b4c833f44432906359530da1Jim Tan } 4803aad68c052667ec9b4c833f44432906359530da1Jim Tan try { 4813aad68c052667ec9b4c833f44432906359530da1Jim Tan Thread.sleep(THOUSAND); 4823aad68c052667ec9b4c833f44432906359530da1Jim Tan } catch (InterruptedException e) { 4833aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.d(TAG, "Sleep is interrupted"); 4843aad68c052667ec9b4c833f44432906359530da1Jim Tan } 4853aad68c052667ec9b4c833f44432906359530da1Jim Tan } 4863aad68c052667ec9b4c833f44432906359530da1Jim Tan if (!verifyCodeConfig(codecType, sampleRate, 4873aad68c052667ec9b4c833f44432906359530da1Jim Tan bitsPerSample, channelMode, codecSpecific1)) { 4883aad68c052667ec9b4c833f44432906359530da1Jim Tan Log.e(TAG, "Codec config is NOT set correctly"); 4893aad68c052667ec9b4c833f44432906359530da1Jim Tan return false; 4900eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4913aad68c052667ec9b4c833f44432906359530da1Jim Tan return true; 4920eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan } 4933aad68c052667ec9b4c833f44432906359530da1Jim Tan 4943aad68c052667ec9b4c833f44432906359530da1Jim Tan /** 4953aad68c052667ec9b4c833f44432906359530da1Jim Tan * Method to verify if the codec config values are changed 4963aad68c052667ec9b4c833f44432906359530da1Jim Tan * 4973aad68c052667ec9b4c833f44432906359530da1Jim Tan * @param codecType - Codec Type 4983aad68c052667ec9b4c833f44432906359530da1Jim Tan * @param sampleRate - Sample Rate 4993aad68c052667ec9b4c833f44432906359530da1Jim Tan * @param bitsPerSample - Bit Per Sample 5003aad68c052667ec9b4c833f44432906359530da1Jim Tan * @param codecSpecific1 - LDAC playback quality 5013aad68c052667ec9b4c833f44432906359530da1Jim Tan */ 5023aad68c052667ec9b4c833f44432906359530da1Jim Tan private boolean verifyCodeConfig(int codecType, int sampleRate, int bitsPerSample, 5033aad68c052667ec9b4c833f44432906359530da1Jim Tan int channelMode, long codecSpecific1) { 5043aad68c052667ec9b4c833f44432906359530da1Jim Tan BluetoothCodecConfig codecConfig = null; 5053aad68c052667ec9b4c833f44432906359530da1Jim Tan codecConfig = getCodecValue(false); 5063aad68c052667ec9b4c833f44432906359530da1Jim Tan if (codecConfig == null) return false; 5073aad68c052667ec9b4c833f44432906359530da1Jim Tan 5083aad68c052667ec9b4c833f44432906359530da1Jim Tan if (codecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) { 5093aad68c052667ec9b4c833f44432906359530da1Jim Tan if (codecConfig.getCodecType() == codecType 5103aad68c052667ec9b4c833f44432906359530da1Jim Tan && codecConfig.getSampleRate() == sampleRate 5113aad68c052667ec9b4c833f44432906359530da1Jim Tan && codecConfig.getBitsPerSample() == bitsPerSample 5123aad68c052667ec9b4c833f44432906359530da1Jim Tan && codecConfig.getChannelMode() == channelMode 5133aad68c052667ec9b4c833f44432906359530da1Jim Tan && codecConfig.getCodecSpecific1() == codecSpecific1) return true; 5143aad68c052667ec9b4c833f44432906359530da1Jim Tan } else { 5153aad68c052667ec9b4c833f44432906359530da1Jim Tan if (codecConfig.getCodecType() == codecType 5163aad68c052667ec9b4c833f44432906359530da1Jim Tan && codecConfig.getSampleRate() == sampleRate 5173aad68c052667ec9b4c833f44432906359530da1Jim Tan && codecConfig.getBitsPerSample() == bitsPerSample 5183aad68c052667ec9b4c833f44432906359530da1Jim Tan && codecConfig.getChannelMode() == channelMode) return true; 5193aad68c052667ec9b4c833f44432906359530da1Jim Tan } 5203aad68c052667ec9b4c833f44432906359530da1Jim Tan 5213aad68c052667ec9b4c833f44432906359530da1Jim Tan return false; 5223aad68c052667ec9b4c833f44432906359530da1Jim Tan } 5233aad68c052667ec9b4c833f44432906359530da1Jim Tan 5240eef78fec19807c7f0223f90ca235e10e6f5ea61Jim Tan} 525