blob: 9bb9b28c6902d8c9f3e2e5d5420795d6a66b88d9 [file] [log] [blame]
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301/*
Satish kumar sugasieead6722016-10-18 14:47:46 -07002 * Copyright (c) 2009-2016, The Linux Foundation. All rights reserved.
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of The Linux Foundation nor
12 * the names of its contributors may be used to endorse or promote
13 * products derived from this software without specific prior written
14 * permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29package com.caf.fmradio;
30
31import java.io.File;
32import java.util.*;
33import java.io.IOException;
34import java.lang.ref.WeakReference;
35
36import android.app.AlarmManager;
37import android.app.Notification;
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +053038import android.app.NotificationChannel;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +053039import android.app.NotificationManager;
40import android.app.PendingIntent;
41import android.app.Service;
42import android.content.Context;
43import android.content.Intent;
44import android.content.IntentFilter;
Venkateshwarlu Domakondafa22ae12013-07-27 12:25:16 +053045import android.app.IntentService;
46import android.os.UserHandle;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +053047import android.content.BroadcastReceiver;
48import android.media.AudioManager;
49import android.media.AudioManager.OnAudioFocusChangeListener;
50import android.media.AudioSystem;
51import android.media.MediaRecorder;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +053052import android.media.AudioDevicePort;
53import android.media.AudioDevicePortConfig;
54import android.media.AudioFormat;
55import android.media.AudioManager.OnAudioPortUpdateListener;
56import android.media.AudioMixPort;
57import android.media.AudioPatch;
58import android.media.AudioPort;
59import android.media.AudioPortConfig;
60import android.media.AudioRecord;
61import android.media.AudioTrack;
himta rambff94f22018-06-05 11:03:21 +053062import android.media.AudioDeviceInfo;
himta ramdfa45932019-03-07 17:57:54 +053063import android.media.AudioAttributes;
64import android.media.AudioFocusRequest;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +053065
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +053066import android.os.Environment;
67import android.os.Handler;
68import android.os.IBinder;
69import android.os.Message;
70import android.os.PowerManager;
71import android.os.PowerManager.WakeLock;
72import android.os.RemoteException;
73import android.telephony.PhoneStateListener;
74import android.telephony.TelephonyManager;
75import android.util.Log;
76import android.widget.RemoteViews;
77import android.widget.Toast;
78import android.view.KeyEvent;
79import android.os.SystemProperties;
80
81import qcom.fmradio.FmReceiver;
82import qcom.fmradio.FmRxEvCallbacksAdaptor;
83import qcom.fmradio.FmRxRdsData;
84import qcom.fmradio.FmConfig;
85import android.net.Uri;
86import android.content.res.Resources;
87import java.util.Date;
88import java.text.SimpleDateFormat;
89import android.provider.MediaStore;
90import android.content.ContentResolver;
91import android.content.ContentValues;
92import android.database.Cursor;
93import com.caf.utils.A2dpDeviceStatus;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +053094import android.content.ComponentName;
95import android.os.StatFs;
96import android.os.SystemClock;
Ayaz Ahmad5d19b1b2013-09-05 16:53:09 +053097import android.os.Process;
98import android.app.ActivityManager;
99import android.app.ActivityManager.RunningAppProcessInfo;
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +0530100import android.media.session.MediaSession;
AnubhavGupta5059e772018-07-23 18:21:36 +0530101import android.media.AudioRouting;
Rupesh Tatiya5ed72802015-11-30 15:40:46 +0530102import android.bluetooth.BluetoothA2dp;
103import android.bluetooth.BluetoothProfile;
104import android.bluetooth.BluetoothAdapter;
105import android.bluetooth.BluetoothDevice;
Balvinder Singh7b765532017-08-04 15:45:28 +0530106import android.os.IBinder.DeathRecipient;
Smriti Guptaab10c8b2017-09-06 16:48:48 +0530107import android.content.SharedPreferences;
108import android.content.SharedPreferences.Editor;
himta ram43bf6232018-11-02 11:16:37 +0530109import java.lang.Math;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530110
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530111
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530112/**
113 * Provides "background" FM Radio (that uses the hardware) capabilities,
114 * allowing the user to switch between activities without stopping playback.
115 */
116public class FMRadioService extends Service
117{
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530118 private static final int FMRADIOSERVICE_STATUS = 101;
119 private static final String FMRADIO_DEVICE_FD_STRING = "/dev/radio0";
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +0530120 private static final String FMRADIO_NOTIFICATION_CHANNEL = "fmradio_notification_channel";
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530121 private static final String LOGTAG = "FMService";//FMRadio.LOGTAG;
122
123 private FmReceiver mReceiver;
himta rambe1ab412018-11-22 13:28:00 +0530124 private final Object mReceiverLock = new Object();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530125 private BroadcastReceiver mHeadsetReceiver = null;
126 private BroadcastReceiver mSdcardUnmountReceiver = null;
127 private BroadcastReceiver mMusicCommandListener = null;
128 private BroadcastReceiver mSleepExpiredListener = null;
Ayaz Ahmad594e34a2013-09-12 17:04:29 +0530129 private boolean mSleepActive = false;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530130 private BroadcastReceiver mRecordTimeoutListener = null;
131 private BroadcastReceiver mDelayedServiceStopListener = null;
Venkateshwarlu Domakondafd50fd42014-04-18 12:36:13 +0530132 private BroadcastReceiver mAudioBecomeNoisyListener = null;
Smriti Guptaab10c8b2017-09-06 16:48:48 +0530133 private SharedPreferences mPref = null;
134 private Editor mEditor = null;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530135 private boolean mOverA2DP = false;
136 private BroadcastReceiver mFmMediaButtonListener;
Venkateshwarlu Domakondae8d7acf2015-04-06 19:01:37 +0530137 private BroadcastReceiver mAirplaneModeChanged;
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530138 private BroadcastReceiver mRegisterUserSwitched;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530139 private IFMRadioServiceCallbacks mCallbacks;
140 private static FmSharedPreferences mPrefs;
141 private boolean mHeadsetPlugged = false;
142 private boolean mInternalAntennaAvailable = false;
143 private WakeLock mWakeLock;
144 private int mServiceStartId = -1;
145 private boolean mServiceInUse = false;
146 private static boolean mMuted = false;
Edward Wang6844bc52015-04-09 16:06:02 -0700147 private static int mFreq = 0;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530148 private static boolean mResumeAfterCall = false;
himta ram046d5c32019-01-10 15:42:34 +0530149 private static int mAudioDevice = AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530150 MediaRecorder mRecorder = null;
151 MediaRecorder mA2dp = null;
152 private boolean mFMOn = false;
153 private boolean mFmRecordingOn = false;
Venkateshwarlu Domakondad09c0882015-05-26 15:16:38 +0530154 private static boolean mRtPlusSupport = false;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530155 private boolean mSpeakerPhoneOn = false;
156 private int mCallStatus = 0;
157 private BroadcastReceiver mScreenOnOffReceiver = null;
158 final Handler mHandler = new Handler();
159 private boolean misAnalogModeSupported = false;
160 private boolean misAnalogPathEnabled = false;
161 private boolean mA2dpDisconnected = false;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530162 private boolean mA2dpConnected = false;
Balvinder Singh7b765532017-08-04 15:45:28 +0530163
164 //Install the death receipient
165 private IBinder.DeathRecipient mDeathRecipient;
166 private FMDeathRecipient mFMdr;
167
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530168 //PhoneStateListener instances corresponding to each
Danesh M94cab4e2015-08-19 15:43:48 -0700169 private ArrayList<Integer> mScannedFrequencies = new ArrayList<Integer>();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530170
171 private FmRxRdsData mFMRxRDSData=null;
172 // interval after which we stop the service when idle
173 private static final int IDLE_DELAY = 60000;
174 private File mA2DPSampleFile = null;
175 //Track FM playback for reenter App usecases
176 private boolean mPlaybackInProgress = false;
Mingbo Zhange579ce12017-01-13 10:53:00 +0800177 private boolean mStoppedOnFocusLoss = true;
Kamal Negidd175dc2016-06-03 20:09:24 +0530178 private boolean mStoppedOnFactoryReset = false;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530179 private File mSampleFile = null;
180 long mSampleStart = 0;
Smriti Guptada03ddb2016-08-03 16:11:05 +0530181 int mSampleLength = 0;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530182 // Messages handled in FM Service
183 private static final int FM_STOP =1;
184 private static final int RESET_NOTCH_FILTER =2;
185 private static final int STOPSERVICE_ONSLEEP = 3;
186 private static final int STOPRECORD_ONTIMEOUT = 4;
187 private static final int FOCUSCHANGE = 5;
188 //Track notch filter settings
189 private boolean mNotchFilterSet = false;
190 public static final int STOP_SERVICE = 0;
191 public static final int STOP_RECORD = 1;
192 // A2dp Device Status will be queried through this class
193 A2dpDeviceStatus mA2dpDeviceState = null;
194 private boolean mA2dpDeviceSupportInHal = false;
195 //on shutdown not to send start Intent to AudioManager
196 private boolean mAppShutdown = false;
197 private boolean mSingleRecordingInstanceSupported = false;
198 private AudioManager mAudioManager;
199 public static final long UNAVAILABLE = -1L;
200 public static final long PREPARING = -2L;
201 public static final long UNKNOWN_SIZE = -3L;
202 public static final long LOW_STORAGE_THRESHOLD = 50000000;
203 private long mStorageSpace;
204 private static final String IOBUSY_UNVOTE = "com.android.server.CpuGovernorService.action.IOBUSY_UNVOTE";
205 private static final String SLEEP_EXPIRED_ACTION = "com.caf.fmradio.SLEEP_EXPIRED";
206 private static final String RECORD_EXPIRED_ACTION = "com.caf.fmradio.RECORD_TIMEOUT";
207 private static final String SERVICE_DELAYED_STOP_ACTION = "com.caf.fmradio.SERVICE_STOP";
Venkateshwarlu Domakondafa22ae12013-07-27 12:25:16 +0530208 public static final String ACTION_FM =
209 "codeaurora.intent.action.FM";
210 public static final String ACTION_FM_RECORDING =
211 "codeaurora.intent.action.FM_Recording";
212 public static final String ACTION_FM_RECORDING_STATUS =
213 "codeaurora.intent.action.FM.Recording.Status";
214 private BroadcastReceiver mFmRecordingStatus = null;
Satish Kodishala46c9bf62014-03-04 20:22:52 +0530215 private Thread mRecordServiceCheckThread = null;
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +0530216 private MediaSession mSession;
Satish Kodishala454dd9e2014-11-20 15:34:46 +0530217 private boolean mIsSSRInProgress = false;
218 private boolean mIsSSRInProgressFromActivity = false;
Hu Wangb80e8482015-04-08 14:36:46 +0800219 private int mKeyActionDownCount = 0;
himta ramdfa45932019-03-07 17:57:54 +0530220
Erfan Abdi60258312019-08-21 17:25:21 +0430221 private Thread mRecordSinkThread = null;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530222 private AudioTrack mAudioTrack = null;
Erfan Abdi60258312019-08-21 17:25:21 +0430223 private boolean mIsRecordSink = false;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530224 private static final int AUDIO_FRAMES_COUNT_TO_IGNORE = 3;
Kamal Negi3d3cdea2016-06-27 19:54:56 +0530225 private Object mEventWaitLock = new Object();
Dhananjay Kumard3f90872015-10-21 15:10:06 +0530226 private boolean mIsFMDeviceLoopbackActive = false;
Erfan Abdi60258312019-08-21 17:25:21 +0430227 private Object mRecordSinkLock = new Object();
Rupesh Tatiya9a50d9a2016-01-19 21:54:49 +0530228 private File mStoragePath = null;
Rupesh Tatiyafd07e802015-11-04 17:51:44 +0530229 private static final int FM_OFF_FROM_APPLICATION = 1;
230 private static final int FM_OFF_FROM_ANTENNA = 2;
Kamal Negi3d3cdea2016-06-27 19:54:56 +0530231 private static final int RADIO_TIMEOUT = 1500;
Smriti Guptaab10c8b2017-09-06 16:48:48 +0530232 private static final int FW_TIMEOUT = 200;
Rupesh Tatiya9917f922017-06-21 13:00:43 +0530233 private static final int DISABLE_SLIMBUS_DATA_PORT = 0;
234 private static final int ENABLE_SLIMBUS_DATA_PORT = 1;
himta ram56984632018-03-19 13:07:29 +0530235 private static final int DISABLE_SOFT_MUTE = 0;
236 private static final int ENABLE_SOFT_MUTE = 1;
himta ram198e3282019-06-13 14:57:47 +0530237 private static final int DEFAULT_VOLUME_INDEX = 6;
Rupesh Tatiya8d881502016-01-12 18:37:31 +0530238 private static Object mNotchFilterLock = new Object();
himta ram5c7f7db2018-06-05 16:25:55 +0530239 private static Object mNotificationLock = new Object();
Rupesh Tatiya8d881502016-01-12 18:37:31 +0530240
Kamal Negi6c3e6892017-03-15 14:05:32 +0530241 private boolean mEventReceived = false;
himta rame628c052018-07-06 20:26:48 +0530242 private boolean isfmOffFromApplication = false;
himta ramdfa45932019-03-07 17:57:54 +0530243 private AudioFocusRequest mGainFocusReq;
Kamal Negic5a78e22017-02-24 12:16:54 +0530244
Erfan Abdi60258312019-08-21 17:25:21 +0430245 private AudioRoutingListener mRoutingListener = null;
246 private int mCurrentDevice = AudioDeviceInfo.TYPE_UNKNOWN; // current output device
247 private boolean mUseAudioSession = false;
248
249 private static final int AUDIO_SAMPLE_RATE = 44100;
250 private static final int AUDIO_CHANNEL_CONFIG =
251 AudioFormat.CHANNEL_CONFIGURATION_STEREO;
252 private static final int AUDIO_ENCODING_FORMAT =
253 AudioFormat.ENCODING_PCM_16BIT;
254 private static final int FM_RECORD_BUF_SIZE =
255 AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE,
256 AUDIO_CHANNEL_CONFIG, AUDIO_ENCODING_FORMAT);
257 private AudioRecord mAudioRecord = null;
258
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530259 public FMRadioService() {
260 }
261
262 @Override
263 public void onCreate() {
264 super.onCreate();
265
Smriti Guptaab10c8b2017-09-06 16:48:48 +0530266 mPref = getApplicationContext().getSharedPreferences("SlimbusPref", MODE_PRIVATE);
267 mEditor = mPref.edit();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530268 mPrefs = new FmSharedPreferences(this);
269 mCallbacks = null;
270 TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
271 tmgr.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE |
272 PhoneStateListener.LISTEN_DATA_ACTIVITY);
273 PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
274 mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName());
275 mWakeLock.setReferenceCounted(false);
276 misAnalogModeSupported = SystemProperties.getBoolean("ro.fm.analogpath.supported",false);
277 /* Register for Screen On/off broadcast notifications */
278 mA2dpDeviceState = new A2dpDeviceStatus(getApplicationContext());
279 registerScreenOnOffListener();
280 registerHeadsetListener();
281 registerSleepExpired();
282 registerRecordTimeout();
283 registerDelayedServiceStop();
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530284 registerExternalStorageListener();
Venkateshwarlu Domakondae8d7acf2015-04-06 19:01:37 +0530285 registerAirplaneModeStatusChanged();
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530286 registerUserSwitch();
himta ramd1e2dd02018-07-30 16:05:29 +0530287 registerAudioBecomeNoisy();
Rupesh Tatiyafd07e802015-11-04 17:51:44 +0530288
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +0530289 mSession = new MediaSession(getApplicationContext(), this.getClass().getName());
290 mSession.setCallback(mSessionCallback);
himta ramdfa45932019-03-07 17:57:54 +0530291 mSession.setFlags(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530292 if ( false == SystemProperties.getBoolean("ro.fm.mulinst.recording.support",true)) {
293 mSingleRecordingInstanceSupported = true;
294 }
295
296 // Register for pause commands from other apps to stop FM
297 registerMusicServiceCommandReceiver();
298
299 // If the service was idle, but got killed before it stopped itself, the
300 // system will relaunch it. Make sure it gets stopped again in that case.
301 setAlarmDelayedServiceStop();
302 /* Query to check is a2dp supported in Hal */
303 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
304 String valueStr = audioManager.getParameters("isA2dpDeviceSupported");
305 mA2dpDeviceSupportInHal = valueStr.contains("=true");
306 Log.d(LOGTAG, " is A2DP device Supported In HAL"+mA2dpDeviceSupportInHal);
Rupesh Tatiya5ed72802015-11-30 15:40:46 +0530307
Erfan Abdi60258312019-08-21 17:25:21 +0430308 mUseAudioSession = SystemProperties.getBoolean("ro.vendor.fm.use_audio_session", false);
309 if (mUseAudioSession)
310 mRoutingListener = new AudioRoutingListener();
himta ramdfa45932019-03-07 17:57:54 +0530311 mGainFocusReq = requestAudioFocus();
himta ram1e6791a2019-05-27 15:56:37 +0530312 AudioManager mAudioManager =
313 (AudioManager) getSystemService(Context.AUDIO_SERVICE);
314 AudioDeviceInfo[] deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
315 for (int index = 0; index < deviceList.length; index++) {
316 if ((deviceList[index].getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET ) ||
317 (deviceList[index].getType() == AudioDeviceInfo.TYPE_WIRED_HEADPHONES )){
318 mHeadsetPlugged = true;
319 break;
320 }
321 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530322 }
323
324 @Override
325 public void onDestroy() {
326 Log.d(LOGTAG, "onDestroy");
327 if (isFmOn())
328 {
himta ramda7c84e2020-02-12 12:24:24 +0530329 Log.e(LOGTAG, "FMRadio Service being destroyed");
330 /* Since the service is closing, disable the receiver */
331 fmOff();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530332 }
333
334 // make sure there aren't any other messages coming
335 mDelayedStopHandler.removeCallbacksAndMessages(null);
336 cancelAlarms();
337 //release the audio focus listener
338 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
himta ramdfa45932019-03-07 17:57:54 +0530339 audioManager.abandonAudioFocusRequest(mGainFocusReq);
340 mGainFocusReq = null;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530341 /* Remove the Screen On/off listener */
342 if (mScreenOnOffReceiver != null) {
343 unregisterReceiver(mScreenOnOffReceiver);
344 mScreenOnOffReceiver = null;
345 }
346 /* Unregister the headset Broadcase receiver */
347 if (mHeadsetReceiver != null) {
348 unregisterReceiver(mHeadsetReceiver);
349 mHeadsetReceiver = null;
350 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530351 if( mMusicCommandListener != null ) {
352 unregisterReceiver(mMusicCommandListener);
353 mMusicCommandListener = null;
354 }
355 if( mFmMediaButtonListener != null ) {
356 unregisterReceiver(mFmMediaButtonListener);
357 mFmMediaButtonListener = null;
358 }
Venkateshwarlu Domakondafd50fd42014-04-18 12:36:13 +0530359 if (mAudioBecomeNoisyListener != null) {
360 unregisterReceiver(mAudioBecomeNoisyListener);
361 mAudioBecomeNoisyListener = null;
362 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530363 if (mSleepExpiredListener != null ) {
364 unregisterReceiver(mSleepExpiredListener);
365 mSleepExpiredListener = null;
366 }
367 if (mRecordTimeoutListener != null) {
368 unregisterReceiver(mRecordTimeoutListener);
369 mRecordTimeoutListener = null;
370 }
371 if (mDelayedServiceStopListener != null) {
372 unregisterReceiver(mDelayedServiceStopListener);
373 mDelayedServiceStopListener = null;
374 }
Venkateshwarlu Domakondafa22ae12013-07-27 12:25:16 +0530375 if (mFmRecordingStatus != null ) {
376 unregisterReceiver(mFmRecordingStatus);
377 mFmRecordingStatus = null;
378 }
Venkateshwarlu Domakondae8d7acf2015-04-06 19:01:37 +0530379 if (mAirplaneModeChanged != null) {
380 unregisterReceiver(mAirplaneModeChanged);
381 mAirplaneModeChanged = null;
382 }
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530383 if( mSdcardUnmountReceiver != null ) {
384 unregisterReceiver(mSdcardUnmountReceiver);
385 mSdcardUnmountReceiver = null;
386 }
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530387 if (mRegisterUserSwitched != null) {
388 unregisterReceiver(mRegisterUserSwitched);
389 mRegisterUserSwitched = null;
390 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530391
392 TelephonyManager tmgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
393 tmgr.listen(mPhoneStateListener, 0);
394
395 Log.d(LOGTAG, "onDestroy: unbindFromService completed");
396
397 //unregisterReceiver(mIntentReceiver);
398 mWakeLock.release();
399 super.onDestroy();
400 }
401
Erfan Abdi60258312019-08-21 17:25:21 +0430402 private synchronized void CreateRecordSessions() {
403
404 if (mAudioRecord != null) {
405 mAudioRecord.stop();
406 }
407 if (mAudioTrack != null) {
408 mAudioTrack.stop();
409 }
410 mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.RADIO_TUNER,
411 AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_CONFIG,
412 AUDIO_ENCODING_FORMAT, FM_RECORD_BUF_SIZE);
413
414 mAudioTrack = new AudioTrack.Builder()
415 .setAudioFormat(new AudioFormat.Builder()
416 .setEncoding(AUDIO_ENCODING_FORMAT)
417 .setSampleRate(AUDIO_SAMPLE_RATE)
418 .setChannelIndexMask(AUDIO_CHANNEL_CONFIG)
419 .build())
420 .setBufferSizeInBytes(FM_RECORD_BUF_SIZE)
421 .build();
422 Log.d(LOGTAG," adding RoutingChangedListener() ");
423 mAudioTrack.addOnRoutingChangedListener(mRoutingListener, null);
424
425 if (mMuted)
426 mAudioTrack.setVolume(0.0f);
427 }
428
429 private synchronized void startRecordSink() {
430 Log.d(LOGTAG, "startRecordSink "
431 + AudioSystem.getForceUse(AudioSystem.FOR_MEDIA));
432
433 mIsRecordSink = true;
434 createRecordSinkThread();
435
436 }
437
438 private synchronized void createRecordSinkThread() {
439 if (mRecordSinkThread == null) {
440 mRecordSinkThread = new RecordSinkThread();
441 mRecordSinkThread.start();
442 Log.d(LOGTAG, "mRecordSinkThread started");
443 try {
444 synchronized (mRecordSinkLock) {
445 Log.d(LOGTAG, "waiting for play to complete");
446 mRecordSinkLock.wait();
447 }
448 } catch (InterruptedException e) {
449 e.printStackTrace();
450 }
451 if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
452 enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
453 }
454 }
455 }
456
457 private synchronized void exitRecordSinkThread() {
458 if(isRecordSinking()) {
459 Log.d(LOGTAG, "stopRecordSink");
460 mAudioTrack.setPreferredDevice(null);
461 mIsRecordSink = false;
462 } else {
463 Log.d(LOGTAG, "exitRecordSinkThread called mRecordSinkThread not running");
464 return;
465 }
466 try {
467 Log.d(LOGTAG, "stopRecordSink waiting to join mRecordSinkThread");
468 mRecordSinkThread.join();
469 } catch (InterruptedException e) {
470 Log.d(LOGTAG, "Exceprion while mRecordSinkThread join");
471 }
472 mRecordSinkThread = null;
473 mAudioTrack = null;
474 mAudioRecord = null;
475 Log.d(LOGTAG, "exitRecordSinkThread completed");
476 }
477
478 private boolean isRecordSinking() {
479 return mIsRecordSink;
480 }
481
482 class RecordSinkThread extends Thread {
483 private int mCurrentFrame = 0;
484 private boolean isAudioFrameNeedIgnore() {
485 return mCurrentFrame < AUDIO_FRAMES_COUNT_TO_IGNORE;
486 }
487
488 @Override
489 public void run() {
490 try {
491 Log.d(LOGTAG, "RecordSinkThread: run started ");
492 byte[] buffer = new byte[FM_RECORD_BUF_SIZE];
493 while (isRecordSinking()) {
494 // Speaker mode or BT a2dp mode will come here and keep reading and writing.
495 // If we want FM sound output from speaker or BT a2dp, we must record data
496 // to AudioRecrd and write data to AudioTrack.
497 if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED) {
498 mAudioRecord.startRecording();
499 Log.d(LOGTAG, "RecordSinkThread: mAudioRecord.startRecording started");
500 }
501
502 if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_STOPPED) {
503 Log.d(LOGTAG, "RecordSinkThread: mAudioTrack.play executed");
504 mAudioTrack.play();
505 Log.d(LOGTAG, "RecordSinkThread: mAudioTrack.play completed");
506 synchronized (mRecordSinkLock) {
507 mRecordSinkLock.notify();
508 }
509 }
510 int size = mAudioRecord.read(buffer, 0, FM_RECORD_BUF_SIZE);
511 // check whether need to ignore first 3 frames audio data from AudioRecord
512 // to avoid pop noise.
513 if (isAudioFrameNeedIgnore()) {
514 mCurrentFrame += 1;
515 continue ;
516 }
517 if (size <= 0) {
518 Log.e(LOGTAG, "RecordSinkThread read data from AudioRecord "
519 + "error size: " + size);
520 continue;
521 }
522 byte[] tmpBuf = new byte[size];
523 System.arraycopy(buffer, 0, tmpBuf, 0, size);
524 // Check again to avoid noises, because RecordSink may be changed
525 // while AudioRecord is reading.
526 if (isRecordSinking()) {
527 mAudioTrack.write(tmpBuf, 0, tmpBuf.length);
528 } else {
529 mCurrentFrame = 0;
530 Log.d(LOGTAG, "RecordSinkThread: stopRecordSink called stopping mAudioTrack and mAudioRecord ");
531 break;
532 }
533 }
534 } catch (Exception e) {
535 Log.d(LOGTAG, "RecordSinkThread.run, thread is interrupted, need exit thread");
536 } finally {
537 Log.d(LOGTAG, "RecordSinkThread: stopRecordSink called stopping mAudioTrack and mAudioRecord ");
538 if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {
539 Log.d(LOGTAG, "RecordSinkThread: mAudioRecord.stop()");
540 mAudioRecord.stop();
541 Log.d(LOGTAG, "RecordSinkThread: mAudioRecord.stop() completed");
542 mAudioRecord.release();
543 Log.d(LOGTAG, "RecordSinkThread: mAudioRecord.release() completed");
544 }
545 if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
546 Log.d(LOGTAG, "RecordSinkThread: mAudioTrack.stop();");
547 mAudioTrack.stop();
548 Log.d(LOGTAG, "RecordSinkThread:mAudioTrack.stop() completed");
549 mAudioTrack.release();
550 Log.d(LOGTAG, "RecordSinkThread: mAudioTrack.release() completed");
551 }
552 }
553 }
554 }
555
himta ram43bf6232018-11-02 11:16:37 +0530556 private void setFMVolume(int mCurrentVolumeIndex) {
557 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
558 float decibels = audioManager.getStreamVolumeDb(AudioManager.STREAM_MUSIC,
559 mCurrentVolumeIndex,mAudioDevice);
560 /* DbToAmpl */
561 float volume = (float)Math.exp(decibels * 0.115129f);
562 Log.d(LOGTAG, "setFMVolume mCurrentVolumeIndex = "+
563 mCurrentVolumeIndex + " volume = " + volume);
564 String keyValPairs = new String("fm_volume="+volume);
565 Log.d(LOGTAG, "keyValPairs = "+keyValPairs);
566 audioManager.setParameters(keyValPairs);
himta rambff94f22018-06-05 11:03:21 +0530567
himta ram43bf6232018-11-02 11:16:37 +0530568 }
569 private boolean configureFMDeviceLoopback(boolean enable) {
570 Log.d(LOGTAG, "configureFMDeviceLoopback enable = " + enable +
571 " DeviceLoopbackActive = " + mIsFMDeviceLoopbackActive +
572 " mStoppedOnFocusLoss = "+mStoppedOnFocusLoss);
573 int mAudioDeviceType;
himta ram3a615df2019-01-10 16:00:51 +0530574
himta ram43bf6232018-11-02 11:16:37 +0530575 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
576 if(enable) {
577 if(mIsFMDeviceLoopbackActive || mStoppedOnFocusLoss) {
578 Log.d(LOGTAG, "either FM does not have audio focus"+
579 "or Already devcie loop back is acive, not enabling audio");
580 return false;
himta rama1c405b2018-07-11 17:13:56 +0530581 }
himta ramc65cc462018-12-18 16:54:45 +0530582 String status = audioManager.getParameters("fm_status");
583 Log.d(LOGTAG," FM hardwareLoopback Status = " + status);
584 if (status.contains("1")) {
585 /* This case usually happens, when FM is force killed through settings app
586 * and we don't get chance to disable Hardware LoopBack.
587 * Hardware LoopBack will be running,disable it first and enable again
588 * using routing set param to audio */
589 Log.d(LOGTAG," FM HardwareLoopBack Active, disable it first and enable again");
590 mAudioDeviceType =
591 AudioDeviceInfo.TYPE_WIRED_HEADPHONES | AudioSystem.DEVICE_OUT_FM;
592 String keyValPairs = new String("fm_routing="+mAudioDeviceType);
593 Log.d(LOGTAG, "keyValPairs = "+keyValPairs);
594 audioManager.setParameters(keyValPairs);
595 }
himta ram43bf6232018-11-02 11:16:37 +0530596 mIsFMDeviceLoopbackActive = true;
597 /*or with DEVICE_OUT_FM to support backward compatiblity*/
598 mAudioDeviceType = mAudioDevice | AudioSystem.DEVICE_OUT_FM;
599 int mCurrentVolumeIndex = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
600 setFMVolume(mCurrentVolumeIndex);
Luca Weiss17e054b2021-07-29 09:05:38 +0200601
602 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
603 AudioSystem.DEVICE_STATE_AVAILABLE, "", "",
604 AudioSystem.AUDIO_FORMAT_DEFAULT);
himta ram43bf6232018-11-02 11:16:37 +0530605 } else if (mIsFMDeviceLoopbackActive == false) {
606 Log.d(LOGTAG, "no devcie loop back is active, not disabling the audio");
607 return false;
himta ram49c98492018-06-14 15:08:50 +0530608 } else {
himta ram43bf6232018-11-02 11:16:37 +0530609 /*disabling the fm audio*/
Dhananjay Kumard3f90872015-10-21 15:10:06 +0530610 mIsFMDeviceLoopbackActive = false;
himta ram43bf6232018-11-02 11:16:37 +0530611 mAudioDeviceType = mAudioDevice;
Luca Weiss17e054b2021-07-29 09:05:38 +0200612
613 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
614 AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "",
615 AudioSystem.AUDIO_FORMAT_DEFAULT);
Dhananjay Kumard3f90872015-10-21 15:10:06 +0530616 }
himta ram43bf6232018-11-02 11:16:37 +0530617 String keyValPairs = new String("handle_fm="+mAudioDeviceType);
618 Log.d(LOGTAG, "keyValPairs = "+keyValPairs);
619 audioManager.setParameters(keyValPairs);
Dhananjay Kumard3f90872015-10-21 15:10:06 +0530620
himta ram43bf6232018-11-02 11:16:37 +0530621 return true;
Dhananjay Kumard3f90872015-10-21 15:10:06 +0530622 }
623
Erfan Abdi60258312019-08-21 17:25:21 +0430624 private boolean configureFMDeviceLoopback_O(boolean enable) {
625 boolean success = true;
626 int status = AudioSystem.SUCCESS;
627
628 Log.d(LOGTAG, "configureFMDeviceLoopback enable:" + enable +
629 " DeviceLoopbackActive:" + mIsFMDeviceLoopbackActive);
630 if (enable && mIsFMDeviceLoopbackActive == false) {
631 status = AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,"");
632 Log.d(LOGTAG," FM hardwareLoopback Status = " + status);
633 if( status == AudioSystem.DEVICE_STATE_AVAILABLE) {
634 // This case usually happens, when FM is force killed through settings app
635 // and we don't get chance to disable Hardware LoopBack.
636 Log.d(LOGTAG," FM HardwareLoopBack Active, disable it first");
637 status = AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
638 AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "",
639 AudioSystem.AUDIO_FORMAT_DEFAULT);
640 mCurrentDevice = AudioDeviceInfo.TYPE_WIRED_HEADSET;
641 }
642 status = AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
643 AudioSystem.DEVICE_STATE_AVAILABLE, "", "",
644 AudioSystem.AUDIO_FORMAT_DEFAULT);
645 if (status != AudioSystem.SUCCESS) {
646 success = false;
647 Log.e(LOGTAG, "configureFMDeviceLoopback failed! status:" + status);
648 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
649 AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "",
650 AudioSystem.AUDIO_FORMAT_DEFAULT);
651 mCurrentDevice = AudioDeviceInfo.TYPE_UNKNOWN;
652 } else {
653 mIsFMDeviceLoopbackActive = true;
654 }
655 } else if (!enable && mIsFMDeviceLoopbackActive == true) {
656 AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_FM,
657 AudioSystem.DEVICE_STATE_UNAVAILABLE, "", "",
658 AudioSystem.AUDIO_FORMAT_DEFAULT);
659 mIsFMDeviceLoopbackActive = false;
660 mCurrentDevice = AudioDeviceInfo.TYPE_UNKNOWN;
661 }
662
663 return success;
664 }
665
666 private synchronized void configureAudioDataPath(boolean enable) {
667 Log.d(LOGTAG, "configureAudioDataPath:" + enable +
668 " mA2dpConnected:" + mA2dpConnected +
669 " isRecordSinking" + isRecordSinking() +
670 " mSpeakerPhoneOn:" + mSpeakerPhoneOn +
671 " mIsFMDeviceLoopbackActive:" + mIsFMDeviceLoopbackActive);
672
673 if (enable) {
674 Log.d(LOGTAG,"Start Hardware loop back for audio");
675 if (mStoppedOnFocusLoss == true) {
676 Log.d(LOGTAG, "FM does not have audio focus, not enabling " +
677 "audio path");
678 return;
679 }
680 if ((!mIsFMDeviceLoopbackActive) && (!mA2dpConnected) && (!mSpeakerPhoneOn)) {
681 // not on BT and device loop is also not active
682 if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
683 enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
684 }
685 exitRecordSinkThread();
686 configureFMDeviceLoopback_O(true);
687 }
688 } else {
689 //inform audio to disbale fm audio
690 configureFMDeviceLoopback_O(false);
691 exitRecordSinkThread();
692 }
693 }
694
himta ram3a615df2019-01-10 16:00:51 +0530695 private void setCurrentFMVolume() {
696 if(isFmOn()) {
697 AudioManager maudioManager =
698 (AudioManager) getSystemService(Context.AUDIO_SERVICE);
699 int mCurrentVolumeIndex =
700 maudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
701 setFMVolume(mCurrentVolumeIndex);
702 }
703 }
704
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530705 /**
706 * Registers an intent to listen for ACTION_MEDIA_UNMOUNTED notifications.
707 * The intent will call closeExternalStorageFiles() if the external media
708 * is going to be ejected, so applications can clean up.
709 */
710 public void registerExternalStorageListener() {
711 if (mSdcardUnmountReceiver == null) {
712 mSdcardUnmountReceiver = new BroadcastReceiver() {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530713 @Override
714 public void onReceive(Context context, Intent intent) {
715 String action = intent.getAction();
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530716 if ((action.equals(Intent.ACTION_MEDIA_UNMOUNTED))
717 || (action.equals(Intent.ACTION_MEDIA_EJECT))) {
718 Log.d(LOGTAG, "ACTION_MEDIA_UNMOUNTED Intent received");
719 if (mFmRecordingOn == true) {
Rupesh Tatiya9a50d9a2016-01-19 21:54:49 +0530720 if (mStoragePath == null) {
721 Log.d(LOGTAG, "Storage path is null, doing nothing");
722 return;
723 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530724 try {
Rupesh Tatiya9a50d9a2016-01-19 21:54:49 +0530725 String state = Environment.getExternalStorageState(mStoragePath);
726 if (!Environment.MEDIA_MOUNTED.equals(state)) {
727 Log.d(LOGTAG, "Recording storage is not mounted, stop recording");
728 stopRecording();
729 }
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530730 } catch (Exception e) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530731 e.printStackTrace();
732 }
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530733 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530734 }
735 }
736 };
737 IntentFilter iFilter = new IntentFilter();
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530738 iFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
739 iFilter.addAction(Intent.ACTION_MEDIA_EJECT);
740 iFilter.addDataScheme("file");
741 registerReceiver(mSdcardUnmountReceiver, iFilter);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530742 }
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +0530743 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530744
Venkateshwarlu Domakondae8d7acf2015-04-06 19:01:37 +0530745 public void registerAirplaneModeStatusChanged() {
746 if (mAirplaneModeChanged == null) {
747 mAirplaneModeChanged = new BroadcastReceiver() {
748 @Override
749 public void onReceive(Context context, Intent intent) {
750 String action = intent.getAction();
751 if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) {
752 Log.d(LOGTAG, "ACTION_AIRPLANE_MODE_CHANGED received");
753 boolean state = intent.getBooleanExtra("state", false);
754 if (state == true) {
755 fmOff();
Venkateshwarlu Domakonda6c5cd5c2015-07-15 16:00:30 +0530756 try {
757 if ((mServiceInUse) && (mCallbacks != null) ) {
758 mCallbacks.onDisabled();
759 }
760 } catch (RemoteException e) {
761 e.printStackTrace();
762 }
Venkateshwarlu Domakondae8d7acf2015-04-06 19:01:37 +0530763 }
764 }
765 }
766 };
767 IntentFilter iFilter = new IntentFilter();
768 iFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
769 registerReceiver(mAirplaneModeChanged, iFilter);
770 }
771 }
772
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530773 public void registerUserSwitch(){
774 if (mRegisterUserSwitched == null) {
775 mRegisterUserSwitched = new BroadcastReceiver() {
776 @Override
777 public void onReceive(Context context, Intent intent) {
778 String action = intent.getAction();
779 Log.d(LOGTAG, "on receive UserSwitched " + action);
780 if (action.equals(Intent.ACTION_USER_SWITCHED)) {
781 Log.d(LOGTAG, "ACTION_USER_SWITCHED Intent received");
782 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
783 Log.d(LOGTAG, "ACTION_USER_SWITCHED, user ID:" + userId);
himta rama5aef032018-08-09 16:55:02 +0530784 if (isFmOn()){
785 fmOff();
786 try {
787 if ((mServiceInUse) && (mCallbacks != null) ) {
788 mCallbacks.onDisabled();
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530789 }
himta rama5aef032018-08-09 16:55:02 +0530790 } catch (RemoteException e) {
791 e.printStackTrace();
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530792 }
himta rama5aef032018-08-09 16:55:02 +0530793 }
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530794 stop();
795 android.os.Process.killProcess(android.os.Process.myPid());
796 System.exit(0);
Smriti Gupta1abb1c12017-08-17 14:02:26 +0530797 }
798 }
799 };
800 IntentFilter iFilter = new IntentFilter();
801 iFilter.addAction(Intent.ACTION_USER_SWITCHED);
802 registerReceiver(mRegisterUserSwitched, iFilter);
803 }
804 }
805
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530806 /**
807 * Registers an intent to listen for ACTION_HEADSET_PLUG
808 * notifications. This intent is called to know if the headset
809 * was plugged in/out
810 */
811 public void registerHeadsetListener() {
812 if (mHeadsetReceiver == null) {
813 mHeadsetReceiver = new BroadcastReceiver() {
814 @Override
815 public void onReceive(Context context, Intent intent) {
816 String action = intent.getAction();
Rupesh Tatiya5ed72802015-11-30 15:40:46 +0530817 Log.d(LOGTAG, "on receive HeadsetListener " + action);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530818 if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
819 Log.d(LOGTAG, "ACTION_HEADSET_PLUG Intent received");
820 // Listen for ACTION_HEADSET_PLUG broadcasts.
821 Log.d(LOGTAG, "mReceiver: ACTION_HEADSET_PLUG");
822 Log.d(LOGTAG, "==> intent: " + intent);
823 Log.d(LOGTAG, " state: " + intent.getIntExtra("state", 0));
824 Log.d(LOGTAG, " name: " + intent.getStringExtra("name"));
825 mHeadsetPlugged = (intent.getIntExtra("state", 0) == 1);
826 // if headset is plugged out it is required to disable
827 // in minimal duration to avoid race conditions with
828 // audio policy manager switch audio to speaker.
himta rame628c052018-07-06 20:26:48 +0530829 if (isfmOffFromApplication) {
830 Log.d(LOGTAG, "fm is off from Application, bail out");
831 return;
832 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530833 mHandler.removeCallbacks(mHeadsetPluginHandler);
834 mHandler.post(mHeadsetPluginHandler);
Peng Chenb7941f72015-08-12 17:20:39 +0800835 } else if(mA2dpDeviceState.isA2dpStateChange(action) &&
836 (mA2dpDeviceState.isConnected(intent) ||
837 mA2dpDeviceState.isDisconnected(intent))) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530838 boolean bA2dpConnected =
839 mA2dpDeviceState.isConnected(intent);
Rupesh Tatiya5ed72802015-11-30 15:40:46 +0530840 Log.d(LOGTAG, "bA2dpConnected: " + bA2dpConnected);
juncao693dc452016-01-08 17:29:35 +0800841
himta rambff94f22018-06-05 11:03:21 +0530842 //mSpeakerPhoneOn = bA2dpConnected;
843 mA2dpConnected = bA2dpConnected;
844 mA2dpDisconnected = !bA2dpConnected;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530845 } else if (action.equals("HDMI_CONNECTED")) {
846 //FM should be off when HDMI is connected.
847 fmOff();
848 try
849 {
850 /* Notify the UI/Activity, only if the service is "bound"
851 by an activity and if Callbacks are registered
852 */
853 if((mServiceInUse) && (mCallbacks != null) )
854 {
855 mCallbacks.onDisabled();
856 }
857 } catch (RemoteException e)
858 {
859 e.printStackTrace();
860 }
861 } else if( action.equals(Intent.ACTION_SHUTDOWN)) {
862 mAppShutdown = true;
Kamal Negi26b56832016-07-08 15:59:20 +0530863 if (isFmRecordingOn()) {
864 stopRecording();
865 }
himta ram43bf6232018-11-02 11:16:37 +0530866 } else if( action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
himta ram046d5c32019-01-10 15:42:34 +0530867 if(!isFmOn()) {
868 Log.d(LOGTAG, "FM is Turned off ,not applying the changed volume");
869 return;
870 }
himta ram43bf6232018-11-02 11:16:37 +0530871 int streamType =
872 intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
873 if (streamType == AudioManager.STREAM_MUSIC) {
874 int mCurrentVolumeIndex =
875 intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, -1);
876 setFMVolume(mCurrentVolumeIndex);
877 }
himta ram3a615df2019-01-10 16:00:51 +0530878 } else if (action.equals(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED)) {
879 mHandler.removeCallbacks(mFmVolumeHandler);
880 mHandler.post(mFmVolumeHandler);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530881
himta ram3a615df2019-01-10 16:00:51 +0530882 } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
883 int state =
884 intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
885 Log.d(LOGTAG, "ACTION_STATE_CHANGED state :"+ state);
886 if (state == BluetoothAdapter.STATE_OFF) {
887 mHandler.removeCallbacks(mFmVolumeHandler);
888 mHandler.post(mFmVolumeHandler);
889 }
890 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530891 }
892 };
Dhananjay Kumard3f90872015-10-21 15:10:06 +0530893 AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530894 IntentFilter iFilter = new IntentFilter();
895 iFilter.addAction(Intent.ACTION_HEADSET_PLUG);
himta ramc46068f2018-07-25 15:06:08 +0530896 iFilter.addAction(mA2dpDeviceState.getActionSinkStateChangedString());
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530897 iFilter.addAction("HDMI_CONNECTED");
898 iFilter.addAction(Intent.ACTION_SHUTDOWN);
himta ram43bf6232018-11-02 11:16:37 +0530899 iFilter.addAction(AudioManager.VOLUME_CHANGED_ACTION);
himta ram3a615df2019-01-10 16:00:51 +0530900 iFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
901 iFilter.addAction(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530902 iFilter.addCategory(Intent.CATEGORY_DEFAULT);
903 registerReceiver(mHeadsetReceiver, iFilter);
904 }
905 }
906
Venkateshwarlu Domakondafd50fd42014-04-18 12:36:13 +0530907 public void registerAudioBecomeNoisy() {
908 if (mAudioBecomeNoisyListener == null) {
909 mAudioBecomeNoisyListener = new BroadcastReceiver() {
910 @Override
911 public void onReceive(Context context, Intent intent) {
Venkateshwarlu Domakondafd50fd42014-04-18 12:36:13 +0530912 String intentAction = intent.getAction();
himta ramd1e2dd02018-07-30 16:05:29 +0530913 Log.d(LOGTAG, "intent received " + intentAction);
914 if ((intentAction != null) &&
915 intentAction.equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
916 if (isFmOn())
917 {
918 Log.d(LOGTAG, "AUDIO_BECOMING_NOISY INTENT: mute FM Audio");
919 mute();
920 }
Venkateshwarlu Domakondafd50fd42014-04-18 12:36:13 +0530921 }
922 }
923 };
himta ramd1e2dd02018-07-30 16:05:29 +0530924 IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
Venkateshwarlu Domakondafd50fd42014-04-18 12:36:13 +0530925 registerReceiver(mAudioBecomeNoisyListener, intentFilter);
926 }
927 }
928
Rupesh Tatiyac9829e52016-01-27 12:46:57 +0530929 // TODO: Check if this is needed with latest Android versions?
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530930 public void registerMusicServiceCommandReceiver() {
931 if (mMusicCommandListener == null) {
932 mMusicCommandListener = new BroadcastReceiver() {
933 @Override
934 public void onReceive(Context context, Intent intent) {
935 String action = intent.getAction();
936
937 if (action.equals("com.android.music.musicservicecommand")) {
938 String cmd = intent.getStringExtra("command");
939 Log.d(LOGTAG, "Music Service command : "+cmd+ " received");
940 if (cmd != null && cmd.equals("pause")) {
Rupesh Tatiyac9829e52016-01-27 12:46:57 +0530941 if (isFmOn()) {
Mingbo Zhang5b83d772017-01-10 14:02:28 +0800942 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
himta ramdfa45932019-03-07 17:57:54 +0530943 audioManager.abandonAudioFocusRequest(mGainFocusReq);
Mingbo Zhang5b83d772017-01-10 14:02:28 +0800944 mDelayedStopHandler.obtainMessage(FOCUSCHANGE, AudioManager.AUDIOFOCUS_LOSS, 0).sendToTarget();
945
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530946 if (isOrderedBroadcast()) {
947 abortBroadcast();
948 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +0530949 }
950 }
951 }
952 }
953 };
954 IntentFilter commandFilter = new IntentFilter();
955 commandFilter.addAction("com.android.music.musicservicecommand");
956 registerReceiver(mMusicCommandListener, commandFilter);
957 }
958 }
959 public void registerSleepExpired() {
960 if (mSleepExpiredListener == null) {
961 mSleepExpiredListener = new BroadcastReceiver() {
962 @Override
963 public void onReceive(Context context, Intent intent) {
964 Log.d(LOGTAG, "registerSleepExpired");
965 mWakeLock.acquire(10 * 1000);
966 fmOff();
967 }
968 };
969 IntentFilter intentFilter = new IntentFilter(SLEEP_EXPIRED_ACTION);
970 registerReceiver(mSleepExpiredListener, intentFilter);
971 }
972 }
973 public void registerRecordTimeout() {
974 if (mRecordTimeoutListener == null) {
975 mRecordTimeoutListener = new BroadcastReceiver() {
976 @Override
977 public void onReceive(Context context, Intent intent) {
978 Log.d(LOGTAG, "registerRecordTimeout");
979 mWakeLock.acquire(5 * 1000);
980 stopRecording();
981 }
982 };
983 IntentFilter intentFilter = new IntentFilter(RECORD_EXPIRED_ACTION);
984 registerReceiver(mRecordTimeoutListener, intentFilter);
985 }
986 }
987 public void registerDelayedServiceStop() {
988 if (mDelayedServiceStopListener == null) {
989 mDelayedServiceStopListener = new BroadcastReceiver() {
990 @Override
991 public void onReceive(Context context, Intent intent) {
992 Log.d(LOGTAG, "registerDelayedServiceStop");
993 mWakeLock.acquire(5 * 1000);
994 if (isFmOn() || mServiceInUse) {
995 return;
996 }
997 stopSelf(mServiceStartId);
998 }
999 };
1000 IntentFilter intentFilter = new IntentFilter(SERVICE_DELAYED_STOP_ACTION);
1001 registerReceiver(mDelayedServiceStopListener, intentFilter);
1002 }
1003 }
1004
himta ram3a615df2019-01-10 16:00:51 +05301005 final Runnable mFmVolumeHandler = new Runnable() {
1006 public void run() {
1007 try {
himta rame4e8ad12019-05-30 10:42:10 +05301008 Thread.sleep(1500);
himta ram3a615df2019-01-10 16:00:51 +05301009 } catch (Exception ex) {
1010 Log.d( LOGTAG, "RunningThread InterruptedException");
1011 return;
1012 }
1013 setCurrentFMVolume();
1014 }
1015 };
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301016
1017 final Runnable mHeadsetPluginHandler = new Runnable() {
1018 public void run() {
1019 /* Update the UI based on the state change of the headset/antenna*/
1020 if(!isAntennaAvailable())
1021 {
juncao693dc452016-01-08 17:29:35 +08001022 mSpeakerPhoneOn = false;
Venkateshwarlu Domakondafd50fd42014-04-18 12:36:13 +05301023 if (!isFmOn())
1024 return;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301025 /* Disable FM and let the UI know */
Kamal Negi28a8da72016-03-19 15:10:31 +05301026 fmOff(FM_OFF_FROM_ANTENNA);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301027 try
1028 {
1029 /* Notify the UI/Activity, only if the service is "bound"
1030 by an activity and if Callbacks are registered
1031 */
1032 if((mServiceInUse) && (mCallbacks != null) )
1033 {
1034 mCallbacks.onDisabled();
1035 }
1036 } catch (RemoteException e)
1037 {
1038 e.printStackTrace();
1039 }
1040 }
1041 else
1042 {
1043 /* headset is plugged back in,
1044 So turn on FM if:
1045 - FM is not already ON.
1046 - If the FM UI/Activity is in the foreground
1047 (the service is "bound" by an activity
1048 and if Callbacks are registered)
1049 */
1050 if ((!isFmOn()) && (mServiceInUse)
1051 && (mCallbacks != null))
1052 {
1053 if( true != fmOn() ) {
1054 return;
1055 }
1056 try
1057 {
1058 mCallbacks.onEnabled();
1059 } catch (RemoteException e)
1060 {
1061 e.printStackTrace();
1062 }
1063 }
1064 }
1065 }
1066 };
1067
1068
1069 @Override
1070 public IBinder onBind(Intent intent) {
1071 mDelayedStopHandler.removeCallbacksAndMessages(null);
1072 cancelAlarms();
1073 mServiceInUse = true;
1074 /* Application/UI is attached, so get out of lower power mode */
1075 setLowPowerMode(false);
Balvinder Singh7b765532017-08-04 15:45:28 +05301076 Log.d(LOGTAG, "onBind ");
1077 //todo check for the mBinder validity
1078 mFMdr = new FMDeathRecipient(this, mBinder);
1079 try {
1080 mBinder.linkToDeath(mFMdr, 0);
1081 Log.d(LOGTAG, "onBind mBinder linked to death" + mBinder);
1082 } catch (RemoteException e) {
1083 Log.e(LOGTAG,"LinktoDeath Exception: "+e + "FM DR =" + mFMdr);
1084 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301085 return mBinder;
1086 }
1087
1088 @Override
1089 public void onRebind(Intent intent) {
Rupesh Tatiya9917f922017-06-21 13:00:43 +05301090 Log.d(LOGTAG, "onRebind");
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301091 mDelayedStopHandler.removeCallbacksAndMessages(null);
Ayaz Ahmad594e34a2013-09-12 17:04:29 +05301092 cancelAlarmDealyedServiceStop();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301093 mServiceInUse = true;
1094 /* Application/UI is attached, so get out of lower power mode */
Venkateshwarlu Domakonda93cacf82014-11-21 16:40:12 +05301095 if (isFmOn()) {
1096 setLowPowerMode(false);
1097 startFM();
himta ramdd027a32019-01-18 20:50:08 +05301098 if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
1099 enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
1100 }
Venkateshwarlu Domakonda93cacf82014-11-21 16:40:12 +05301101 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301102 }
1103
1104 @Override
himta ramdfa45932019-03-07 17:57:54 +05301105 public int onStartCommand(Intent intent, int flags, int startId) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301106 Log.d(LOGTAG, "onStart");
1107 mServiceStartId = startId;
1108 // make sure the service will shut down on its own if it was
1109 // just started but not bound to and nothing is playing
1110 mDelayedStopHandler.removeCallbacksAndMessages(null);
Ayaz Ahmad594e34a2013-09-12 17:04:29 +05301111 cancelAlarmDealyedServiceStop();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301112 setAlarmDelayedServiceStop();
himta ramdfa45932019-03-07 17:57:54 +05301113
1114 return START_STICKY;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301115 }
1116
1117 @Override
1118 public boolean onUnbind(Intent intent) {
Balvinder Singh7b765532017-08-04 15:45:28 +05301119 mServiceInUse = false;
1120 Log.d(LOGTAG, "onUnbind");
1121 /* Application/UI is not attached, so go into lower power mode */
1122 unregisterCallbacks();
1123 setLowPowerMode(true);
1124 try{
1125 Log.d(LOGTAG,"Unlinking FM Death receipient");
1126 mBinder.unlinkToDeath(mFMdr,0);
1127 }
1128 catch(NoSuchElementException e){
1129 Log.e(LOGTAG,"No death recipient registered"+e);
1130 }
1131 return true;
1132 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301133
Ayaz Ahmad5d19b1b2013-09-05 16:53:09 +05301134 private String getProcessName() {
1135 int id = Process.myPid();
1136 String myProcessName = this.getPackageName();
1137
1138 ActivityManager actvityManager =
1139 (ActivityManager)this.getSystemService(this.ACTIVITY_SERVICE);
1140 List<RunningAppProcessInfo> procInfos =
1141 actvityManager.getRunningAppProcesses();
1142
1143 for(RunningAppProcessInfo procInfo : procInfos) {
1144 if (id == procInfo.pid) {
1145 myProcessName = procInfo.processName;
1146 }
1147 }
1148 procInfos.clear();
1149 return myProcessName;
1150 }
1151
Venkateshwarlu Domakondafa22ae12013-07-27 12:25:16 +05301152 private void sendRecordServiceIntent(int action) {
1153 Intent intent = new Intent(ACTION_FM);
1154 intent.putExtra("state", action);
Satish Kodishalaf2c06632014-01-21 16:31:24 +05301155 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Venkateshwarlu Domakondafa22ae12013-07-27 12:25:16 +05301156 Log.d(LOGTAG, "Sending Recording intent for = " +action);
1157 getApplicationContext().sendBroadcast(intent);
1158 }
1159
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +05301160 private void toggleFM() {
1161 Log.d(LOGTAG, "Toggle FM");
1162 if (isFmOn()){
1163 fmOff();
1164 try {
1165 if ((mServiceInUse) && (mCallbacks != null) ) {
1166 mCallbacks.onDisabled();
1167 }
1168 } catch (RemoteException e) {
1169 e.printStackTrace();
1170 }
Venkateshwarlu Domakondae4643d12015-10-06 11:43:38 +05301171 } else if(isAntennaAvailable() && mServiceInUse ) {
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +05301172 fmOn();
1173 try {
1174 if (mCallbacks != null ) {
1175 mCallbacks.onEnabled();
1176 }
1177 } catch (RemoteException e) {
1178 e.printStackTrace();
1179 }
1180 }
1181 }
1182
1183 private final MediaSession.Callback mSessionCallback = new MediaSession.Callback() {
1184 @Override
1185 public boolean onMediaButtonEvent(Intent intent) {
1186 KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
1187 Log.d(LOGTAG, "SessionCallback.onMediaButton()... event = " +event);
1188 int key_action = event.getAction();
1189 if ((event != null) && ((event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)
Hu Wangb80e8482015-04-08 14:36:46 +08001190 || (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE))) {
1191 if (key_action == KeyEvent.ACTION_DOWN) {
1192 mKeyActionDownCount++;
1193 }
1194 if ((mKeyActionDownCount == 1) && (key_action == KeyEvent.ACTION_UP)) {
1195 Log.d(LOGTAG, "SessionCallback: HEADSETHOOK/MEDIA_PLAY_PAUSE short press");
1196 mKeyActionDownCount = 0;
1197 toggleFM();
1198 } else if ((mKeyActionDownCount == 2) && (key_action == KeyEvent.ACTION_DOWN)) {
1199 Log.d(LOGTAG, "SessionCallback: HEADSETHOOK/MEDIA_PLAY_PAUSE long press");
Chenyang Zhangc7bddc82015-06-18 10:28:45 +08001200 if (isFmOn() && getResources()
1201 .getBoolean(R.bool.def_headset_next_enabled)) {
1202 try {
Mingbo Zhange1a4ab02016-03-21 10:28:18 +08001203 if ((mServiceInUse) && (mCallbacks != null))
1204 mCallbacks.onSeekNextStation();
Chenyang Zhangc7bddc82015-06-18 10:28:45 +08001205 }catch (RemoteException e) {
1206 }
1207 }
Hu Wangb80e8482015-04-08 14:36:46 +08001208 mKeyActionDownCount = 0;
1209 }
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +05301210 return true;
Venkateshwarlu Domakondab6ffaa62015-06-29 19:07:07 +05301211 } else if((event != null) && (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY)
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +05301212 && (key_action == KeyEvent.ACTION_DOWN)) {
Venkateshwarlu Domakondab6ffaa62015-06-29 19:07:07 +05301213 Log.d(LOGTAG, "SessionCallback: MEDIA_PLAY");
Venkateshwarlu Domakondae4643d12015-10-06 11:43:38 +05301214 if (isAntennaAvailable() && mServiceInUse) {
Kamal Negi8377ec42016-07-05 10:42:45 +05301215 if (isFmOn()){
1216 //FM should be off when Headset hook pressed.
1217 fmOff();
1218 try {
1219 /* Notify the UI/Activity, only if the service is "bound"
1220 * by an activity and if Callbacks are registered
1221 * */
1222 if ((mServiceInUse) && (mCallbacks != null) ) {
1223 mCallbacks.onDisabled();
1224 }
1225 } catch (RemoteException e) {
1226 e.printStackTrace();
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +05301227 }
Kamal Negi8377ec42016-07-05 10:42:45 +05301228 } else {
1229 fmOn();
1230 try {
1231 if (mCallbacks != null ) {
1232 mCallbacks.onEnabled();
1233 }
1234 } catch (RemoteException e) {
1235 e.printStackTrace();
1236 }
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +05301237 }
1238 return true;
1239 }
Venkateshwarlu Domakondab6ffaa62015-06-29 19:07:07 +05301240 } else if ((event != null) && ((event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PAUSE) ||
1241 (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_STOP))
1242 && (key_action == KeyEvent.ACTION_DOWN)) {
1243 Log.d(LOGTAG, "SessionCallback: MEDIA_PAUSE");
Venkateshwarlu Domakonda3b55b852014-11-28 14:30:42 +05301244 if (isFmOn()){
1245 //FM should be off when Headset hook pressed.
1246 fmOff();
1247 try {
1248 /* Notify the UI/Activity, only if the service is "bound"
1249 by an activity and if Callbacks are registered
1250 */
1251 if ((mServiceInUse) && (mCallbacks != null) ) {
1252 mCallbacks.onDisabled();
1253 }
1254 } catch (RemoteException e) {
1255 e.printStackTrace();
1256 }
1257 return true;
1258 }
1259 }
1260 return false;
1261 }
1262 };
1263
himta ramdfa45932019-03-07 17:57:54 +05301264 private AudioFocusRequest requestAudioFocus() {
1265 AudioAttributes playbackAttr = new AudioAttributes.Builder()
1266 .setUsage(AudioAttributes.USAGE_MEDIA)
1267 .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
1268 .build();
1269 AudioFocusRequest focusRequest =
1270 new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
1271 .setAudioAttributes(playbackAttr)
1272 .setAcceptsDelayedFocusGain(true)
1273 .setWillPauseWhenDucked(true)
1274 .setOnAudioFocusChangeListener(this::onAudioFocusChange)
1275 .build();
1276
1277 return focusRequest;
1278 }
1279
Rupesh Tatiya21784702016-02-24 15:16:28 +05301280 private void startFM() {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301281 Log.d(LOGTAG, "In startFM");
1282 if(true == mAppShutdown) { // not to send intent to AudioManager in Shutdown
1283 return;
1284 }
1285 if (isCallActive()) { // when Call is active never let audio playback
1286 mResumeAfterCall = true;
1287 return;
1288 }
1289 mResumeAfterCall = false;
1290 if ( true == mPlaybackInProgress ) // no need to resend event
1291 return;
Satish Kodishala454dd9e2014-11-20 15:34:46 +05301292
1293 /* If audio focus lost while SSR in progress, don't request for Audio focus */
1294 if ( (true == mIsSSRInProgress || true == mIsSSRInProgressFromActivity) &&
1295 true == mStoppedOnFocusLoss) {
1296 Log.d(LOGTAG, "Audio focus lost while SSR in progress, returning");
1297 return;
1298 }
1299
Mingbo Zhange579ce12017-01-13 10:53:00 +08001300 if (mStoppedOnFocusLoss) {
himta ramccab50c2018-12-18 17:06:13 +05301301 for(int i = 0; i < 4; i++)
1302 {
1303 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
himta ramdfa45932019-03-07 17:57:54 +05301304 int granted = audioManager.requestAudioFocus(mGainFocusReq);
himta ramccab50c2018-12-18 17:06:13 +05301305 if (granted == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
1306 Log.d(LOGTAG, "audio focuss granted");
1307 break;
1308 } else {
1309 Log.d(LOGTAG, "audio focuss couldnot granted retry after some time");
1310 /*in case of call and fm concurency case focus is abandon
1311 ** after on call state callback, need to retry to get focus*/
1312 try {
1313 Thread.sleep(200);
1314 } catch (Exception ex) {
1315 Log.d( LOGTAG, "RunningThread InterruptedException");
1316 return;
1317 }
1318 }
Mingbo Zhange579ce12017-01-13 10:53:00 +08001319 }
Ayaz Ahmadc01694b2013-09-16 17:57:06 +05301320 }
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05301321 mSession.setActive(true);
Ayaz Ahmadc01694b2013-09-16 17:57:06 +05301322
himta ramdfa45932019-03-07 17:57:54 +05301323 Log.d(LOGTAG,"FM registering for MediaButtonReceiver");
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301324 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
1325 ComponentName fmRadio = new ComponentName(this.getPackageName(),
1326 FMMediaButtonIntentReceiver.class.getName());
himta ramdfa45932019-03-07 17:57:54 +05301327 Intent mediaButtonIntent =
1328 new Intent(Intent.ACTION_MEDIA_BUTTON).setComponent(fmRadio);
1329 PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0,
1330 mediaButtonIntent, 0);
1331 mSession.setMediaButtonReceiver(pi);
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05301332
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301333 mStoppedOnFocusLoss = false;
himta rama1c405b2018-07-11 17:13:56 +05301334 mPlaybackInProgress = true;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301335
Kamal Negidd175dc2016-06-03 20:09:24 +05301336 if (mStoppedOnFactoryReset) {
1337 mStoppedOnFactoryReset = false;
1338 mSpeakerPhoneOn = false;
Erfan Abdi60258312019-08-21 17:25:21 +04301339 if (mUseAudioSession)
1340 configureAudioDataPath(true);
Kamal Negidd175dc2016-06-03 20:09:24 +05301341 // In FM stop, the audio route is set to default audio device
himta ram05563692018-08-09 15:10:26 +05301342 }
himta ram43bf6232018-11-02 11:16:37 +05301343 String temp = mSpeakerPhoneOn ? "Speaker" : "WiredHeadset";
1344 Log.d(LOGTAG, "Route audio to " + temp);
1345 if (mSpeakerPhoneOn) {
1346 mAudioDevice = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
himta rama1c405b2018-07-11 17:13:56 +05301347 } else {
himta ram43bf6232018-11-02 11:16:37 +05301348 mAudioDevice = AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301349 }
Erfan Abdi60258312019-08-21 17:25:21 +04301350 if (mUseAudioSession)
1351 startApplicationLoopBack(mAudioDevice);
1352 else
1353 configureFMDeviceLoopback(true);
Rupesh Tatiya21784702016-02-24 15:16:28 +05301354 try {
Mingbo Zhange1a4ab02016-03-21 10:28:18 +08001355 if ((mServiceInUse) && (mCallbacks != null))
1356 mCallbacks.onFmAudioPathStarted();
Rupesh Tatiya21784702016-02-24 15:16:28 +05301357 } catch(RemoteException e) {
1358 e.printStackTrace();
1359 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301360 }
1361
Rupesh Tatiya21784702016-02-24 15:16:28 +05301362 private void stopFM() {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301363 Log.d(LOGTAG, "In stopFM");
Erfan Abdi60258312019-08-21 17:25:21 +04301364 if (mUseAudioSession)
1365 configureAudioDataPath(false);
1366 else
1367 configureFMDeviceLoopback(false);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301368 mPlaybackInProgress = false;
Rupesh Tatiya21784702016-02-24 15:16:28 +05301369 try {
Mingbo Zhange1a4ab02016-03-21 10:28:18 +08001370 if ((mServiceInUse) && (mCallbacks != null))
1371 mCallbacks.onFmAudioPathStopped();
Rupesh Tatiya21784702016-02-24 15:16:28 +05301372 } catch(RemoteException e) {
1373 e.printStackTrace();
1374 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301375 }
1376
1377 private void resetFM(){
1378 Log.d(LOGTAG, "resetFM");
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301379 mPlaybackInProgress = false;
Erfan Abdi60258312019-08-21 17:25:21 +04301380 if (mUseAudioSession)
1381 configureAudioDataPath(false);
1382 else
1383 configureFMDeviceLoopback(false);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301384 }
1385
Satish Kodishala46c9bf62014-03-04 20:22:52 +05301386 private boolean getRecordServiceStatus() {
1387 boolean status = false;
1388 ActivityManager actvityManager =
1389 (ActivityManager)this.getSystemService(this.ACTIVITY_SERVICE);
1390 List<RunningAppProcessInfo> procInfos =
1391 actvityManager.getRunningAppProcesses();
1392 for(RunningAppProcessInfo procInfo : procInfos) {
1393 if (procInfo.processName.equals("com.codeaurora.fmrecording")) {
1394 status = true;
1395 break;
1396 }
1397 }
1398 procInfos.clear();
1399 return status;
1400 }
Venkateshwarlu Domakondafa22ae12013-07-27 12:25:16 +05301401
Xuebo Li38993a92015-11-03 16:37:16 +08001402 private File createTempFile(String prefix, String suffix, File directory)
1403 throws IOException {
1404 // Force a prefix null check first
1405 if (prefix.length() < 3) {
1406 throw new IllegalArgumentException("prefix must be at least 3 characters");
1407 }
1408 if (suffix == null) {
1409 suffix = ".tmp";
1410 }
1411 File tmpDirFile = directory;
1412 if (tmpDirFile == null) {
1413 String tmpDir = System.getProperty("java.io.tmpdir", ".");
1414 tmpDirFile = new File(tmpDir);
1415 }
1416
1417 String nameFormat = getResources().getString(R.string.def_save_name_format);
1418 SimpleDateFormat df = new SimpleDateFormat(nameFormat);
1419 String currentTime = df.format(System.currentTimeMillis());
1420
1421 File result;
1422 do {
1423 result = new File(tmpDirFile, prefix + currentTime + suffix);
1424 } while (!result.createNewFile());
1425 return result;
1426 }
1427
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301428 public boolean startRecording() {
Venkateshwarlu Domakonda11847732015-09-04 18:56:13 +05301429 int mRecordDuration = -1;
1430
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301431 Log.d(LOGTAG, "In startRecording of Recorder");
1432 if((true == mSingleRecordingInstanceSupported) &&
1433 (true == mOverA2DP )) {
1434 Toast.makeText( this,
1435 "playback on BT in progress,can't record now",
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301436 Toast.LENGTH_SHORT).show();
1437 return false;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301438 }
1439 stopRecording();
1440
1441 if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
1442 Log.e(LOGTAG, "startRecording, no external storage available");
1443 return false;
1444 }
1445
1446 if (!updateAndShowStorageHint())
1447 return false;
1448 long maxFileSize = mStorageSpace - LOW_STORAGE_THRESHOLD;
Venkateshwarlu Domakonda11847732015-09-04 18:56:13 +05301449 if(FmSharedPreferences.getRecordDuration() !=
1450 FmSharedPreferences.RECORD_DUR_INDEX_3_VAL) {
1451 mRecordDuration = (FmSharedPreferences.getRecordDuration() * 60 * 1000);
1452 }
1453
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301454 mRecorder = new MediaRecorder();
1455 try {
1456 mRecorder.setMaxFileSize(maxFileSize);
Venkateshwarlu Domakonda11847732015-09-04 18:56:13 +05301457 if (mRecordDuration >= 0)
1458 mRecorder.setMaxDuration(mRecordDuration);
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301459 } catch (RuntimeException exception) {
1460
1461 }
1462
Rupesh Tatiya9a50d9a2016-01-19 21:54:49 +05301463 mStoragePath = Environment.getExternalStorageDirectory();
1464 Log.d(LOGTAG, "mStoragePath " + mStoragePath);
1465 if (null == mStoragePath) {
1466 Log.e(LOGTAG, "External Storage Directory is null");
1467 return false;
1468 }
1469
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301470 mSampleFile = null;
Xuebo Li38993a92015-11-03 16:37:16 +08001471 File sampleDir = null;
1472 if (!"".equals(getResources().getString(R.string.def_fmRecord_savePath))) {
1473 String fmRecordSavePath = getResources().getString(R.string.def_fmRecord_savePath);
1474 sampleDir = new File(Environment.getExternalStorageDirectory().toString()
1475 + fmRecordSavePath);
1476 } else {
1477 sampleDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
1478 + "/FMRecording");
1479 }
1480
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301481 if(!(sampleDir.mkdirs() || sampleDir.isDirectory()))
1482 return false;
1483 try {
Xuebo Li38993a92015-11-03 16:37:16 +08001484 if (getResources().getBoolean(R.bool.def_save_name_format_enabled)) {
1485 String suffix = getResources().getString(R.string.def_save_name_suffix);
Danesh M26bc1282014-12-04 13:26:54 -08001486 suffix = "".equals(suffix) ? ".aac" : suffix;
Xuebo Li38993a92015-11-03 16:37:16 +08001487 String prefix = getResources().getString(R.string.def_save_name_prefix) + '-';
1488 mSampleFile = createTempFile(prefix, suffix, sampleDir);
1489 } else {
Danesh M26bc1282014-12-04 13:26:54 -08001490 mSampleFile = File.createTempFile("FMRecording", ".aac", sampleDir);
Xuebo Li38993a92015-11-03 16:37:16 +08001491 }
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301492 } catch (IOException e) {
1493 Log.e(LOGTAG, "Not able to access SD Card");
1494 Toast.makeText(this, "Not able to access SD Card", Toast.LENGTH_SHORT).show();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301495 return false;
1496 }
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301497
1498 try {
1499 Log.d(LOGTAG, "AudioSource.RADIO_TUNER" +MediaRecorder.AudioSource.RADIO_TUNER);
1500 mRecorder.setAudioSource(MediaRecorder.AudioSource.RADIO_TUNER);
1501 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
1502 mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
Mahesh Kumar Sharma131a93d2015-09-08 16:27:04 -07001503 final int samplingRate = 44100;
1504 mRecorder.setAudioSamplingRate(samplingRate);
1505 final int bitRate = 128000;
1506 mRecorder.setAudioEncodingBitRate(bitRate);
1507 final int audiochannels = 2;
1508 mRecorder.setAudioChannels(audiochannels);
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301509 } catch (RuntimeException exception) {
1510 mRecorder.reset();
1511 mRecorder.release();
1512 mRecorder = null;
1513 return false;
1514 }
1515 mRecorder.setOutputFile(mSampleFile.getAbsolutePath());
1516 try {
1517 mRecorder.prepare();
1518 Log.d(LOGTAG, "start");
1519 mRecorder.start();
1520 } catch (IOException e) {
1521 mRecorder.reset();
1522 mRecorder.release();
1523 mRecorder = null;
1524 return false;
1525 } catch (RuntimeException e) {
1526 mRecorder.reset();
1527 mRecorder.release();
1528 mRecorder = null;
1529 return false;
1530 }
1531 mFmRecordingOn = true;
1532 Log.d(LOGTAG, "mSampleFile.getAbsolutePath() " +mSampleFile.getAbsolutePath());
1533 mRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
1534 public void onInfo(MediaRecorder mr, int what, int extra) {
1535 if ((what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) ||
1536 (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED)) {
1537 if (mFmRecordingOn) {
1538 Log.d(LOGTAG, "Maximum file size/duration reached, stop the recording");
1539 stopRecording();
1540 }
Venkateshwarlu Domakonda11847732015-09-04 18:56:13 +05301541 if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED)
1542 // Show the toast.
1543 Toast.makeText(FMRadioService.this, R.string.FMRecording_reach_size_limit,
1544 Toast.LENGTH_LONG).show();
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301545 }
1546 }
1547 // from MediaRecorder.OnErrorListener
1548 public void onError(MediaRecorder mr, int what, int extra) {
1549 Log.e(LOGTAG, "MediaRecorder error. what=" + what + ". extra=" + extra);
1550 if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
1551 // We may have run out of space on the sdcard.
1552 if (mFmRecordingOn) {
1553 stopRecording();
1554 }
1555 updateAndShowStorageHint();
1556 }
1557 }
1558 });
1559
1560 mSampleStart = SystemClock.elapsedRealtime();
Smriti Guptada03ddb2016-08-03 16:11:05 +05301561 Log.d(LOGTAG, "Sample start time: " +mSampleStart);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301562 return true;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301563 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301564
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301565 public void stopRecording() {
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301566 Log.d(LOGTAG, "Enter stopRecord");
1567 mFmRecordingOn = false;
1568 if (mRecorder == null)
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301569 return;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301570 try {
1571 mRecorder.stop();
himta ram33a55b42018-07-20 18:48:19 +05301572 } catch(Exception e) {
1573 e.printStackTrace();
1574 } finally {
1575 Log.d(LOGTAG, "reset and release of mRecorder");
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301576 mRecorder.reset();
1577 mRecorder.release();
1578 mRecorder = null;
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301579 }
Smriti Guptada03ddb2016-08-03 16:11:05 +05301580 mSampleLength = (int)(SystemClock.elapsedRealtime() - mSampleStart);
1581 Log.d(LOGTAG, "Sample length is " + mSampleLength);
1582
1583 if (mSampleLength == 0)
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301584 return;
Rupesh Tatiya9a50d9a2016-01-19 21:54:49 +05301585 String state = Environment.getExternalStorageState(mStoragePath);
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301586 Log.d(LOGTAG, "storage state is " + state);
1587
1588 if (Environment.MEDIA_MOUNTED.equals(state)) {
1589 try {
1590 this.addToMediaDB(mSampleFile);
1591 Toast.makeText(this,getString(R.string.save_record_file,
1592 mSampleFile.getAbsolutePath( )),
1593 Toast.LENGTH_LONG).show();
1594 } catch(Exception e) {
1595 e.printStackTrace();
1596 }
1597 } else {
1598 Log.e(LOGTAG, "SD card must have removed during recording. ");
1599 Toast.makeText(this, "Recording aborted", Toast.LENGTH_SHORT).show();
1600 }
1601 try {
1602 if((mServiceInUse) && (mCallbacks != null) ) {
1603 mCallbacks.onRecordingStopped();
1604 }
1605 } catch (RemoteException e) {
1606 e.printStackTrace();
1607 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301608 return;
1609 }
1610
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301611 /*
1612 * Adds file and returns content uri.
1613 */
1614 private Uri addToMediaDB(File file) {
1615 Log.d(LOGTAG, "In addToMediaDB");
1616 Resources res = getResources();
1617 ContentValues cv = new ContentValues();
1618 long current = System.currentTimeMillis();
1619 long modDate = file.lastModified();
1620 Date date = new Date(current);
1621 SimpleDateFormat formatter = new SimpleDateFormat(
1622 res.getString(R.string.audio_db_title_format));
1623 String title = formatter.format(date);
1624
1625 // Lets label the recorded audio file as NON-MUSIC so that the file
1626 // won't be displayed automatically, except for in the playlist.
1627 cv.put(MediaStore.Audio.Media.IS_MUSIC, "1");
Smriti Guptada03ddb2016-08-03 16:11:05 +05301628 cv.put(MediaStore.Audio.Media.DURATION, mSampleLength);
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301629 cv.put(MediaStore.Audio.Media.TITLE, title);
1630 cv.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
1631 cv.put(MediaStore.Audio.Media.DATE_ADDED, (int) (current / 1000));
1632 cv.put(MediaStore.Audio.Media.DATE_MODIFIED, (int) (modDate / 1000));
himta ramcbc2e452019-04-08 17:33:20 +05301633 cv.put(MediaStore.Audio.Media.MIME_TYPE, "audio/aac_mp4");
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301634 cv.put(MediaStore.Audio.Media.ARTIST,
1635 res.getString(R.string.audio_db_artist_name));
1636 cv.put(MediaStore.Audio.Media.ALBUM,
1637 res.getString(R.string.audio_db_album_name));
1638 Log.d(LOGTAG, "Inserting audio record: " + cv.toString());
1639 ContentResolver resolver = getContentResolver();
1640 Uri base = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
1641 Log.d(LOGTAG, "ContentURI: " + base);
1642 Uri result = resolver.insert(base, cv);
1643 if (result == null) {
1644 Toast.makeText(this, "Unable to save recorded audio", Toast.LENGTH_SHORT).show();
1645 return null;
1646 }
1647 if (getPlaylistId(res) == -1) {
1648 createPlaylist(res, resolver);
1649 }
1650 int audioId = Integer.valueOf(result.getLastPathSegment());
1651 addToPlaylist(resolver, audioId, getPlaylistId(res));
1652
1653 // Notify those applications such as Music listening to the
1654 // scanner events that a recorded audio file just created.
1655 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
1656 return result;
1657 }
1658
1659 private int getPlaylistId(Resources res) {
1660 Uri uri = MediaStore.Audio.Playlists.getContentUri("external");
1661 final String[] ids = new String[] { MediaStore.Audio.Playlists._ID };
1662 final String where = MediaStore.Audio.Playlists.NAME + "=?";
1663 final String[] args = new String[] { res.getString(R.string.audio_db_playlist_name) };
1664 Cursor cursor = query(uri, ids, where, args, null);
1665 if (cursor == null) {
1666 Log.v(LOGTAG, "query returns null");
1667 }
1668 int id = -1;
1669 if (cursor != null) {
1670 cursor.moveToFirst();
1671 if (!cursor.isAfterLast()) {
1672 id = cursor.getInt(0);
1673 }
1674 cursor.close();
1675 }
1676 return id;
1677 }
1678
1679 private Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
1680 try {
1681 ContentResolver resolver = getContentResolver();
1682 if (resolver == null) {
1683 return null;
1684 }
1685 return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
1686 } catch (UnsupportedOperationException ex) {
1687 return null;
1688 }
1689 }
1690
1691 private Uri createPlaylist(Resources res, ContentResolver resolver) {
1692 ContentValues cv = new ContentValues();
1693 cv.put(MediaStore.Audio.Playlists.NAME, res.getString(R.string.audio_db_playlist_name));
1694 Uri uri = resolver.insert(MediaStore.Audio.Playlists.getContentUri("external"), cv);
1695 if (uri == null) {
1696 Toast.makeText(this, "Unable to save recorded audio", Toast.LENGTH_SHORT).show();
1697 }
1698 return uri;
1699 }
1700
1701 private void addToPlaylist(ContentResolver resolver, int audioId, long playlistId) {
1702 String[] cols = new String[] {
himta ramcbc2e452019-04-08 17:33:20 +05301703 MediaStore.Audio.Media.ALBUM_ID
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301704 };
1705 Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
1706 Cursor cur = resolver.query(uri, cols, null, null, null);
1707 final int base;
himta ramcbc2e452019-04-08 17:33:20 +05301708 if(cur != null && cur.getCount() != 0) {
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05301709 cur.moveToFirst();
1710 base = cur.getInt(0);
1711 cur.close();
1712 }
1713 else {
1714 base = 0;
1715 }
1716 ContentValues values = new ContentValues();
1717 values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(base + audioId));
1718 values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, audioId);
1719 resolver.insert(uri, values);
1720 }
1721
Kamal Negib59ccc52017-04-04 16:07:28 +05301722 private void resumeAfterCall() {
1723 if (getCallState() != TelephonyManager.CALL_STATE_IDLE)
1724 return;
Kamal Negicd9ddcd2017-03-13 18:01:03 +05301725
Kamal Negib59ccc52017-04-04 16:07:28 +05301726 // start playing again
1727 if (!mResumeAfterCall)
1728 return;
Kamal Negicd9ddcd2017-03-13 18:01:03 +05301729
Kamal Negib59ccc52017-04-04 16:07:28 +05301730 // resume playback only if FM Radio was playing
1731 // when the call was answered
1732 if (isAntennaAvailable() && (!isFmOn()) && mServiceInUse) {
1733 Log.d(LOGTAG, "Resuming after call:");
1734 if(!fmOn()) {
1735 return;
1736 }
1737 mResumeAfterCall = false;
1738 if (mCallbacks != null) {
1739 try {
1740 mCallbacks.onEnabled();
1741 } catch (RemoteException e) {
1742 e.printStackTrace();
Mingbo Zhange579ce12017-01-13 10:53:00 +08001743 }
Edward Wang6844bc52015-04-09 16:06:02 -07001744 } else if (mFreq > 0) {
1745 tune(mFreq);
Mingbo Zhange579ce12017-01-13 10:53:00 +08001746 }
1747 }
Kamal Negib59ccc52017-04-04 16:07:28 +05301748 }
Mingbo Zhange579ce12017-01-13 10:53:00 +08001749
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301750 private void fmActionOnCallState( int state ) {
1751 //if Call Status is non IDLE we need to Mute FM as well stop recording if
1752 //any. Similarly once call is ended FM should be unmuted.
1753 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
1754 mCallStatus = state;
Smriti Gupta9a2f2372016-08-31 13:40:24 +05301755 int granted = AudioManager.AUDIOFOCUS_REQUEST_FAILED, count = 0;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301756
1757 if((TelephonyManager.CALL_STATE_OFFHOOK == state)||
1758 (TelephonyManager.CALL_STATE_RINGING == state)) {
Venkateshwarlu Domakonda14101f92015-09-03 22:08:34 +05301759 boolean bTempSpeaker = mSpeakerPhoneOn ; //need to restore SpeakerPhone
Venkateshwarlu Domakonda2c571ee2014-09-15 17:35:29 +05301760 boolean bTempMute = mMuted;// need to restore Mute status
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301761 int bTempCall = mCallStatus;//need to restore call status
Ayaz Ahmadb7cd23b2013-08-01 11:49:05 +05301762 if (isFmOn() && fmOff()) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301763 if((mServiceInUse) && (mCallbacks != null)) {
1764 try {
1765 mCallbacks.onDisabled();
1766 } catch (RemoteException e) {
1767 e.printStackTrace();
1768 }
1769 }
1770 mResumeAfterCall = true;
1771 mSpeakerPhoneOn = bTempSpeaker;
1772 mCallStatus = bTempCall;
Venkateshwarlu Domakonda2c571ee2014-09-15 17:35:29 +05301773 mMuted = bTempMute;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301774 } else if (!mResumeAfterCall) {
1775 mResumeAfterCall = false;
1776 mSpeakerPhoneOn = bTempSpeaker;
1777 mCallStatus = bTempCall;
Venkateshwarlu Domakonda2c571ee2014-09-15 17:35:29 +05301778 mMuted = bTempMute;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301779 }
Kamal Negib59ccc52017-04-04 16:07:28 +05301780 } else if (TelephonyManager.CALL_STATE_IDLE == state) {
himta ram4ea040c2019-06-04 12:04:45 +05301781 /* do not resume FM after call when fm stopped on focus loss */
1782 if(mStoppedOnFocusLoss == false) {
1783 resumeAfterCall();
1784 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301785 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301786 }
1787
1788 /* Handle Phone Call + FM Concurrency */
1789 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
1790 @Override
1791 public void onCallStateChanged(int state, String incomingNumber) {
1792 Log.d(LOGTAG, "onCallStateChanged: State - " + state );
1793 Log.d(LOGTAG, "onCallStateChanged: incomingNumber - " + incomingNumber );
1794 fmActionOnCallState(state );
1795 }
1796
1797 @Override
1798 public void onDataActivity (int direction) {
1799 Log.d(LOGTAG, "onDataActivity - " + direction );
1800 if (direction == TelephonyManager.DATA_ACTIVITY_NONE ||
1801 direction == TelephonyManager.DATA_ACTIVITY_DORMANT) {
1802 if (mReceiver != null) {
1803 Message msg = mDelayedStopHandler.obtainMessage(RESET_NOTCH_FILTER);
1804 mDelayedStopHandler.sendMessageDelayed(msg, 10000);
1805 }
1806 } else {
1807 if (mReceiver != null) {
Rupesh Tatiya8d881502016-01-12 18:37:31 +05301808 synchronized (mNotchFilterLock) {
1809 if (true == mNotchFilterSet) {
1810 mDelayedStopHandler.removeMessages(RESET_NOTCH_FILTER);
1811 } else {
1812 mReceiver.setNotchFilter(true);
1813 mNotchFilterSet = true;
1814 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301815 }
1816 }
1817 }
1818 }
1819 };
1820
Erfan Abdi60258312019-08-21 17:25:21 +04301821 private class AudioRoutingListener implements AudioRouting.OnRoutingChangedListener {
1822 public void onRoutingChanged(AudioRouting audioRouting) {
1823 Log.d(LOGTAG," onRoutingChanged + currdevice " + mCurrentDevice);
1824 AudioDeviceInfo routedDevice = audioRouting.getRoutedDevice();
1825 // if routing is nowhere, we get routedDevice as null
1826 if(routedDevice != null) {
1827 Log.d(LOGTAG," Audio Routed to device id " + routedDevice.getType());
1828 if(routedDevice.getType() != mCurrentDevice) {
1829 startApplicationLoopBack(mCurrentDevice);
1830 }
1831 }
1832 }
1833 }
1834
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301835 private Handler mDelayedStopHandler = new Handler() {
1836 @Override
1837 public void handleMessage(Message msg) {
1838 switch (msg.what) {
1839 case FM_STOP:
1840 // Check again to make sure nothing is playing right now
1841 if (isFmOn() || mServiceInUse)
1842 {
1843 return;
1844 }
1845 Log.d(LOGTAG, "mDelayedStopHandler: stopSelf");
1846 stopSelf(mServiceStartId);
1847 break;
1848 case RESET_NOTCH_FILTER:
Rupesh Tatiya8d881502016-01-12 18:37:31 +05301849 synchronized (mNotchFilterLock) {
1850 if (false == mNotchFilterSet)
1851 break;
1852 if (mReceiver != null) {
1853 mReceiver.setNotchFilter(false);
1854 mNotchFilterSet = false;
1855 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301856 }
1857 break;
1858 case STOPSERVICE_ONSLEEP:
1859 fmOff();
1860 break;
1861 case STOPRECORD_ONTIMEOUT:
1862 stopRecording();
1863 break;
1864 case FOCUSCHANGE:
Mingbo Zhange579ce12017-01-13 10:53:00 +08001865 if( !isFmOn() && !mResumeAfterCall) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301866 Log.v(LOGTAG, "FM is not running, not handling change");
1867 return;
1868 }
1869 switch (msg.arg1) {
Kamal Negib35787e2016-07-13 11:29:06 +05301870 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
1871 Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
himta ram198e3282019-06-13 14:57:47 +05301872 mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
1873 int mCurrentVolumeIndex =
1874 mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
1875 Log.d(LOGTAG, "Current Volume Index = "+ mCurrentVolumeIndex);
1876 /* lower fm volume only if fm audio playing above default volume index */
1877 if (mCurrentVolumeIndex > DEFAULT_VOLUME_INDEX) {
1878 setFMVolume(DEFAULT_VOLUME_INDEX);
himta ram92ff2d42018-03-23 17:24:00 +05301879 }
Venkateshwarlu Domakonda0053a012014-04-21 14:26:56 +05301880 break;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301881 case AudioManager.AUDIOFOCUS_LOSS:
Balvinder Singh7b765532017-08-04 15:45:28 +05301882 Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS mspeakerphone= " +
1883 mSpeakerPhoneOn);
himta ram198e3282019-06-13 14:57:47 +05301884 if (mSpeakerPhoneOn) {
1885 if (isAnalogModeSupported())
1886 setAudioPath(false);
1887 }
1888 if (mSession.isActive()) {
1889 mSession.setActive(false);
1890 }
himta ram92ff2d42018-03-23 17:24:00 +05301891 //intentional fall through.
himta ram198e3282019-06-13 14:57:47 +05301892 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
1893 Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_LOSS_TRANSIENT");
himta ramd1e63c22019-06-27 15:04:35 +05301894 if (mReceiver != null && mReceiver.isCherokeeChip() &&
1895 (mPref.getBoolean("SLIMBUS_SEQ", true))) {
himta rame4684822018-07-04 11:24:04 +05301896 enableSlimbus(DISABLE_SLIMBUS_DATA_PORT);
himta ram92ff2d42018-03-23 17:24:00 +05301897 }
Ayaz Ahmadd405c1d2013-07-31 13:41:16 +05301898 if (true == mPlaybackInProgress) {
Satish Kodishala96089312013-12-24 11:26:48 +05301899 stopFM();
1900 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05301901
Satish kumar sugasieead6722016-10-18 14:47:46 -07001902 if (true == isFmRecordingOn())
1903 stopRecording();
1904
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301905 mStoppedOnFocusLoss = true;
1906 break;
1907 case AudioManager.AUDIOFOCUS_GAIN:
Balvinder Singh7b765532017-08-04 15:45:28 +05301908 Log.v(LOGTAG, "AudioFocus: received AUDIOFOCUS_GAIN mPlaybackinprogress =" +
1909 mPlaybackInProgress);
Mingbo Zhange579ce12017-01-13 10:53:00 +08001910 mStoppedOnFocusLoss = false;
1911 if (mResumeAfterCall) {
1912 Log.v(LOGTAG, "resumeAfterCall");
Kamal Negib59ccc52017-04-04 16:07:28 +05301913 resumeAfterCall();
Mingbo Zhange579ce12017-01-13 10:53:00 +08001914 break;
1915 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05301916
himta ramdd027a32019-01-18 20:50:08 +05301917 if(false == mPlaybackInProgress) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301918 startFM();
himta ramd1e63c22019-06-27 15:04:35 +05301919 if (mReceiver != null && mReceiver.isCherokeeChip() &&
himta ramdd027a32019-01-18 20:50:08 +05301920 (mPref.getBoolean("SLIMBUS_SEQ", true))) {
1921 enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
1922 }
himta ram198e3282019-06-13 14:57:47 +05301923 } else {
1924 /* This case usually happens, when FM volume is lowered down and Playback
1925 * In Progress on AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK recived. Need
1926 * to restore volume level back when AUDIOFOCUS_GAIN received
1927 */
1928 setCurrentFMVolume();
himta ramdd027a32019-01-18 20:50:08 +05301929 }
himta ram198e3282019-06-13 14:57:47 +05301930 if (!mSession.isActive()) {
1931 mSession.setActive(true);
1932 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301933 break;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05301934 default:
1935 Log.e(LOGTAG, "Unknown audio focus change code"+msg.arg1);
1936 }
1937 break;
1938 }
1939 }
1940 };
1941
1942
1943 /**
1944 * Registers an intent to listen for
1945 * ACTION_SCREEN_ON/ACTION_SCREEN_OFF notifications. This intent
1946 * is called to know iwhen the screen is turned on/off.
1947 */
1948 public void registerScreenOnOffListener() {
1949 if (mScreenOnOffReceiver == null) {
1950 mScreenOnOffReceiver = new BroadcastReceiver() {
1951 @Override
1952 public void onReceive(Context context, Intent intent) {
1953 String action = intent.getAction();
1954 if (action.equals(Intent.ACTION_SCREEN_ON)) {
1955 Log.d(LOGTAG, "ACTION_SCREEN_ON Intent received");
1956 //Screen turned on, set FM module into normal power mode
1957 mHandler.post(mScreenOnHandler);
1958 }
1959 else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
1960 Log.d(LOGTAG, "ACTION_SCREEN_OFF Intent received");
1961 //Screen turned on, set FM module into low power mode
1962 mHandler.post(mScreenOffHandler);
1963 }
1964 }
1965 };
1966 IntentFilter iFilter = new IntentFilter();
1967 iFilter.addAction(Intent.ACTION_SCREEN_ON);
1968 iFilter.addAction(Intent.ACTION_SCREEN_OFF);
1969 registerReceiver(mScreenOnOffReceiver, iFilter);
1970 }
1971 }
1972
1973 /* Handle all the Screen On actions:
1974 Set FM Power mode to Normal
1975 */
1976 final Runnable mScreenOnHandler = new Runnable() {
1977 public void run() {
1978 setLowPowerMode(false);
1979 }
1980 };
1981 /* Handle all the Screen Off actions:
1982 Set FM Power mode to Low Power
1983 This will reduce all the interrupts coming up from the SoC, saving power
1984 */
1985 final Runnable mScreenOffHandler = new Runnable() {
1986 public void run() {
1987 setLowPowerMode(true);
1988 }
1989 };
1990
1991 /* Show the FM Notification */
1992 public void startNotification() {
Nitin Shivpure9eb64372017-04-19 17:59:54 +05301993 Log.d(LOGTAG,"startNotification");
1994
himta ram5c7f7db2018-06-05 16:25:55 +05301995 synchronized (mNotificationLock) {
himta ram5c7f7db2018-06-05 16:25:55 +05301996 Context context = getApplicationContext();
1997 Notification notification;
1998 NotificationManager notificationManager =
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +05301999 (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
himta ram5c7f7db2018-06-05 16:25:55 +05302000 NotificationChannel notificationChannel =
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +05302001 new NotificationChannel(FMRADIO_NOTIFICATION_CHANNEL,
2002 context.getString(R.string.app_name),
Nitin Shivpure35a359e2017-07-19 16:42:58 +05302003 NotificationManager.IMPORTANCE_LOW);
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +05302004
himta ram5c7f7db2018-06-05 16:25:55 +05302005 notificationManager.createNotificationChannel(notificationChannel);
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +05302006
himta ram5c7f7db2018-06-05 16:25:55 +05302007 notification = new Notification.Builder(context, FMRADIO_NOTIFICATION_CHANNEL)
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +05302008 .setSmallIcon(R.drawable.stat_notify_fm)
Konstae3e0b392013-07-16 19:15:42 +03002009 .setContentTitle(isFmOn() ? getString(R.string.app_name) : "")
2010 .setContentText(isFmOn() ? getTunedFrequencyString() : "")
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +05302011 .setContentIntent(PendingIntent.getActivity(this,
2012 0, new Intent("com.caf.fmradio.FMRADIO_ACTIVITY"), 0))
2013 .setOngoing(true)
2014 .build();
2015
himta ram5c7f7db2018-06-05 16:25:55 +05302016 startForeground(FMRADIOSERVICE_STATUS, notification);
2017 mFMOn = true;
2018 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302019 }
2020
2021 private void stop() {
2022 Log.d(LOGTAG,"in stop");
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05302023
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302024 if (!mServiceInUse) {
himta ramdfa45932019-03-07 17:57:54 +05302025 Log.d(LOGTAG,"release media session");
2026 mSession.release();
himta rame8d9d382018-12-06 16:18:34 +05302027 }
2028 if (mSession.isActive()) {
2029 mSession.setActive(false);
2030 Log.d(LOGTAG,"mSession is not active");
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302031 }
2032 gotoIdleState();
2033 mFMOn = false;
2034 }
2035
2036 private void gotoIdleState() {
2037 mDelayedStopHandler.removeCallbacksAndMessages(null);
2038 cancelAlarms();
2039 setAlarmDelayedServiceStop();
2040 stopForeground(true);
2041 }
2042
2043 /** Read's the internal Antenna available state from the FM
2044 * Device.
2045 */
2046 public void readInternalAntennaAvailable()
2047 {
2048 mInternalAntennaAvailable = false;
2049 if (mReceiver != null)
2050 {
2051 mInternalAntennaAvailable = mReceiver.getInternalAntenna();
2052 Log.d(LOGTAG, "getInternalAntenna: " + mInternalAntennaAvailable);
2053 }
2054 }
2055
2056 /*
2057 * By making this a static class with a WeakReference to the Service, we
2058 * ensure that the Service can be GCd even when the system process still
2059 * has a remote reference to the stub.
2060 */
2061 static class ServiceStub extends IFMRadioService.Stub
2062 {
2063 WeakReference<FMRadioService> mService;
2064
2065 ServiceStub(FMRadioService service)
2066 {
2067 mService = new WeakReference<FMRadioService>(service);
2068 }
2069
2070 public boolean fmOn() throws RemoteException
2071 {
2072 return(mService.get().fmOn());
2073 }
2074
2075 public boolean fmOff() throws RemoteException
2076 {
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05302077 return(mService.get().fmOff(FM_OFF_FROM_APPLICATION));
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302078 }
2079
2080 public boolean fmRadioReset() throws RemoteException
2081 {
2082 return true;
2083 }
2084
2085 public boolean isFmOn()
2086 {
2087 return(mService.get().isFmOn());
2088 }
2089
2090 public boolean isAnalogModeEnabled()
2091 {
2092 return(mService.get().isAnalogModeEnabled());
2093 }
2094
2095 public boolean isFmRecordingOn()
2096 {
2097 return(mService.get().isFmRecordingOn());
2098 }
2099
Venkateshwarlu Domakondad09c0882015-05-26 15:16:38 +05302100 public boolean isRtPlusSupported()
2101 {
2102 return(mService.get().isRtPlusSupported());
2103 }
2104
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302105 public boolean isSpeakerEnabled()
2106 {
2107 return(mService.get().isSpeakerEnabled());
2108 }
2109
2110 public boolean fmReconfigure()
2111 {
2112 return(mService.get().fmReconfigure());
2113 }
2114
2115 public void registerCallbacks(IFMRadioServiceCallbacks cb) throws RemoteException
2116 {
2117 mService.get().registerCallbacks(cb);
2118 }
2119
2120 public void unregisterCallbacks() throws RemoteException
2121 {
2122 mService.get().unregisterCallbacks();
2123 }
2124
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302125 public boolean mute()
2126 {
2127 return(mService.get().mute());
2128 }
2129
2130 public boolean unMute()
2131 {
2132 return(mService.get().unMute());
2133 }
2134
2135 public boolean isMuted()
2136 {
2137 return(mService.get().isMuted());
2138 }
2139
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05302140 public boolean startRecording()
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302141 {
Venkateshwarlu Domakonda3fc88f52015-07-22 18:39:42 +05302142 return(mService.get().startRecording());
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302143 }
2144
2145 public void stopRecording()
2146 {
2147 mService.get().stopRecording();
2148 }
2149
2150 public boolean tune(int frequency)
2151 {
2152 return(mService.get().tune(frequency));
2153 }
2154
2155 public boolean seek(boolean up)
2156 {
2157 return(mService.get().seek(up));
2158 }
2159
2160 public void enableSpeaker(boolean speakerOn)
2161 {
Kamal Negidd175dc2016-06-03 20:09:24 +05302162
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302163 mService.get().enableSpeaker(speakerOn);
2164 }
2165
2166 public boolean scan(int pty)
2167 {
2168 return(mService.get().scan(pty));
2169 }
2170
2171 public boolean seekPI(int piCode)
2172 {
2173 return(mService.get().seekPI(piCode));
2174 }
2175 public boolean searchStrongStationList(int numStations)
2176 {
2177 return(mService.get().searchStrongStationList(numStations));
2178 }
2179
2180 public boolean cancelSearch()
2181 {
2182 return(mService.get().cancelSearch());
2183 }
2184
2185 public String getProgramService()
2186 {
2187 return(mService.get().getProgramService());
2188 }
2189 public String getRadioText()
2190 {
2191 return(mService.get().getRadioText());
2192 }
2193 public String getExtenRadioText()
2194 {
2195 return(mService.get().getExtenRadioText());
2196 }
2197 public int getProgramType()
2198 {
2199 return(mService.get().getProgramType());
2200 }
2201 public int getProgramID()
2202 {
2203 return(mService.get().getProgramID());
2204 }
2205 public int[] getSearchList()
2206 {
2207 return(mService.get().getSearchList());
2208 }
2209
2210 public boolean setLowPowerMode(boolean enable)
2211 {
2212 return(mService.get().setLowPowerMode(enable));
2213 }
2214
2215 public int getPowerMode()
2216 {
2217 return(mService.get().getPowerMode());
2218 }
2219 public boolean enableAutoAF(boolean bEnable)
2220 {
2221 return(mService.get().enableAutoAF(bEnable));
2222 }
2223 public boolean enableStereo(boolean bEnable)
2224 {
2225 return(mService.get().enableStereo(bEnable));
2226 }
2227 public boolean isAntennaAvailable()
2228 {
2229 return(mService.get().isAntennaAvailable());
2230 }
2231 public boolean isWiredHeadsetAvailable()
2232 {
2233 return(mService.get().isWiredHeadsetAvailable());
2234 }
2235 public boolean isCallActive()
2236 {
2237 return(mService.get().isCallActive());
2238 }
2239 public int getRssi()
2240 {
2241 return (mService.get().getRssi());
2242 }
2243 public int getIoC()
2244 {
2245 return (mService.get().getIoC());
2246 }
2247 public int getMpxDcc()
2248 {
2249 return (mService.get().getMpxDcc());
2250 }
2251 public int getIntDet()
2252 {
2253 return (mService.get().getIntDet());
2254 }
2255 public void setHiLoInj(int inj)
2256 {
2257 mService.get().setHiLoInj(inj);
2258 }
2259 public void delayedStop(long duration, int nType)
2260 {
2261 mService.get().delayedStop(duration, nType);
2262 }
2263 public void cancelDelayedStop(int nType)
2264 {
2265 mService.get().cancelDelayedStop(nType);
2266 }
2267 public void requestFocus()
2268 {
2269 mService.get().requestFocus();
2270 }
2271 public int getSINR()
2272 {
2273 return (mService.get().getSINR());
2274 }
2275 public boolean setSinrSamplesCnt(int samplesCnt)
2276 {
2277 return (mService.get().setSinrSamplesCnt(samplesCnt));
2278 }
2279 public boolean setSinrTh(int sinr)
2280 {
2281 return (mService.get().setSinrTh(sinr));
2282 }
2283 public boolean setIntfDetLowTh(int intfLowTh)
2284 {
2285 return (mService.get().setIntfDetLowTh(intfLowTh));
2286 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05302287 public boolean getIntfDetLowTh()
2288 {
2289 return (mService.get().getIntfDetLowTh());
2290 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302291 public boolean setIntfDetHighTh(int intfHighTh)
2292 {
2293 return (mService.get().setIntfDetHighTh(intfHighTh));
2294 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05302295 public boolean getIntfDetHighTh()
2296 {
2297 return (mService.get().getIntfDetHighTh());
2298 }
Ayaz Ahmada32e3772013-07-31 12:24:29 +05302299 public int getSearchAlgoType()
2300 {
2301 return (mService.get().getSearchAlgoType());
2302 }
2303 public boolean setSearchAlgoType(int searchType)
2304 {
2305 return (mService.get().setSearchAlgoType(searchType));
2306 }
2307 public int getSinrFirstStage()
2308 {
2309 return (mService.get().getSinrFirstStage());
2310 }
2311 public boolean setSinrFirstStage(int sinr)
2312 {
2313 return (mService.get().setSinrFirstStage(sinr));
2314 }
2315 public int getRmssiFirstStage()
2316 {
2317 return (mService.get().getRmssiFirstStage());
2318 }
2319 public boolean setRmssiFirstStage(int rmssi)
2320 {
2321 return (mService.get().setRmssiFirstStage(rmssi));
2322 }
2323 public int getCFOMeanTh()
2324 {
2325 return (mService.get().getCFOMeanTh());
2326 }
2327 public boolean setCFOMeanTh(int th)
2328 {
2329 return (mService.get().setCFOMeanTh(th));
2330 }
2331 public int getSinrSamplesCnt()
2332 {
2333 return (mService.get().getSinrSamplesCnt());
2334 }
2335 public int getSinrTh()
2336 {
2337 return (mService.get().getSinrTh());
2338 }
2339 public int getAfJmpRmssiTh()
2340 {
2341 return (mService.get().getAfJmpRmssiTh());
2342 }
2343 public boolean setAfJmpRmssiTh(int afJmpRmssiTh)
2344 {
2345 return (mService.get().setAfJmpRmssiTh(afJmpRmssiTh));
2346 }
2347 public int getGoodChRmssiTh()
2348 {
2349 return (mService.get().getGoodChRmssiTh());
2350 }
2351 public boolean setGoodChRmssiTh(int gdChRmssiTh)
2352 {
2353 return (mService.get().setGoodChRmssiTh(gdChRmssiTh));
2354 }
2355 public int getAfJmpRmssiSamplesCnt()
2356 {
2357 return (mService.get().getAfJmpRmssiSamplesCnt());
2358 }
2359 public boolean setAfJmpRmssiSamplesCnt(int afJmpRmssiSmplsCnt)
2360 {
2361 return (mService.get().setAfJmpRmssiSamplesCnt(afJmpRmssiSmplsCnt));
2362 }
Ayaz Ahmad61bedff2013-07-31 13:04:19 +05302363 public boolean setRxRepeatCount(int count)
2364 {
2365 return (mService.get().setRxRepeatCount(count));
2366 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05302367 public boolean getRxRepeatCount()
2368 {
2369 return (mService.get().getRxRepeatCount());
2370 }
Ayaz Ahmad613e5832013-08-01 19:57:19 +05302371 public long getRecordingStartTime()
2372 {
2373 return (mService.get().getRecordingStartTime());
2374 }
Ayaz Ahmad594e34a2013-09-12 17:04:29 +05302375 public boolean isSleepTimerActive()
2376 {
2377 return (mService.get().isSleepTimerActive());
2378 }
Satish Kodishala454dd9e2014-11-20 15:34:46 +05302379 public boolean isSSRInProgress()
2380 {
2381 return(mService.get().isSSRInProgress());
2382 }
Venkateshwarlu Domakonda9c555962015-09-15 13:06:58 +05302383 public boolean isA2DPConnected()
2384 {
2385 return(mService.get().isA2DPConnected());
2386 }
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05302387
Danesh Mf6600ec2015-08-14 11:20:31 -07002388 public boolean isSearchInProgress()
2389 {
2390 return(mService.get().isSearchInProgress());
2391 }
2392
Danesh M94cab4e2015-08-19 15:43:48 -07002393 public List<Integer> getScannedFrequencies()
2394 {
2395 return(mService.get().getScannedFrequencies());
2396 }
2397
Satish kumar sugasid8731b72016-01-27 14:45:45 -08002398 public int getExtenCountryCode()
2399 {
2400 return(mService.get().getExtenCountryCode());
2401 }
Kamal Negidd175dc2016-06-03 20:09:24 +05302402
2403 public void restoreDefaults()
2404 {
2405 mService.get().restoreDefaults();
2406 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302407 }
2408 private final IBinder mBinder = new ServiceStub(this);
2409
2410 private boolean setAudioPath(boolean analogMode) {
2411
2412 if (mReceiver == null) {
2413 return false;
2414 }
2415 if (isAnalogModeEnabled() == analogMode) {
2416 Log.d(LOGTAG,"Analog Path already is set to "+analogMode);
2417 return false;
2418 }
2419 if (!isAnalogModeSupported()) {
2420 Log.d(LOGTAG,"Analog Path is not supported ");
2421 return false;
2422 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302423
2424 boolean state = mReceiver.setAnalogMode(analogMode);
2425 if (false == state) {
2426 Log.d(LOGTAG, "Error in toggling analog/digital path " + analogMode);
2427 return false;
2428 }
2429 misAnalogPathEnabled = analogMode;
2430 return true;
2431 }
Kamal Negi6c3e6892017-03-15 14:05:32 +05302432 private boolean waitForEvent() {
2433 boolean status = false;
2434
2435 synchronized (mEventWaitLock) {
2436 Log.d(LOGTAG, "waiting for event");
2437 try {
2438 if (mEventReceived == false)
2439 mEventWaitLock.wait(RADIO_TIMEOUT);
2440 if (mEventReceived == true)
2441 status = true;
2442 } catch (IllegalMonitorStateException e) {
2443 Log.e(LOGTAG, "Exception caught while waiting for event");
2444 e.printStackTrace();
2445 } catch (InterruptedException ex) {
2446 Log.e(LOGTAG, "Exception caught while waiting for event");
2447 ex.printStackTrace();
2448 }
2449 }
2450 return status;
2451 }
2452
Smriti Guptaab10c8b2017-09-06 16:48:48 +05302453 private boolean waitForFWEvent() {
2454 boolean status = false;
2455
2456 synchronized (mEventWaitLock) {
2457 Log.d(LOGTAG, "waiting for FW event");
2458 try {
2459 if (mEventReceived == false)
2460 mEventWaitLock.wait(FW_TIMEOUT);
2461 if (mEventReceived == true) {
2462 status = true;
2463 }
2464 } catch (IllegalMonitorStateException e) {
2465 Log.e(LOGTAG, "Exception caught while waiting for event");
2466 e.printStackTrace();
2467 } catch (InterruptedException ex) {
2468 Log.e(LOGTAG, "Exception caught while waiting for event");
2469 ex.printStackTrace();
2470 }
2471 }
2472 return status;
2473 }
2474
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302475 private boolean fmTurnOnSequence () {
2476 boolean bStatus = false;
2477 // This sets up the FM radio device
2478 FmConfig config = FmSharedPreferences.getFMConfiguration();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302479
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302480 Log.d(LOGTAG, "fmOn: RadioBand :"+ config.getRadioBand());
2481 Log.d(LOGTAG, "fmOn: Emphasis :"+ config.getEmphasis());
2482 Log.d(LOGTAG, "fmOn: ChSpacing :"+ config.getChSpacing());
2483 Log.d(LOGTAG, "fmOn: RdsStd :"+ config.getRdsStd());
2484 Log.d(LOGTAG, "fmOn: LowerLimit :"+ config.getLowerLimit());
2485 Log.d(LOGTAG, "fmOn: UpperLimit :"+ config.getUpperLimit());
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302486
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302487 mEventReceived = false;
2488 bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration(), this);
Kamal Negi6c3e6892017-03-15 14:05:32 +05302489
Smriti Guptaab10c8b2017-09-06 16:48:48 +05302490 if (mReceiver.isCherokeeChip()) {
2491 bStatus = waitForEvent();
2492 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302493 if (isSpeakerEnabled()) {
2494 setAudioPath(false);
2495 } else {
2496 setAudioPath(true);
2497 }
2498 Log.d(LOGTAG, "mReceiver.enable done, Status :" + bStatus);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302499
2500 if (bStatus == true)
2501 {
2502 /* Put the hardware into normal mode */
2503 bStatus = setLowPowerMode(false);
2504 Log.d(LOGTAG, "setLowPowerMode done, Status :" + bStatus);
2505
2506
2507 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
2508 if( (audioManager != null) &&(false == mPlaybackInProgress) )
2509 {
2510 Log.d(LOGTAG, "mAudioManager.setFmRadioOn = true \n" );
2511 //audioManager.setParameters("FMRadioOn="+mAudioDevice);
2512 int state = getCallState();
2513 if ( TelephonyManager.CALL_STATE_IDLE != getCallState() )
2514 {
2515 fmActionOnCallState(state);
2516 } else {
2517 startFM(); // enable FM Audio only when Call is IDLE
2518 }
2519 Log.d(LOGTAG, "mAudioManager.setFmRadioOn done \n" );
2520 }
2521 if (mReceiver != null) {
2522 bStatus = mReceiver.registerRdsGroupProcessing(FmReceiver.FM_RX_RDS_GRP_RT_EBL|
2523 FmReceiver.FM_RX_RDS_GRP_PS_EBL|
2524 FmReceiver.FM_RX_RDS_GRP_AF_EBL|
Satish kumar sugasib0ba3c82016-05-04 20:18:23 -07002525 FmReceiver.FM_RX_RDS_GRP_PS_SIMPLE_EBL|
2526 FmReceiver.FM_RX_RDS_GRP_ECC_EBL|
2527 FmReceiver.FM_RX_RDS_GRP_PTYN_EBL|
2528 FmReceiver.FM_RX_RDS_GRP_RT_PLUS_EBL);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302529 Log.d(LOGTAG, "registerRdsGroupProcessing done, Status :" + bStatus);
2530 }
2531 bStatus = enableAutoAF(FmSharedPreferences.getAutoAFSwitch());
2532 Log.d(LOGTAG, "enableAutoAF done, Status :" + bStatus);
2533
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302534 readInternalAntennaAvailable();
2535
Brinly Taylor6b384e32015-02-07 15:29:00 +10302536 bStatus = mReceiver.setInternalAntenna(mInternalAntennaAvailable);
2537 Log.d(LOGTAG, "setInternalAntenna done, Status :" + bStatus);
2538
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302539 startNotification();
2540 bStatus = true;
2541 }
2542 else
2543 {
Smriti Guptabfc78cb2017-08-30 14:18:07 +05302544 if ((mReceiver.getFMState() != mReceiver.subPwrLevel_FMRx_Starting) &&
2545 (mReceiver.getFMState() != mReceiver.FMState_Rx_Turned_On)) {
2546 mReceiver = null; // as enable failed no need to disable
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302547 // failure of enable can be because handle
2548 // already open which gets effected if
2549 // we disable
Smriti Guptabfc78cb2017-08-30 14:18:07 +05302550 stop();
2551 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302552 }
Satish Kodishala454dd9e2014-11-20 15:34:46 +05302553
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302554 return bStatus;
2555 }
2556
himta rame4684822018-07-04 11:24:04 +05302557 private boolean enableSlimbus(int flag) {
2558 Log.d(LOGTAG, "enableSlimbus");
Smriti Guptaab10c8b2017-09-06 16:48:48 +05302559 boolean bStatus = false;
2560 // Send command to enable FM core
2561 mEventReceived = false;
himta rame4684822018-07-04 11:24:04 +05302562 mReceiver.EnableSlimbus(flag);
Smriti Guptaab10c8b2017-09-06 16:48:48 +05302563 bStatus = waitForFWEvent();
2564 return bStatus;
2565 }
2566
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302567 /*
2568 * Turn ON FM: Powers up FM hardware, and initializes the FM module
2569 * .
2570 * @return true if fm Enable api was invoked successfully, false if the api failed.
2571 */
2572 private boolean fmTurnOnSequenceCherokee () {
2573 boolean bStatus = false;
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302574 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
2575 if ((audioManager != null) & (false == mPlaybackInProgress)) {
2576 Log.d(LOGTAG, "mAudioManager.setFmRadioOn = true \n" );
2577 int state = getCallState();
2578 if (TelephonyManager.CALL_STATE_IDLE != getCallState())
2579 {
2580 fmActionOnCallState(state);
2581 } else {
2582 startFM(); // enable FM Audio only when Call is IDLE
2583 }
2584 Log.d(LOGTAG, "mAudioManager.setFmRadioOn done \n" );
2585 }
2586
2587 // This sets up the FM radio device
2588 FmConfig config = FmSharedPreferences.getFMConfiguration();
2589 Log.d(LOGTAG, "fmOn: RadioBand :"+ config.getRadioBand());
2590 Log.d(LOGTAG, "fmOn: Emphasis :"+ config.getEmphasis());
2591 Log.d(LOGTAG, "fmOn: ChSpacing :"+ config.getChSpacing());
2592 Log.d(LOGTAG, "fmOn: RdsStd :"+ config.getRdsStd());
2593 Log.d(LOGTAG, "fmOn: LowerLimit :"+ config.getLowerLimit());
2594 Log.d(LOGTAG, "fmOn: UpperLimit :"+ config.getUpperLimit());
2595
2596 // Enable FM receiver
2597 mEventReceived = false;
2598 bStatus = mReceiver.enable(FmSharedPreferences.getFMConfiguration(), this);
2599 bStatus = waitForEvent();
himta ram1f23f3a2019-03-20 12:05:22 +05302600 mReceiver.setRawRdsGrpMask();
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302601
2602 if (isSpeakerEnabled()) {
2603 setAudioPath(false);
2604 } else {
2605 setAudioPath(true);
2606 }
2607 Log.d(LOGTAG, "mReceiver.enable done, Status :" + bStatus);
2608
2609 if (bStatus == true) {
2610 /* Put the hardware into normal mode */
2611 bStatus = setLowPowerMode(false);
2612 Log.d(LOGTAG, "setLowPowerMode done, Status :" + bStatus);
2613
2614 if (mReceiver != null) {
2615 bStatus = mReceiver.registerRdsGroupProcessing(FmReceiver.FM_RX_RDS_GRP_RT_EBL|
2616 FmReceiver.FM_RX_RDS_GRP_PS_EBL|
2617 FmReceiver.FM_RX_RDS_GRP_AF_EBL|
2618 FmReceiver.FM_RX_RDS_GRP_PS_SIMPLE_EBL|
2619 FmReceiver.FM_RX_RDS_GRP_ECC_EBL|
2620 FmReceiver.FM_RX_RDS_GRP_PTYN_EBL|
2621 FmReceiver.FM_RX_RDS_GRP_RT_PLUS_EBL);
2622 Log.d(LOGTAG, "registerRdsGroupProcessing done, Status :" + bStatus);
2623 }
2624 bStatus = enableAutoAF(FmSharedPreferences.getAutoAFSwitch());
2625 Log.d(LOGTAG, "enableAutoAF done, Status :" + bStatus);
2626
2627 /* There is no internal Antenna*/
2628 bStatus = mReceiver.setInternalAntenna(false);
2629 Log.d(LOGTAG, "setInternalAntenna done, Status :" + bStatus);
2630
2631 /* Read back to verify the internal Antenna mode*/
2632 readInternalAntennaAvailable();
2633
2634 startNotification();
2635 bStatus = true;
2636 } else {
2637 mReceiver = null; // as enable failed no need to disable
2638 // failure of enable can be because handle
2639 // already open which gets effected if
2640 // we disable
himta ramdfa45932019-03-07 17:57:54 +05302641 audioManager.abandonAudioFocusRequest(mGainFocusReq);
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302642 stop();
2643 }
2644
2645 return bStatus;
2646 }
2647
2648 /*
2649 * Turn ON FM: Powers up FM hardware, and initializes the FM module
2650 * .
2651 * @return true if fm Enable api was invoked successfully, false if the api failed.
2652 */
2653 private boolean fmOn () {
2654 boolean bStatus = false;
2655 mWakeLock.acquire(10*1000);
2656
2657 if (TelephonyManager.CALL_STATE_IDLE != getCallState()) {
2658 return bStatus;
2659 }
2660
2661 if (mReceiver == null)
2662 {
2663 try {
2664 mReceiver = new FmReceiver(FMRADIO_DEVICE_FD_STRING, fmCallbacks);
himta rame628c052018-07-06 20:26:48 +05302665 isfmOffFromApplication = false;
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302666 }
2667 catch (InstantiationException e)
2668 {
2669 throw new RuntimeException("FmReceiver service not available!");
2670 }
2671 }
2672
2673 if (mReceiver != null)
2674 {
2675 if (isFmOn())
2676 {
2677 /* FM Is already on,*/
2678 bStatus = true;
2679 Log.d(LOGTAG, "mReceiver.already enabled");
2680 }
2681 else
2682 {
2683 if (mReceiver.isCherokeeChip()) {
himta ramdd027a32019-01-18 20:50:08 +05302684 if (mPref.getBoolean("SLIMBUS_SEQ", true)) {
2685 enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
2686 }
himta rama1c405b2018-07-11 17:13:56 +05302687 bStatus = fmTurnOnSequenceCherokee();
2688 } else {
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302689 bStatus = fmTurnOnSequence();
himta rama1c405b2018-07-11 17:13:56 +05302690 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05302691 /* reset SSR flag */
2692 mIsSSRInProgressFromActivity = false;
2693 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302694 }
2695 return(bStatus);
2696 }
2697
2698 /*
2699 * Turn OFF FM Operations: This disables all the current FM operations .
2700 */
2701 private void fmOperationsOff() {
Satish kumar sugasieead6722016-10-18 14:47:46 -07002702 // disable audio path
2703 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
2704 if(audioManager != null)
2705 {
2706 Log.d(LOGTAG, "audioManager.setFmRadioOn = false \n" );
2707 stopFM();
2708 unMute();
Mingbo Zhange579ce12017-01-13 10:53:00 +08002709 // If call is active, we will use audio focus to resume fm after call ends.
2710 // So don't abandon audiofocus automatically
2711 if (getCallState() == TelephonyManager.CALL_STATE_IDLE) {
himta ramdfa45932019-03-07 17:57:54 +05302712 audioManager.abandonAudioFocusRequest(mGainFocusReq);
Mingbo Zhange579ce12017-01-13 10:53:00 +08002713 mStoppedOnFocusLoss = true;
2714 }
Satish kumar sugasieead6722016-10-18 14:47:46 -07002715 //audioManager.setParameters("FMRadioOn=false");
2716 Log.d(LOGTAG, "audioManager.setFmRadioOn false done \n" );
2717 }
Rupesh Tatiya1314b052016-02-25 13:09:30 +05302718 // stop recording
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302719 if (isFmRecordingOn())
2720 {
2721 stopRecording();
Venkateshwarlu Domakonda8fff19e2014-04-16 17:18:37 +05302722 try {
2723 Thread.sleep(300);
2724 } catch (Exception ex) {
2725 Log.d( LOGTAG, "RunningThread InterruptedException");
2726 return;
2727 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302728 }
Kamal Negidd175dc2016-06-03 20:09:24 +05302729
Rupesh Tatiya1314b052016-02-25 13:09:30 +05302730 if (isMuted() == true)
2731 unMute();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302732
2733 if (isAnalogModeEnabled()) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302734 misAnalogPathEnabled = false;
2735 }
2736 }
2737
Satish kumar sugasieead6722016-10-18 14:47:46 -07002738
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302739 /*
2740 * Reset (OFF) FM Operations: This resets all the current FM operations .
2741 */
2742 private void fmOperationsReset() {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302743 if (isFmRecordingOn())
2744 {
Venkateshwarlu Domakondafa22ae12013-07-27 12:25:16 +05302745 stopRecording();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302746 }
2747
2748 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
2749 if(audioManager != null)
2750 {
2751 Log.d(LOGTAG, "audioManager.setFmRadioOn = false \n" );
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302752 resetFM();
2753 //audioManager.setParameters("FMRadioOn=false");
2754 Log.d(LOGTAG, "audioManager.setFmRadioOn false done \n" );
2755 }
2756
2757 if (isAnalogModeEnabled()) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302758 misAnalogPathEnabled = false;
2759 }
kexiao6d421312015-12-21 16:04:00 +08002760
2761 if ( mSpeakerPhoneOn) {
2762 mSpeakerPhoneOn = false;
kexiao6d421312015-12-21 16:04:00 +08002763 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302764 }
2765
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302766 private boolean fmOffImpl() {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302767 boolean bStatus=false;
2768
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302769 // This will disable the FM radio device
himta rambe1ab412018-11-22 13:28:00 +05302770 synchronized(mReceiverLock) {
2771 if (mReceiver != null)
2772 {
2773 bStatus = mReceiver.disable(this);
2774 mReceiver = null;
2775 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302776 }
Kamal Negif2f00702016-05-31 15:46:35 +05302777 fmOperationsOff();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302778 stop();
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302779
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302780 return(bStatus);
2781 }
2782
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302783 private boolean fmOffImplCherokee() {
2784 boolean bStatus=false;
2785
2786 fmOperationsOff();
2787 stop();
2788 try {
2789 Thread.sleep(200);
2790 } catch (Exception ex) {
2791 Log.d( LOGTAG, "RunningThread InterruptedException");
2792 }
2793
2794 // This will disable the FM radio device
2795 if (mReceiver != null)
2796 {
Kamal Negi6c3e6892017-03-15 14:05:32 +05302797 mEventReceived = false;
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302798 bStatus = mReceiver.disable(this);
2799 if (bStatus &&
2800 (mReceiver.getFMState() == mReceiver.subPwrLevel_FMTurning_Off)) {
Kamal Negi6c3e6892017-03-15 14:05:32 +05302801 bStatus = waitForEvent();
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302802 }
2803 mReceiver = null;
2804 }
2805 return(bStatus);
2806 }
2807 /*
2808 * Turn OFF FM: Disable the FM Host and hardware .
2809 * .
2810 * @return true if fm Disable api was invoked successfully, false if the api failed.
2811 */
2812 private boolean fmOff() {
himta ramb396f592018-08-14 11:23:52 +05302813 boolean ret = false;
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302814 if (mReceiver != null) {
2815 if (mReceiver.isCherokeeChip()) {
himta ramb396f592018-08-14 11:23:52 +05302816 ret = fmOffImplCherokee();
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302817 } else {
himta ramb396f592018-08-14 11:23:52 +05302818 ret = fmOffImpl();
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302819 }
2820 }
himta ramb396f592018-08-14 11:23:52 +05302821 mWakeLock.release();
2822 return ret;
Satish kumar sugasi3b47fd12016-12-07 19:02:35 +05302823 }
2824
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05302825 private boolean fmOff(int off_from) {
2826 if (off_from == FM_OFF_FROM_APPLICATION || off_from == FM_OFF_FROM_ANTENNA) {
2827 Log.d(LOGTAG, "FM application close button pressed or antenna removed");
2828 mSession.setActive(false);
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05302829 }
himta rame628c052018-07-06 20:26:48 +05302830 if(off_from == FM_OFF_FROM_APPLICATION) {
2831 Log.d(LOGTAG, "FM off from Application");
2832 isfmOffFromApplication = true;
2833 }
Nitin Shivpurec2ee76b2017-06-21 19:09:49 +05302834
Rupesh Tatiyafd07e802015-11-04 17:51:44 +05302835 return fmOff();
2836 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302837 /*
2838 * Turn OFF FM: Disable the FM Host when hardware resets asynchronously .
2839 * .
2840 * @return true if fm Reset api was invoked successfully, false if the api failed .
2841 */
2842 private boolean fmRadioReset() {
2843 boolean bStatus=false;
2844
2845 Log.v(LOGTAG, "fmRadioReset");
2846
2847 fmOperationsReset();
2848
2849 // This will reset the FM radio receiver
2850 if (mReceiver != null)
2851 {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302852 mReceiver = null;
2853 }
2854 stop();
2855 return(bStatus);
2856 }
2857
Danesh M94cab4e2015-08-19 15:43:48 -07002858 public List<Integer> getScannedFrequencies() {
2859 return mScannedFrequencies;
2860 }
2861
Danesh Mf6600ec2015-08-14 11:20:31 -07002862 public boolean isSearchInProgress() {
2863 int state = mReceiver.getFMState();
2864 return state == qcom.fmradio.FmTransceiver.FMState_Srch_InProg;
2865 }
2866
Satish Kodishala454dd9e2014-11-20 15:34:46 +05302867 public boolean isSSRInProgress() {
2868 return mIsSSRInProgress;
2869 }
2870
Venkateshwarlu Domakonda9c555962015-09-15 13:06:58 +05302871 public boolean isA2DPConnected() {
2872 return (mA2dpConnected);
2873 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302874 /* Returns whether FM hardware is ON.
2875 *
2876 * @return true if FM was tuned, searching. (at the end of
2877 * the search FM goes back to tuned).
2878 *
2879 */
2880 public boolean isFmOn() {
2881 return mFMOn;
2882 }
2883
2884 /* Returns true if Analog Path is enabled */
2885 public boolean isAnalogModeEnabled() {
2886 return misAnalogPathEnabled;
2887 }
2888
2889 public boolean isAnalogModeSupported() {
2890 return misAnalogModeSupported;
2891 }
2892
2893 public boolean isFmRecordingOn() {
2894 return mFmRecordingOn;
2895 }
2896
Venkateshwarlu Domakondad09c0882015-05-26 15:16:38 +05302897 public boolean isRtPlusSupported() {
2898 return mRtPlusSupport;
2899 }
2900
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302901 public boolean isSpeakerEnabled() {
2902 return mSpeakerPhoneOn;
2903 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302904
Rupesh Tatiya5ed72802015-11-30 15:40:46 +05302905 public void enableSpeaker(boolean speakerOn) {
2906 Log.d(LOGTAG, "speakerOn: " + speakerOn);
himta ram43bf6232018-11-02 11:16:37 +05302907 int mAudioDeviceType;
2908 String outputDevice;
Rupesh Tatiya5ed72802015-11-30 15:40:46 +05302909 if (isCallActive())
2910 return;
2911
2912 mSpeakerPhoneOn = speakerOn;
himta ram43bf6232018-11-02 11:16:37 +05302913 if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
2914 enableSlimbus(DISABLE_SLIMBUS_DATA_PORT);
2915 }
Rupesh Tatiya5ed72802015-11-30 15:40:46 +05302916
2917 if (speakerOn == false) {
himta ram43bf6232018-11-02 11:16:37 +05302918 mAudioDevice = AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
2919 outputDevice = "WiredHeadset";
2920 } else {
2921 mAudioDevice = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
2922 outputDevice = "Speaker";
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302923 }
Erfan Abdi60258312019-08-21 17:25:21 +04302924 if (mUseAudioSession) {
2925 startApplicationLoopBack(mAudioDevice);
2926 } else {
2927 mAudioDeviceType = mAudioDevice | AudioSystem.DEVICE_OUT_FM;
2928 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
2929 String keyValPairs = new String("fm_routing="+mAudioDeviceType);
2930 Log.d(LOGTAG, "keyValPairs = "+keyValPairs);
2931 audioManager.setParameters(keyValPairs);
2932 }
himta ram43bf6232018-11-02 11:16:37 +05302933 if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
2934 enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
2935 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302936 }
2937 /*
2938 * ReConfigure the FM Setup parameters
2939 * - Band
2940 * - Channel Spacing (50/100/200 KHz)
2941 * - Emphasis (50/75)
2942 * - Frequency limits
2943 * - RDS/RBDS standard
2944 *
2945 * @return true if configure api was invoked successfully, false if the api failed.
2946 */
2947 public boolean fmReconfigure() {
2948 boolean bStatus=false;
2949 Log.d(LOGTAG, "fmReconfigure");
2950 if (mReceiver != null)
2951 {
2952 // This sets up the FM radio device
2953 FmConfig config = FmSharedPreferences.getFMConfiguration();
2954 Log.d(LOGTAG, "RadioBand :"+ config.getRadioBand());
2955 Log.d(LOGTAG, "Emphasis :"+ config.getEmphasis());
2956 Log.d(LOGTAG, "ChSpacing :"+ config.getChSpacing());
2957 Log.d(LOGTAG, "RdsStd :"+ config.getRdsStd());
2958 Log.d(LOGTAG, "LowerLimit :"+ config.getLowerLimit());
2959 Log.d(LOGTAG, "UpperLimit :"+ config.getUpperLimit());
2960 bStatus = mReceiver.configure(config);
2961 }
2962 return(bStatus);
2963 }
2964
2965 /*
2966 * Register UI/Activity Callbacks
2967 */
2968 public void registerCallbacks(IFMRadioServiceCallbacks cb)
2969 {
2970 mCallbacks = cb;
2971 }
2972
2973 /*
2974 * unRegister UI/Activity Callbacks
2975 */
2976 public void unregisterCallbacks()
2977 {
2978 mCallbacks=null;
2979 }
2980
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302981 /*
2982 * Mute FM Hardware (SoC)
2983 * @return true if set mute mode api was invoked successfully, false if the api failed.
2984 */
2985 public boolean mute() {
2986 boolean bCommandSent=true;
2987 if(isMuted())
2988 return bCommandSent;
Venkateshwarlu Domakonda2c571ee2014-09-15 17:35:29 +05302989 if(isCallActive())
2990 return false;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302991 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
2992 Log.d(LOGTAG, "mute:");
2993 if (audioManager != null)
2994 {
2995 mMuted = true;
Dhananjay Kumar76b2c962016-01-25 20:30:17 +05302996 audioManager.setParameters("fm_mute=1");
2997 if (mAudioTrack != null)
2998 mAudioTrack.setVolume(0.0f);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05302999 }
3000 return bCommandSent;
3001 }
3002
3003 /*
3004 * UnMute FM Hardware (SoC)
3005 * @return true if set mute mode api was invoked successfully, false if the api failed.
3006 */
3007 public boolean unMute() {
3008 boolean bCommandSent=true;
3009 if(!isMuted())
3010 return bCommandSent;
Venkateshwarlu Domakonda2c571ee2014-09-15 17:35:29 +05303011 if(isCallActive())
3012 return false;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303013 Log.d(LOGTAG, "unMute:");
3014 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
3015 if (audioManager != null)
3016 {
3017 mMuted = false;
Dhananjay Kumar76b2c962016-01-25 20:30:17 +05303018 audioManager.setParameters("fm_mute=0");
3019 if (mAudioTrack != null)
3020 mAudioTrack.setVolume(1.0f);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303021 if (mResumeAfterCall)
3022 {
3023 //We are unmuting FM in a voice call. Need to enable FM audio routing.
3024 startFM();
3025 }
3026 }
3027 return bCommandSent;
3028 }
3029
3030 /* Returns whether FM Hardware(Soc) Audio is Muted.
3031 *
3032 * @return true if FM Audio is muted, false if not muted.
3033 *
3034 */
3035 public boolean isMuted() {
3036 return mMuted;
3037 }
3038
3039 /* Tunes to the specified frequency
3040 *
3041 * @return true if Tune command was invoked successfully, false if not muted.
3042 * Note: Callback FmRxEvRadioTuneStatus will be called when the tune
3043 * is complete
3044 */
3045 public boolean tune(int frequency) {
3046 boolean bCommandSent=false;
3047 double doubleFrequency = frequency/1000.00;
3048
3049 Log.d(LOGTAG, "tuneRadio: " + doubleFrequency);
3050 if (mReceiver != null)
3051 {
3052 mReceiver.setStation(frequency);
3053 bCommandSent = true;
Edward Wang6844bc52015-04-09 16:06:02 -07003054 mFreq = frequency;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303055 }
3056 return bCommandSent;
3057 }
3058
3059 /* Seeks (Search for strong station) to the station in the direction specified
3060 * relative to the tuned station.
3061 * boolean up: true - Search in the forward direction.
3062 * false - Search in the backward direction.
3063 * @return true if Seek command was invoked successfully, false if not muted.
3064 * Note: 1. Callback FmRxEvSearchComplete will be called when the Search
3065 * is complete
3066 * 2. Callback FmRxEvRadioTuneStatus will also be called when tuned to a station
3067 * at the end of the Search or if the seach was cancelled.
3068 */
3069 public boolean seek(boolean up)
3070 {
3071 boolean bCommandSent=false;
3072 if (mReceiver != null)
3073 {
3074 if (up == true)
3075 {
3076 Log.d(LOGTAG, "seek: Up");
3077 mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SEEK,
3078 FmReceiver.FM_RX_DWELL_PERIOD_1S,
3079 FmReceiver.FM_RX_SEARCHDIR_UP);
3080 }
3081 else
3082 {
3083 Log.d(LOGTAG, "seek: Down");
3084 mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SEEK,
3085 FmReceiver.FM_RX_DWELL_PERIOD_1S,
3086 FmReceiver.FM_RX_SEARCHDIR_DOWN);
3087 }
3088 bCommandSent = true;
3089 }
3090 return bCommandSent;
3091 }
3092
3093 /* Scan (Search for station with a "preview" of "n" seconds)
3094 * FM Stations. It always scans in the forward direction relative to the
3095 * current tuned station.
3096 * int pty: 0 or a reserved PTY value- Perform a "strong" station search of all stations.
3097 * Valid/Known PTY - perform RDS Scan for that pty.
3098 *
3099 * @return true if Scan command was invoked successfully, false if not muted.
3100 * Note: 1. Callback FmRxEvRadioTuneStatus will be called when tuned to various stations
3101 * during the Scan.
3102 * 2. Callback FmRxEvSearchComplete will be called when the Search
3103 * is complete
3104 * 3. Callback FmRxEvRadioTuneStatus will also be called when tuned to a station
3105 * at the end of the Search or if the seach was cancelled.
3106 *
3107 */
3108 public boolean scan(int pty)
3109 {
Danesh M94cab4e2015-08-19 15:43:48 -07003110 // Clear previously scanned frequencies
3111 mScannedFrequencies.clear();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303112 boolean bCommandSent=false;
3113 if (mReceiver != null)
3114 {
3115 Log.d(LOGTAG, "scan: PTY: " + pty);
3116 if(FmSharedPreferences.isRBDSStd())
3117 {
3118 /* RBDS : Validate PTY value?? */
3119 if( ((pty > 0) && (pty <= 23)) || ((pty >= 29) && (pty <= 31)) )
3120 {
3121 bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCHRDS_MODE_SCAN_PTY,
3122 FmReceiver.FM_RX_DWELL_PERIOD_2S,
3123 FmReceiver.FM_RX_SEARCHDIR_UP,
3124 pty,
3125 0);
3126 }
3127 else
3128 {
3129 bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SCAN,
3130 FmReceiver.FM_RX_DWELL_PERIOD_2S,
3131 FmReceiver.FM_RX_SEARCHDIR_UP);
3132 }
3133 }
3134 else
3135 {
3136 /* RDS : Validate PTY value?? */
3137 if( (pty > 0) && (pty <= 31) )
3138 {
3139 bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCHRDS_MODE_SCAN_PTY,
3140 FmReceiver.FM_RX_DWELL_PERIOD_2S,
3141 FmReceiver.FM_RX_SEARCHDIR_UP,
3142 pty,
3143 0);
3144 }
3145 else
3146 {
3147 bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCH_MODE_SCAN,
3148 FmReceiver.FM_RX_DWELL_PERIOD_2S,
3149 FmReceiver.FM_RX_SEARCHDIR_UP);
3150 }
3151 }
3152 }
3153 return bCommandSent;
3154 }
3155
3156 /* Search for the 'numStations' number of strong FM Stations.
3157 *
3158 * It searches in the forward direction relative to the current tuned station.
3159 * int numStations: maximum number of stations to search.
3160 *
3161 * @return true if Search command was invoked successfully, false if not muted.
3162 * Note: 1. Callback FmRxEvSearchListComplete will be called when the Search
3163 * is complete
3164 * 2. Callback FmRxEvRadioTuneStatus will also be called when tuned to
3165 * the previously tuned station.
3166 */
3167 public boolean searchStrongStationList(int numStations)
3168 {
3169 boolean bCommandSent=false;
3170 if (mReceiver != null)
3171 {
3172 Log.d(LOGTAG, "searchStrongStationList: numStations: " + numStations);
3173 bCommandSent = mReceiver.searchStationList(FmReceiver.FM_RX_SRCHLIST_MODE_STRONG,
3174 FmReceiver.FM_RX_SEARCHDIR_UP,
3175 numStations,
3176 0);
3177 }
3178 return bCommandSent;
3179 }
3180
3181 /* Search for the FM Station that matches the RDS PI (Program Identifier) code.
3182 * It always scans in the forward direction relative to the current tuned station.
3183 * int piCode: PI Code of the station to search.
3184 *
3185 * @return true if Search command was invoked successfully, false if not muted.
3186 * Note: 1. Callback FmRxEvSearchComplete will be called when the Search
3187 * is complete
3188 * 2. Callback FmRxEvRadioTuneStatus will also be called when tuned to a station
3189 * at the end of the Search or if the seach was cancelled.
3190 */
3191 public boolean seekPI(int piCode)
3192 {
3193 boolean bCommandSent=false;
3194 if (mReceiver != null)
3195 {
3196 Log.d(LOGTAG, "seekPI: piCode: " + piCode);
3197 bCommandSent = mReceiver.searchStations(FmReceiver.FM_RX_SRCHRDS_MODE_SEEK_PI,
3198 FmReceiver.FM_RX_DWELL_PERIOD_1S,
3199 FmReceiver.FM_RX_SEARCHDIR_UP,
3200 0,
3201 piCode
3202 );
3203 }
3204 return bCommandSent;
3205 }
3206
3207
3208 /* Cancel any ongoing Search (Seek/Scan/SearchStationList).
3209 *
3210 * @return true if Search command was invoked successfully, false if not muted.
3211 * Note: 1. Callback FmRxEvSearchComplete will be called when the Search
3212 * is complete/cancelled.
3213 * 2. Callback FmRxEvRadioTuneStatus will also be called when tuned to a station
3214 * at the end of the Search or if the seach was cancelled.
3215 */
3216 public boolean cancelSearch()
3217 {
3218 boolean bCommandSent=false;
3219 if (mReceiver != null)
3220 {
3221 Log.d(LOGTAG, "cancelSearch");
3222 bCommandSent = mReceiver.cancelSearch();
3223 }
3224 return bCommandSent;
3225 }
3226
3227 /* Retrieves the RDS Program Service (PS) String.
3228 *
3229 * @return String - RDS PS String.
3230 * Note: 1. This is a synchronous call that should typically called when
3231 * Callback FmRxEvRdsPsInfo is invoked.
3232 * 2. Since PS contains multiple fields, this Service reads all the fields and "caches"
3233 * the values and provides this helper routine for the Activity to get only the information it needs.
3234 * 3. The "cached" data fields are always "cleared" when the tune status changes.
3235 */
3236 public String getProgramService() {
3237 String str = "";
3238 if (mFMRxRDSData != null)
3239 {
3240 str = mFMRxRDSData.getPrgmServices();
3241 if(str == null)
3242 {
3243 str= "";
3244 }
3245 }
3246 Log.d(LOGTAG, "Program Service: [" + str + "]");
3247 return str;
3248 }
3249
3250 /* Retrieves the RDS Radio Text (RT) String.
3251 *
3252 * @return String - RDS RT String.
3253 * Note: 1. This is a synchronous call that should typically called when
3254 * Callback FmRxEvRdsRtInfo is invoked.
3255 * 2. Since RT contains multiple fields, this Service reads all the fields and "caches"
3256 * the values and provides this helper routine for the Activity to get only the information it needs.
3257 * 3. The "cached" data fields are always "cleared" when the tune status changes.
3258 */
3259 public String getRadioText() {
3260 String str = "";
3261 if (mFMRxRDSData != null)
3262 {
3263 str = mFMRxRDSData.getRadioText();
3264 if(str == null)
3265 {
3266 str= "";
3267 }
3268 }
3269 Log.d(LOGTAG, "Radio Text: [" + str + "]");
3270 return str;
3271 }
3272
3273 public String getExtenRadioText() {
3274 String str = "";
3275 if (mFMRxRDSData != null)
3276 {
3277 str = mFMRxRDSData.getERadioText();
3278 if(str == null)
3279 {
3280 str= "";
3281 }
3282 }
3283 Log.d(LOGTAG, "eRadio Text:[" + str +"]");
3284 return str;
3285 }
Satish kumar sugasid8731b72016-01-27 14:45:45 -08003286 public int getExtenCountryCode() {
3287 int val = 0;
3288 if (mFMRxRDSData != null)
3289 {
3290 val = mFMRxRDSData.getECountryCode();
3291 }
3292 Log.d(LOGTAG, "eCountry Code :[" + val +"]");
3293 return val;
3294 }
3295
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303296 /* Retrieves the RDS Program Type (PTY) code.
3297 *
3298 * @return int - RDS PTY code.
3299 * Note: 1. This is a synchronous call that should typically called when
3300 * Callback FmRxEvRdsRtInfo and or FmRxEvRdsPsInfo is invoked.
3301 * 2. Since RT/PS contains multiple fields, this Service reads all the fields and "caches"
3302 * the values and provides this helper routine for the Activity to get only the information it needs.
3303 * 3. The "cached" data fields are always "cleared" when the tune status changes.
3304 */
3305 public int getProgramType() {
3306 int pty = -1;
3307 if (mFMRxRDSData != null)
3308 {
3309 pty = mFMRxRDSData.getPrgmType();
3310 }
3311 Log.d(LOGTAG, "PTY: [" + pty + "]");
3312 return pty;
3313 }
3314
3315 /* Retrieves the RDS Program Identifier (PI).
3316 *
3317 * @return int - RDS PI code.
3318 * Note: 1. This is a synchronous call that should typically called when
3319 * Callback FmRxEvRdsRtInfo and or FmRxEvRdsPsInfo is invoked.
3320 * 2. Since RT/PS contains multiple fields, this Service reads all the fields and "caches"
3321 * the values and provides this helper routine for the Activity to get only the information it needs.
3322 * 3. The "cached" data fields are always "cleared" when the tune status changes.
3323 */
3324 public int getProgramID() {
3325 int pi = -1;
3326 if (mFMRxRDSData != null)
3327 {
3328 pi = mFMRxRDSData.getPrgmId();
3329 }
3330 Log.d(LOGTAG, "PI: [" + pi + "]");
3331 return pi;
3332 }
3333
3334
3335 /* Retrieves the station list from the SearchStationlist.
3336 *
3337 * @return Array of integers that represents the station frequencies.
3338 * Note: 1. This is a synchronous call that should typically called when
3339 * Callback onSearchListComplete.
3340 */
3341 public int[] getSearchList()
3342 {
3343 int[] frequencyList = null;
3344 if (mReceiver != null)
3345 {
3346 Log.d(LOGTAG, "getSearchList: ");
3347 frequencyList = mReceiver.getStationList();
3348 }
3349 return frequencyList;
3350 }
3351
3352 /* Set the FM Power Mode on the FM hardware SoC.
3353 * Typically used when UI/Activity is in the background, so the Host is interrupted less often.
3354 *
3355 * boolean bLowPower: true: Enable Low Power mode on FM hardware.
3356 * false: Disable Low Power mode on FM hardware. (Put into normal power mode)
3357 * @return true if set power mode api was invoked successfully, false if the api failed.
3358 */
3359 public boolean setLowPowerMode(boolean bLowPower)
3360 {
3361 boolean bCommandSent=false;
3362 if (mReceiver != null)
3363 {
3364 Log.d(LOGTAG, "setLowPowerMode: " + bLowPower);
3365 if(bLowPower)
3366 {
3367 bCommandSent = mReceiver.setPowerMode(FmReceiver.FM_RX_LOW_POWER_MODE);
3368 }
3369 else
3370 {
3371 bCommandSent = mReceiver.setPowerMode(FmReceiver.FM_RX_NORMAL_POWER_MODE);
3372 }
3373 }
3374 return bCommandSent;
3375 }
3376
3377 /* Get the FM Power Mode on the FM hardware SoC.
3378 *
3379 * @return the device power mode.
3380 */
3381 public int getPowerMode()
3382 {
3383 int powerMode=FmReceiver.FM_RX_NORMAL_POWER_MODE;
3384 if (mReceiver != null)
3385 {
3386 powerMode = mReceiver.getPowerMode();
3387 Log.d(LOGTAG, "getLowPowerMode: " + powerMode);
3388 }
3389 return powerMode;
3390 }
3391
3392 /* Set the FM module to auto switch to an Alternate Frequency for the
3393 * station if one the signal strength of that frequency is stronger than the
3394 * current tuned frequency.
3395 *
3396 * boolean bEnable: true: Auto switch to stronger alternate frequency.
3397 * false: Do not switch to alternate frequency.
3398 *
3399 * @return true if set Auto AF mode api was invoked successfully, false if the api failed.
3400 * Note: Callback FmRxEvRadioTuneStatus will be called when tune
3401 * is complete to a different frequency.
3402 */
3403 public boolean enableAutoAF(boolean bEnable)
3404 {
3405 boolean bCommandSent=false;
3406 if (mReceiver != null)
3407 {
3408 Log.d(LOGTAG, "enableAutoAF: " + bEnable);
3409 bCommandSent = mReceiver.enableAFjump(bEnable);
3410 }
3411 return bCommandSent;
3412 }
3413
3414 /* Set the FM module to Stereo Mode or always force it to Mono Mode.
3415 * Note: The stereo mode will be available only when the station is broadcasting
3416 * in Stereo mode.
3417 *
3418 * boolean bEnable: true: Enable Stereo Mode.
3419 * false: Always stay in Mono Mode.
3420 *
3421 * @return true if set Stereo mode api was invoked successfully, false if the api failed.
3422 */
3423 public boolean enableStereo(boolean bEnable)
3424 {
3425 boolean bCommandSent=false;
himta rambe1ab412018-11-22 13:28:00 +05303426 synchronized(mReceiverLock) {
3427 if (mReceiver != null)
3428 {
3429 Log.d(LOGTAG, "enableStereo: " + bEnable);
3430 bCommandSent = mReceiver.setStereoMode(bEnable);
3431 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303432 }
3433 return bCommandSent;
3434 }
3435
3436 /** Determines if an internal Antenna is available.
3437 * Returns the cached value initialized on FMOn.
3438 *
3439 * @return true if internal antenna is available or wired
3440 * headset is plugged in, false if internal antenna is
3441 * not available and wired headset is not plugged in.
3442 */
3443 public boolean isAntennaAvailable()
3444 {
3445 boolean bAvailable = false;
3446 if ((mInternalAntennaAvailable) || (mHeadsetPlugged) )
3447 {
3448 bAvailable = true;
3449 }
3450 return bAvailable;
3451 }
3452
3453 public static long getAvailableSpace() {
3454 String state = Environment.getExternalStorageState();
3455 Log.d(LOGTAG, "External storage state=" + state);
3456 if (Environment.MEDIA_CHECKING.equals(state)) {
3457 return PREPARING;
3458 }
3459 if (!Environment.MEDIA_MOUNTED.equals(state)) {
3460 return UNAVAILABLE;
3461 }
3462
3463 try {
3464 File sampleDir = Environment.getExternalStorageDirectory();
3465 StatFs stat = new StatFs(sampleDir.getAbsolutePath());
himta ramdfa45932019-03-07 17:57:54 +05303466 return stat.getAvailableBlocksLong() * stat.getBlockSizeLong();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303467 } catch (Exception e) {
3468 Log.i(LOGTAG, "Fail to access external storage", e);
3469 }
3470 return UNKNOWN_SIZE;
3471 }
3472
3473 private boolean updateAndShowStorageHint() {
3474 mStorageSpace = getAvailableSpace();
3475 return showStorageHint();
3476 }
3477
3478 private boolean showStorageHint() {
3479 String errorMessage = null;
3480 if (mStorageSpace == UNAVAILABLE) {
3481 errorMessage = getString(R.string.no_storage);
3482 } else if (mStorageSpace == PREPARING) {
3483 errorMessage = getString(R.string.preparing_sd);
3484 } else if (mStorageSpace == UNKNOWN_SIZE) {
3485 errorMessage = getString(R.string.access_sd_fail);
3486 } else if (mStorageSpace < LOW_STORAGE_THRESHOLD) {
3487 errorMessage = getString(R.string.spaceIsLow_content);
3488 }
3489
3490 if (errorMessage != null) {
3491 Toast.makeText(this, errorMessage,
3492 Toast.LENGTH_LONG).show();
3493 return false;
3494 }
3495 return true;
3496 }
3497
3498 /** Determines if a Wired headset is plugged in. Returns the
3499 * cached value initialized on broadcast receiver
3500 * initialization.
3501 *
3502 * @return true if wired headset is plugged in, false if wired
3503 * headset is not plugged in.
3504 */
3505 public boolean isWiredHeadsetAvailable()
3506 {
3507 return (mHeadsetPlugged);
3508 }
3509 public boolean isCallActive()
3510 {
3511 //Non-zero: Call state is RINGING or OFFHOOK on the available subscriptions
3512 //zero: Call state is IDLE on all the available subscriptions
3513 if(0 != getCallState()) return true;
3514 return false;
3515 }
3516 public int getCallState()
3517 {
3518 return mCallStatus;
3519 }
3520
3521 public void clearStationInfo() {
3522 if(mFMRxRDSData != null) {
Venkateshwarlu Domakondad09c0882015-05-26 15:16:38 +05303523 mRtPlusSupport = false;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303524 mFMRxRDSData.setRadioText("");
3525 mFMRxRDSData.setPrgmId(0);
3526 mFMRxRDSData.setPrgmType(0);
3527 mFMRxRDSData.setPrgmServices("");
3528 mFMRxRDSData.setERadioText("");
3529 mFMRxRDSData.setTagValue("", 1);
3530 mFMRxRDSData.setTagValue("", 2);
3531 mFMRxRDSData.setTagCode((byte)0, 1);
3532 mFMRxRDSData.setTagCode((byte)0, 2);
3533 Log.d(LOGTAG, "clear tags data");
3534 FmSharedPreferences.clearTags();
3535 }
3536 }
3537
3538 /* Receiver callbacks back from the FM Stack */
3539 FmRxEvCallbacksAdaptor fmCallbacks = new FmRxEvCallbacksAdaptor()
3540 {
Rupesh Tatiya9917f922017-06-21 13:00:43 +05303541 public void FmRxEvEnableReceiver()
3542 {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303543 Log.d(LOGTAG, "FmRxEvEnableReceiver");
Smriti Guptabfc78cb2017-08-30 14:18:07 +05303544 if (mReceiver != null) {
Smriti Guptabfc78cb2017-08-30 14:18:07 +05303545 if (mReceiver.isCherokeeChip()) {
3546 synchronized(mEventWaitLock) {
3547 mEventReceived = true;
3548 mEventWaitLock.notify();
3549 }
Kamal Negi6c3e6892017-03-15 14:05:32 +05303550 }
3551 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303552 }
3553 public void FmRxEvDisableReceiver()
3554 {
3555 Log.d(LOGTAG, "FmRxEvDisableReceiver");
3556 mFMOn = false;
3557 FmSharedPreferences.clearTags();
Kamal Negi6c3e6892017-03-15 14:05:32 +05303558 if (mReceiver != null && mReceiver.isCherokeeChip()) {
3559 synchronized (mEventWaitLock) {
3560 mEventReceived = true;
3561 mEventWaitLock.notify();
3562 }
Kamal Negi3d3cdea2016-06-27 19:54:56 +05303563 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303564 }
3565 public void FmRxEvRadioReset()
3566 {
Satish Kodishala454dd9e2014-11-20 15:34:46 +05303567 boolean bStatus;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303568 Log.d(LOGTAG, "FmRxEvRadioReset");
3569 if(isFmOn()) {
3570 // Received radio reset event while FM is ON
3571 Log.d(LOGTAG, "FM Radio reset");
3572 fmRadioReset();
3573 try
3574 {
3575 /* Notify the UI/Activity, only if the service is "bound"
3576 by an activity and if Callbacks are registered
3577 */
3578 if((mServiceInUse) && (mCallbacks != null) )
3579 {
Satish Kodishala454dd9e2014-11-20 15:34:46 +05303580 mIsSSRInProgressFromActivity = true;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303581 mCallbacks.onRadioReset();
Satish Kodishala454dd9e2014-11-20 15:34:46 +05303582 } else {
3583 Log.d(LOGTAG, "Activity is not in foreground, turning on from service");
3584 if (isAntennaAvailable())
3585 {
3586 mIsSSRInProgress = true;
Venkateshwarlu Domakonda2681b2f2015-06-22 16:23:03 +05303587 try {
3588 Thread.sleep(2000);
3589 } catch (Exception ex) {
3590 Log.d( LOGTAG, "RunningThread InterruptedException in RadioReset");
3591 }
Satish Kodishala454dd9e2014-11-20 15:34:46 +05303592 bStatus = fmOn();
3593 if(bStatus)
3594 {
3595 bStatus = tune(FmSharedPreferences.getTunedFrequency());
3596 if(!bStatus)
3597 Log.e(LOGTAG, "Tuning after SSR from service failed");
3598 } else {
3599 Log.e(LOGTAG, "Turning on after SSR from service failed");
3600 }
3601 mIsSSRInProgress = false;
3602 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303603 }
3604 }
3605 catch (RemoteException e)
3606 {
3607 e.printStackTrace();
3608 }
3609 }
3610 }
3611 public void FmRxEvConfigReceiver()
3612 {
3613 Log.d(LOGTAG, "FmRxEvConfigReceiver");
3614 }
3615 public void FmRxEvMuteModeSet()
3616 {
3617 Log.d(LOGTAG, "FmRxEvMuteModeSet");
3618 }
3619 public void FmRxEvStereoModeSet()
3620 {
3621 Log.d(LOGTAG, "FmRxEvStereoModeSet");
3622 }
3623 public void FmRxEvRadioStationSet()
3624 {
3625 Log.d(LOGTAG, "FmRxEvRadioStationSet");
3626 }
3627 public void FmRxEvPowerModeSet()
3628 {
3629 Log.d(LOGTAG, "FmRxEvPowerModeSet");
3630 }
3631 public void FmRxEvSetSignalThreshold()
3632 {
3633 Log.d(LOGTAG, "FmRxEvSetSignalThreshold");
3634 }
3635
3636 public void FmRxEvRadioTuneStatus(int frequency)
3637 {
3638 Log.d(LOGTAG, "FmRxEvRadioTuneStatus: Tuned Frequency: " +frequency);
3639 try
3640 {
3641 FmSharedPreferences.setTunedFrequency(frequency);
3642 mPrefs.Save();
3643 //Log.d(LOGTAG, "Call mCallbacks.onTuneStatusChanged");
3644 /* Since the Tuned Status changed, clear out the RDSData cached */
3645 if(mReceiver != null) {
3646 clearStationInfo();
3647 }
Danesh M94cab4e2015-08-19 15:43:48 -07003648 if (isSearchInProgress()) {
3649 mScannedFrequencies.add(frequency);
3650 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303651 if(mCallbacks != null)
3652 {
3653 mCallbacks.onTuneStatusChanged();
3654 }
3655 /* Update the frequency in the StatusBar's Notification */
3656 startNotification();
Ayaz Ahmadd97a0bb2013-09-02 12:17:33 +05303657 enableStereo(FmSharedPreferences.getAudioOutputMode());
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303658 }
3659 catch (RemoteException e)
3660 {
3661 e.printStackTrace();
3662 }
3663 }
3664
3665 public void FmRxEvStationParameters()
3666 {
3667 Log.d(LOGTAG, "FmRxEvStationParameters");
3668 }
3669
3670 public void FmRxEvRdsLockStatus(boolean bRDSSupported)
3671 {
3672 Log.d(LOGTAG, "FmRxEvRdsLockStatus: " + bRDSSupported);
3673 try
3674 {
3675 if(mCallbacks != null)
3676 {
3677 mCallbacks.onStationRDSSupported(bRDSSupported);
3678 }
3679 }
3680 catch (RemoteException e)
3681 {
3682 e.printStackTrace();
3683 }
3684 }
3685
3686 public void FmRxEvStereoStatus(boolean stereo)
3687 {
3688 Log.d(LOGTAG, "FmRxEvStereoStatus: " + stereo);
3689 try
3690 {
3691 if(mCallbacks != null)
3692 {
3693 mCallbacks.onAudioUpdate(stereo);
3694 }
3695 }
3696 catch (RemoteException e)
3697 {
3698 e.printStackTrace();
3699 }
3700 }
3701 public void FmRxEvServiceAvailable(boolean signal)
3702 {
3703 Log.d(LOGTAG, "FmRxEvServiceAvailable");
3704 if(signal) {
3705 Log.d(LOGTAG, "FmRxEvServiceAvailable: Tuned frequency is above signal threshold level");
3706 }
3707 else {
3708 Log.d(LOGTAG, "FmRxEvServiceAvailable: Tuned frequency is below signal threshold level");
3709 }
3710 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05303711 public void FmRxEvGetSignalThreshold(int val, int status)
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303712 {
3713 Log.d(LOGTAG, "FmRxEvGetSignalThreshold");
Kamal Negi8813e0f2016-02-10 19:12:09 +05303714
3715 if (mCallbacks != null) {
3716 try {
3717 mCallbacks.getSigThCb(val, status);
3718 } catch (RemoteException e) {
3719 Log.e(LOGTAG, "FmRxEvGetSignalThreshold: Exception:" + e.toString());
3720 }
3721 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303722 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05303723
3724 public void FmRxEvGetChDetThreshold(int val, int status)
3725 {
3726 Log.e(LOGTAG, "FmRxEvGetChDetThreshold");
3727 if (mCallbacks != null) {
3728 try {
3729 mCallbacks.getChDetThCb(val, status);
3730 } catch (RemoteException e) {
3731 Log.e(LOGTAG, "FmRxEvGetChDetThreshold: Exception = " + e.toString());
3732 }
3733 }
3734 }
3735
3736 public void FmRxEvSetChDetThreshold(int status)
3737 {
3738 Log.e(LOGTAG, "FmRxEvSetChDetThreshold");
3739 if (mCallbacks != null) {
3740 try {
3741 mCallbacks.setChDetThCb(status);
3742 } catch (RemoteException e) {
3743 e.printStackTrace();
3744 }
3745 }
3746 }
3747
3748 public void FmRxEvDefDataRead(int val, int status) {
3749 Log.e(LOGTAG, "FmRxEvDefDataRead");
3750 if (mCallbacks != null) {
3751 try {
3752 mCallbacks.DefDataRdCb(val, status);
3753 } catch (RemoteException e) {
3754 Log.e(LOGTAG, "FmRxEvDefDataRead: Exception = " + e.toString());
3755 }
3756 }
3757 }
3758
3759 public void FmRxEvDefDataWrite(int status)
3760 {
3761 Log.e(LOGTAG, "FmRxEvDefDataWrite");
3762 if (mCallbacks != null) {
3763 try {
3764 mCallbacks.DefDataWrtCb(status);
3765 } catch (RemoteException e) {
3766 e.printStackTrace();
3767 }
3768 }
3769 }
3770
3771 public void FmRxEvGetBlend(int val, int status)
3772 {
3773 Log.e(LOGTAG, "FmRxEvGetBlend");
3774
3775 if (mCallbacks != null) {
3776 try {
3777 mCallbacks.getBlendCb(val, status);
3778 } catch (RemoteException e) {
3779 e.printStackTrace();
3780 }
3781 }
3782 }
3783
3784 public void FmRxEvSetBlend(int status)
3785 {
3786 Log.e(LOGTAG, "FmRxEvSetBlend");
3787 if (mCallbacks != null) {
3788 try {
3789 mCallbacks.setBlendCb(status);
3790 } catch (RemoteException e) {
3791 e.printStackTrace();
3792 }
3793 }
3794 }
3795
3796 public void FmRxGetStationParam(int val, int status)
3797 {
3798 if (mCallbacks != null) {
3799 try {
3800 mCallbacks.getStationParamCb(val, status);
himta ram15771752018-08-10 18:06:18 +05303801 if (mReceiver != null && mReceiver.isCherokeeChip()) {
3802 synchronized(mEventWaitLock) {
3803 mEventReceived = true;
3804 mEventWaitLock.notify();
3805 }
3806 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05303807 } catch (RemoteException e) {
3808 e.printStackTrace();
3809 }
3810 }
3811 }
3812
3813 public void FmRxGetStationDbgParam(int val, int status)
3814 {
3815 if (mCallbacks != null) {
3816 try {
3817 mCallbacks.getStationDbgParamCb(val, status);
3818 } catch (RemoteException e) {
3819 e.printStackTrace();
3820 }
3821 }
3822 }
3823
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303824 public void FmRxEvSearchInProgress()
3825 {
3826 Log.d(LOGTAG, "FmRxEvSearchInProgress");
3827 }
3828 public void FmRxEvSearchRdsInProgress()
3829 {
3830 Log.d(LOGTAG, "FmRxEvSearchRdsInProgress");
3831 }
3832 public void FmRxEvSearchListInProgress()
3833 {
3834 Log.d(LOGTAG, "FmRxEvSearchListInProgress");
3835 }
3836 public void FmRxEvSearchComplete(int frequency)
3837 {
3838 Log.d(LOGTAG, "FmRxEvSearchComplete: Tuned Frequency: " +frequency);
3839 try
3840 {
3841 FmSharedPreferences.setTunedFrequency(frequency);
Venkateshwarlu Domakondaac37b092014-06-30 15:28:36 +05303842 mPrefs.Save();
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303843 //Log.d(LOGTAG, "Call mCallbacks.onSearchComplete");
3844 /* Since the Tuned Status changed, clear out the RDSData cached */
3845 if(mReceiver != null) {
3846 clearStationInfo();
3847 }
3848 if(mCallbacks != null)
3849 {
3850 mCallbacks.onSearchComplete();
3851 }
3852 /* Update the frequency in the StatusBar's Notification */
3853 startNotification();
3854 }
3855 catch (RemoteException e)
3856 {
3857 e.printStackTrace();
3858 }
3859 }
3860
3861 public void FmRxEvSearchRdsComplete()
3862 {
3863 Log.d(LOGTAG, "FmRxEvSearchRdsComplete");
3864 }
3865
3866 public void FmRxEvSearchListComplete()
3867 {
3868 Log.d(LOGTAG, "FmRxEvSearchListComplete");
3869 try
3870 {
3871 if(mCallbacks != null)
3872 {
3873 mCallbacks.onSearchListComplete();
3874 }
3875 } catch (RemoteException e)
3876 {
3877 e.printStackTrace();
3878 }
3879 }
3880
3881 public void FmRxEvSearchCancelled()
3882 {
3883 Log.d(LOGTAG, "FmRxEvSearchCancelled: Cancelled the on-going search operation.");
3884 }
3885 public void FmRxEvRdsGroupData()
3886 {
3887 Log.d(LOGTAG, "FmRxEvRdsGroupData");
3888 }
3889
3890 public void FmRxEvRdsPsInfo() {
3891 Log.d(LOGTAG, "FmRxEvRdsPsInfo: ");
3892 try
3893 {
3894 if(mReceiver != null)
3895 {
3896 mFMRxRDSData = mReceiver.getPSInfo();
3897 if(mFMRxRDSData != null)
3898 {
3899 Log.d(LOGTAG, "PI: [" + mFMRxRDSData.getPrgmId() + "]");
3900 Log.d(LOGTAG, "PTY: [" + mFMRxRDSData.getPrgmType() + "]");
3901 Log.d(LOGTAG, "PS: [" + mFMRxRDSData.getPrgmServices() + "]");
3902 }
3903 if(mCallbacks != null)
3904 {
3905 mCallbacks.onProgramServiceChanged();
3906 }
3907 }
3908 } catch (RemoteException e)
3909 {
3910 e.printStackTrace();
3911 }
3912 }
3913
3914 public void FmRxEvRdsRtInfo() {
3915 Log.d(LOGTAG, "FmRxEvRdsRtInfo");
3916 try
3917 {
3918 //Log.d(LOGTAG, "Call mCallbacks.onRadioTextChanged");
3919 if(mReceiver != null)
3920 {
3921 mFMRxRDSData = mReceiver.getRTInfo();
3922 if(mFMRxRDSData != null)
3923 {
3924 Log.d(LOGTAG, "PI: [" + mFMRxRDSData.getPrgmId() + "]");
3925 Log.d(LOGTAG, "PTY: [" + mFMRxRDSData.getPrgmType() + "]");
3926 Log.d(LOGTAG, "RT: [" + mFMRxRDSData.getRadioText() + "]");
3927 }
3928 if(mCallbacks != null)
3929 {
3930 mCallbacks.onRadioTextChanged();
3931 }
3932 }
3933 } catch (RemoteException e)
3934 {
3935 e.printStackTrace();
3936 }
3937
3938 }
3939
3940 public void FmRxEvRdsAfInfo()
3941 {
3942 Log.d(LOGTAG, "FmRxEvRdsAfInfo");
3943 mReceiver.getAFInfo();
3944 }
3945 public void FmRxEvRTPlus()
3946 {
3947 int tag_nums;
3948 Log.d(LOGTAG, "FmRxEvRTPlusInfo");
Venkateshwarlu Domakondad09c0882015-05-26 15:16:38 +05303949 mRtPlusSupport = true;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303950 if (mReceiver != null) {
3951 mFMRxRDSData = mReceiver.getRTPlusInfo();
3952 tag_nums = mFMRxRDSData.getTagNums();
3953 if (tag_nums >= 1) {
3954 Log.d(LOGTAG, "tag1 is: " + mFMRxRDSData.getTagCode(1) + "value: "
3955 + mFMRxRDSData.getTagValue(1));
3956 FmSharedPreferences.addTags(mFMRxRDSData.getTagCode(1), mFMRxRDSData.getTagValue(1));
3957 }
3958 if(tag_nums == 2) {
3959 Log.d(LOGTAG, "tag2 is: " + mFMRxRDSData.getTagCode(2) + "value: "
3960 + mFMRxRDSData.getTagValue(2));
3961 FmSharedPreferences.addTags(mFMRxRDSData.getTagCode(2), mFMRxRDSData.getTagValue(2));
3962 }
3963 }
3964 }
3965 public void FmRxEvERTInfo()
3966 {
3967 Log.d(LOGTAG, "FmRxEvERTInfo");
3968 try {
3969 if (mReceiver != null) {
3970 mFMRxRDSData = mReceiver.getERTInfo();
3971 if(mCallbacks != null)
3972 mCallbacks.onExtenRadioTextChanged();
3973 }
3974 } catch (RemoteException e) {
3975 e.printStackTrace();
3976 }
3977 }
Satish kumar sugasid8731b72016-01-27 14:45:45 -08003978 public void FmRxEvECCInfo()
3979 {
3980 Log.d(LOGTAG, "FmRxEvECCInfo");
3981 try {
3982 if (mReceiver != null) {
3983 mFMRxRDSData = mReceiver.getECCInfo();
3984 if(mCallbacks != null)
3985 mCallbacks.onExtenCountryCodeChanged();
3986 }
3987 } catch (RemoteException e) {
3988 e.printStackTrace();
3989 }
3990 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05303991 public void FmRxEvRdsPiMatchAvailable()
3992 {
3993 Log.d(LOGTAG, "FmRxEvRdsPiMatchAvailable");
3994 }
3995 public void FmRxEvRdsGroupOptionsSet()
3996 {
3997 Log.d(LOGTAG, "FmRxEvRdsGroupOptionsSet");
3998 }
3999 public void FmRxEvRdsProcRegDone()
4000 {
4001 Log.d(LOGTAG, "FmRxEvRdsProcRegDone");
4002 }
4003 public void FmRxEvRdsPiMatchRegDone()
4004 {
4005 Log.d(LOGTAG, "FmRxEvRdsPiMatchRegDone");
4006 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05304007 public void FmRxEvEnableSlimbus(int status)
4008 {
4009 Log.e(LOGTAG, "FmRxEvEnableSlimbus status = " + status);
4010 if (mReceiver != null && mReceiver.isCherokeeChip()) {
4011 synchronized(mEventWaitLock) {
4012 mEventReceived = true;
4013 mEventWaitLock.notify();
4014 }
4015 }
4016 }
himta ram43bf6232018-11-02 11:16:37 +05304017 public void FmRxEvEnableSoftMute(int status)
himta ram56984632018-03-19 13:07:29 +05304018 {
4019 Log.e(LOGTAG, "FmRxEvEnableSoftMute status = " + status);
4020 if (mReceiver != null && mReceiver.isCherokeeChip()) {
4021 synchronized(mEventWaitLock) {
4022 mEventReceived = true;
4023 mEventWaitLock.notify();
4024 }
4025 }
4026 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304027 };
4028
4029
4030 /*
4031 * Read the Tuned Frequency from the FM module.
4032 */
4033 private String getTunedFrequencyString() {
4034
4035 double frequency = FmSharedPreferences.getTunedFrequency() / 1000.0;
4036 String frequencyString = getString(R.string.stat_notif_frequency, (""+frequency));
4037 return frequencyString;
4038 }
4039 public int getRssi() {
himta ram15771752018-08-10 18:06:18 +05304040 if (mReceiver != null) {
4041 mEventReceived = false;
4042 int rssi = mReceiver.getRssi();
4043 waitForFWEvent();
4044 return rssi;
4045 } else
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304046 return Integer.MAX_VALUE;
4047 }
4048 public int getIoC() {
4049 if (mReceiver != null)
4050 return mReceiver.getIoverc();
4051 else
4052 return Integer.MAX_VALUE;
4053 }
4054 public int getIntDet() {
4055 if (mReceiver != null)
4056 return mReceiver.getIntDet();
4057 else
4058 return Integer.MAX_VALUE;
4059 }
4060 public int getMpxDcc() {
4061 if (mReceiver != null)
4062 return mReceiver.getMpxDcc();
4063 else
4064 return Integer.MAX_VALUE;
4065 }
4066 public void setHiLoInj(int inj) {
4067 if (mReceiver != null)
4068 mReceiver.setHiLoInj(inj);
4069 }
4070 public int getSINR() {
himta ram15771752018-08-10 18:06:18 +05304071 if (mReceiver != null) {
4072 mEventReceived = false;
4073 int sinr = mReceiver.getSINR();;
4074 waitForFWEvent();
4075 return sinr;
4076 } else
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304077 return Integer.MAX_VALUE;
4078 }
4079 public boolean setSinrSamplesCnt(int samplesCnt) {
4080 if(mReceiver != null)
4081 return mReceiver.setSINRsamples(samplesCnt);
4082 else
4083 return false;
4084 }
4085 public boolean setSinrTh(int sinr) {
4086 if(mReceiver != null)
4087 return mReceiver.setSINRThreshold(sinr);
4088 else
4089 return false;
4090 }
4091 public boolean setIntfDetLowTh(int intfLowTh) {
4092 if(mReceiver != null)
4093 return mReceiver.setOnChannelThreshold(intfLowTh);
4094 else
4095 return false;
4096 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05304097 public boolean getIntfDetLowTh()
4098 {
4099 if (mReceiver != null)
4100 return mReceiver.getOnChannelThreshold();
4101 else
4102 return false;
4103 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304104 public boolean setIntfDetHighTh(int intfHighTh) {
4105 if(mReceiver != null)
4106 return mReceiver.setOffChannelThreshold(intfHighTh);
4107 else
4108 return false;
4109 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05304110 public boolean getIntfDetHighTh()
4111 {
4112 if (mReceiver != null)
4113 return mReceiver.getOffChannelThreshold();
4114 else
4115 return false;
4116 }
Ayaz Ahmada32e3772013-07-31 12:24:29 +05304117 public int getSearchAlgoType() {
4118 if(mReceiver != null)
4119 return mReceiver.getSearchAlgoType();
4120 else
4121 return -1;
4122 }
4123 public boolean setSearchAlgoType(int searchType) {
4124 if(mReceiver != null)
4125 return mReceiver.setSearchAlgoType(searchType);
4126 else
4127 return false;
4128 }
4129 public int getSinrFirstStage() {
4130 if(mReceiver != null)
4131 return mReceiver.getSinrFirstStage();
4132 else
4133 return Integer.MAX_VALUE;
4134 }
4135 public boolean setSinrFirstStage(int sinr) {
4136 if(mReceiver != null)
4137 return mReceiver.setSinrFirstStage(sinr);
4138 else
4139 return false;
4140 }
4141 public int getRmssiFirstStage() {
4142 if(mReceiver != null)
4143 return mReceiver.getRmssiFirstStage();
4144 else
4145 return Integer.MAX_VALUE;
4146 }
4147 public boolean setRmssiFirstStage(int rmssi) {
4148 if(mReceiver != null)
4149 return mReceiver.setRmssiFirstStage(rmssi);
4150 else
4151 return false;
4152 }
4153 public int getCFOMeanTh() {
4154 if(mReceiver != null)
4155 return mReceiver.getCFOMeanTh();
4156 else
4157 return Integer.MAX_VALUE;
4158 }
4159 public boolean setCFOMeanTh(int th) {
4160 if(mReceiver != null)
4161 return mReceiver.setCFOMeanTh(th);
4162 else
4163 return false;
4164 }
4165 public int getSinrSamplesCnt() {
4166 if(mReceiver != null)
4167 return mReceiver.getSINRsamples();
4168 else
4169 return Integer.MAX_VALUE;
4170 }
4171 public int getSinrTh() {
4172 if(mReceiver != null)
4173 return mReceiver.getSINRThreshold();
4174 else
4175 return Integer.MAX_VALUE;
4176 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304177
Ayaz Ahmada32e3772013-07-31 12:24:29 +05304178 boolean setAfJmpRmssiTh(int afJmpRmssiTh) {
4179 if(mReceiver != null)
4180 return mReceiver.setAFJumpRmssiTh(afJmpRmssiTh);
4181 else
4182 return false;
4183 }
4184 boolean setGoodChRmssiTh(int gdChRmssiTh) {
4185 if(mReceiver != null)
4186 return mReceiver.setGdChRmssiTh(gdChRmssiTh);
4187 else
4188 return false;
4189 }
4190 boolean setAfJmpRmssiSamplesCnt(int afJmpRmssiSmplsCnt) {
4191 if(mReceiver != null)
4192 return mReceiver.setAFJumpRmssiSamples(afJmpRmssiSmplsCnt);
4193 else
4194 return false;
4195 }
4196 int getAfJmpRmssiTh() {
4197 if(mReceiver != null)
4198 return mReceiver.getAFJumpRmssiTh();
4199 else
4200 return Integer.MIN_VALUE;
4201 }
4202 int getGoodChRmssiTh() {
4203 if(mReceiver != null)
4204 return mReceiver.getGdChRmssiTh();
4205 else
4206 return Integer.MAX_VALUE;
4207 }
4208 int getAfJmpRmssiSamplesCnt() {
4209 if(mReceiver != null)
4210 return mReceiver.getAFJumpRmssiSamples();
4211 else
4212 return Integer.MIN_VALUE;
4213 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304214 private void setAlarmSleepExpired (long duration) {
4215 Intent i = new Intent(SLEEP_EXPIRED_ACTION);
4216 AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
4217 PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
4218 Log.d(LOGTAG, "delayedStop called" + SystemClock.elapsedRealtime() + duration);
4219 am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + duration, pi);
Ayaz Ahmad594e34a2013-09-12 17:04:29 +05304220 mSleepActive = true;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304221 }
4222 private void cancelAlarmSleepExpired() {
4223 Intent i = new Intent(SLEEP_EXPIRED_ACTION);
4224 AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
4225 PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
4226 am.cancel(pi);
Ayaz Ahmad594e34a2013-09-12 17:04:29 +05304227 mSleepActive = false;
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304228 }
4229 private void setAlarmRecordTimeout(long duration) {
4230 Intent i = new Intent(RECORD_EXPIRED_ACTION);
4231 AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
4232 PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
4233 Log.d(LOGTAG, "delayedStop called" + SystemClock.elapsedRealtime() + duration);
4234 am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + duration, pi);
4235 }
4236 private void cancelAlarmRecordTimeout() {
4237 Intent i = new Intent(RECORD_EXPIRED_ACTION);
4238 AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
4239 PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
4240 am.cancel(pi);
4241 }
4242 private void setAlarmDelayedServiceStop() {
4243 Intent i = new Intent(SERVICE_DELAYED_STOP_ACTION);
4244 AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
4245 PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
4246 am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + IDLE_DELAY, pi);
4247 }
4248 private void cancelAlarmDealyedServiceStop() {
4249 Intent i = new Intent(SERVICE_DELAYED_STOP_ACTION);
4250 AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
4251 PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
4252 am.cancel(pi);
4253 }
4254 private void cancelAlarms() {
4255 cancelAlarmSleepExpired();
4256 cancelAlarmRecordTimeout();
4257 cancelAlarmDealyedServiceStop();
4258 }
Ayaz Ahmad61bedff2013-07-31 13:04:19 +05304259 public boolean setRxRepeatCount(int count) {
4260 if(mReceiver != null)
4261 return mReceiver.setPSRxRepeatCount(count);
4262 else
4263 return false;
4264 }
Kamal Negi8813e0f2016-02-10 19:12:09 +05304265 public boolean getRxRepeatCount() {
4266 if(mReceiver != null)
4267 return mReceiver.getPSRxRepeatCount();
4268 else
4269 return false;
4270 }
Ayaz Ahmad613e5832013-08-01 19:57:19 +05304271 public long getRecordingStartTime() {
4272 return mSampleStart;
4273 }
Ayaz Ahmad594e34a2013-09-12 17:04:29 +05304274
4275 public boolean isSleepTimerActive() {
4276 return mSleepActive;
4277 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304278 //handling the sleep and record stop when FM App not in focus
4279 private void delayedStop(long duration, int nType) {
4280 int whatId = (nType == STOP_SERVICE) ? STOPSERVICE_ONSLEEP: STOPRECORD_ONTIMEOUT;
4281 if (nType == STOP_SERVICE)
4282 setAlarmSleepExpired(duration);
4283 else
4284 setAlarmRecordTimeout(duration);
4285 }
4286 private void cancelDelayedStop(int nType) {
4287 int whatId = (nType == STOP_SERVICE) ? STOPSERVICE_ONSLEEP: STOPRECORD_ONTIMEOUT;
4288 if (nType == STOP_SERVICE)
4289 cancelAlarmSleepExpired();
4290 else
4291 cancelAlarmRecordTimeout();
4292 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05304293
4294 private void requestFocusImpl() {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304295 if( (false == mPlaybackInProgress) &&
Mingbo Zhange579ce12017-01-13 10:53:00 +08004296 (true == mStoppedOnFocusLoss) && isFmOn()) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304297 // adding code for audio focus gain.
4298 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
himta ramdfa45932019-03-07 17:57:54 +05304299 audioManager.requestAudioFocus(mGainFocusReq);
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304300 startFM();
4301 mStoppedOnFocusLoss = false;
4302 }
4303 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05304304
4305 private void requestFocusImplCherokee() {
4306 Log.d(LOGTAG, "++requestFocusImplCherokee mPlaybackInProgress: " +
4307 mPlaybackInProgress + " mStoppedOnFocusLoss: " +
4308 mStoppedOnFocusLoss + " isFmOn: " + isFmOn());
4309 if( (false == mPlaybackInProgress) &&
4310 (true == mStoppedOnFocusLoss) && isFmOn()) {
4311 // adding code for audio focus gain.
4312 AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
himta ramdfa45932019-03-07 17:57:54 +05304313 audioManager.requestAudioFocus(mGainFocusReq);
Rupesh Tatiya9917f922017-06-21 13:00:43 +05304314 startFM();
himta ramdd027a32019-01-18 20:50:08 +05304315 if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
4316 enableSlimbus(ENABLE_SLIMBUS_DATA_PORT);
4317 }
Rupesh Tatiya9917f922017-06-21 13:00:43 +05304318 mStoppedOnFocusLoss = false;
4319 }
4320 }
4321
4322 private void requestFocus() {
4323 Log.d(LOGTAG, "++requestFocus");
Smriti Guptaab10c8b2017-09-06 16:48:48 +05304324 if (mReceiver.isCherokeeChip() && (mPref.getBoolean("SLIMBUS_SEQ", true))) {
Rupesh Tatiya9917f922017-06-21 13:00:43 +05304325 requestFocusImplCherokee();
4326 } else {
4327 requestFocusImpl();
4328 }
4329 Log.d(LOGTAG, "--requestFocus");
4330 }
4331
himta ramdfa45932019-03-07 17:57:54 +05304332
4333 public void onAudioFocusChange(int focusChange) {
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304334 mDelayedStopHandler.obtainMessage(FOCUSCHANGE, focusChange, 0).sendToTarget();
himta ramdfa45932019-03-07 17:57:54 +05304335 }
4336
Rupesh Tatiya5ed72802015-11-30 15:40:46 +05304337
4338 class A2dpServiceListener implements BluetoothProfile.ServiceListener {
4339 private List<BluetoothDevice> mA2dpDeviceList = null;
4340 private BluetoothA2dp mA2dpProfile = null;
4341
4342 public void onServiceConnected(int profile, BluetoothProfile proxy) {
4343 mA2dpProfile = (BluetoothA2dp) proxy;
4344 mA2dpDeviceList = mA2dpProfile.getConnectedDevices();
Rupesh Tatiya04b127e2016-06-06 19:34:29 +05304345 if (mA2dpDeviceList == null || mA2dpDeviceList.size() == 0)
Rupesh Tatiya5ed72802015-11-30 15:40:46 +05304346 mA2dpConnected = false;
4347 else
4348 mA2dpConnected = true;
Rupesh Tatiya04b127e2016-06-06 19:34:29 +05304349
Rupesh Tatiya5ed72802015-11-30 15:40:46 +05304350 mA2dpDisconnected = !mA2dpConnected;
himta rambff94f22018-06-05 11:03:21 +05304351 //mSpeakerPhoneOn = mA2dpConnected;
Rupesh Tatiya5ed72802015-11-30 15:40:46 +05304352 Log.d(LOGTAG, "A2DP Status: " + mA2dpConnected);
4353 }
4354
4355 public void onServiceDisconnected(int profile) {
4356 mA2dpProfile = null;
4357 mA2dpDeviceList = null;
4358 }
4359 }
4360
4361 private void getA2dpStatusAtStart () {
4362 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
4363
4364 if (!adapter.getProfileProxy(this, new A2dpServiceListener(),
4365 BluetoothProfile.A2DP)) {
4366 Log.d(LOGTAG, "Failed to get A2DP profile proxy");
4367 }
4368 }
Kamal Negidd175dc2016-06-03 20:09:24 +05304369
4370 private void restoreDefaults () {
4371 mStoppedOnFactoryReset = true;
4372 }
Balvinder Singh7b765532017-08-04 15:45:28 +05304373
4374
4375 class FMDeathRecipient implements IBinder.DeathRecipient {
4376 public FMDeathRecipient(FMRadioService service, IBinder binder) {
4377 }
4378 public void binderDied() {
4379 Log.d(LOGTAG, "** Binder is dead - cleanup audio now ** ");
4380 //TODO unregister the fm service here.
4381 }
4382 }
Erfan Abdi60258312019-08-21 17:25:21 +04304383 private boolean startApplicationLoopBack(int deviceType) {
4384
4385 // stop existing playback path before starting new one
4386 Log.d(LOGTAG,"startApplicationLoopBack for device "+deviceType);
4387
4388 AudioDeviceInfo outputDevice = null;
4389 AudioDeviceInfo[] deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
4390 for (int index = 0; index < deviceList.length; index++) {
4391 Log.d(LOGTAG,"startApplicationLoopBack dev_type " + deviceList[index].getType());
4392 if(AudioDeviceInfo.TYPE_WIRED_HEADSET == deviceType || AudioDeviceInfo.TYPE_WIRED_HEADPHONES == deviceType) {
4393 if ((deviceList[index].getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET ) ||
4394 (deviceList[index].getType() == AudioDeviceInfo.TYPE_WIRED_HEADPHONES )){
4395 outputDevice = deviceList[index];
4396 Log.d(LOGTAG,"startApplicationLoopBack found_dev "
4397 + deviceList[index].getType());
4398 break;
4399 }
4400 }
4401 else if (deviceList[index].getType() == deviceType) {
4402 outputDevice = deviceList[index];
4403 Log.d(LOGTAG,"startApplicationLoopBack found_dev "+ deviceList[index].getType());
4404 break;
4405 }
4406 }
4407 if (outputDevice == null) {
4408 Log.d(LOGTAG,"no output device" + deviceType + " found");
4409 return false;
4410 }
4411 if(mIsFMDeviceLoopbackActive) {
4412 if ((mReceiver != null) && mReceiver.isCherokeeChip() &&
4413 (mPref.getBoolean("SLIMBUS_SEQ", true))) {
4414 enableSlimbus(DISABLE_SLIMBUS_DATA_PORT);
4415 }
4416 configureFMDeviceLoopback_O(false);
4417 }
4418 if(!isRecordSinking()) {
4419 CreateRecordSessions();
4420 Log.d(LOGTAG,"creating AudioTrack session");
4421 }
4422 mCurrentDevice = outputDevice.getType();
4423 mAudioTrack.setPreferredDevice(outputDevice);
4424 Log.d(LOGTAG,"PreferredDevice is set to "+ outputDevice.getType());
4425 if(!isRecordSinking()) {
4426 startRecordSink();
4427 }
4428 return true;
4429 }
Venkateshwarlu Domakonda56262fb2013-07-24 19:56:59 +05304430}