diff --git a/universal7885-common/apps/FMRadio/Android.bp b/universal7885-common/apps/FMRadio/Android.bp index c8b29c2..ffb9490 100644 --- a/universal7885-common/apps/FMRadio/Android.bp +++ b/universal7885-common/apps/FMRadio/Android.bp @@ -8,12 +8,11 @@ android_app { static_libs: [ "androidx.core_core", "androidx.appcompat_appcompat", + "androidx.preference_preference", "com.google.android.material_stable", - "kotlinx_coroutines", "androidx.transition_transition", - "kotlinx_coroutines_android", "androidx.coordinatorlayout_coordinatorlayout", - "vendor.eureka.hardware.fmradio-V1-java", + "vendor.eureka.hardware.fmradio-V2-java", ], required: [ "vendor.eureka.hardware.fmradio-service", diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/FMRadioService.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/FMRadioService.kt index 97b2593..37859f4 100644 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/FMRadioService.kt +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/FMRadioService.kt @@ -10,29 +10,23 @@ import android.media.MediaMetadata import android.media.session.MediaSession import android.media.session.PlaybackState import android.os.IBinder -import com.eurekateam.fmradio.enums.OutputState +import androidx.preference.PreferenceManager import com.eurekateam.fmradio.enums.PlayState import com.eurekateam.fmradio.enums.PowerState -import com.eurekateam.fmradio.fragments.MainFragment import com.eurekateam.fmradio.utils.Log +import vendor.eureka.hardware.fmradio.SetType +import vendor.eureka.hardware.fmradio.GetType class FMRadioService : Service() { private lateinit var mContext: Context private lateinit var mAudioManager: AudioManager - private lateinit var mTracks: IntArray - private lateinit var mNativeFMInterface: NativeFMInterface + private val mNativeFMInterface = NativeFMInterface() override fun onBind(intent: Intent?): IBinder? { return null } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { Log.i("--- FMRadio Background (IN) ---") - fd = MainFragment.fd mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager - mTracks = MainFragment.mTracks - mIndex = MainFragment.getIndex() - if (mTracks.isEmpty() || mIndex == -1) { - return super.onStartCommand(intent, flags, startId) - } if (intent != null) { intent.action?.let { Log.i(it) } when (intent.action) { @@ -47,51 +41,37 @@ class FMRadioService : Service() { } ACTION_BEFORE -> { mPlayState = PlayState.STATE_PLAYING - Log.i("mCurrentIndex $mIndex") - if (mIndex > 0) { - mIndex -= 1 - } - mNativeFMInterface.setFMFreq(fd, mTracks[mIndex].toInt()) - MainFragment.mFreqCurrent = mTracks[mIndex].toInt() + mNativeFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_BEFORE_CHANNEL) } ACTION_NEXT -> { mPlayState = PlayState.STATE_PLAYING - Log.i("mCurrentIndex $mIndex") - if (mIndex < mTracks.size - 1) { - mIndex += 1 - } - mNativeFMInterface.setFMFreq(fd, mTracks[mIndex].toInt()) - MainFragment.mFreqCurrent = mTracks[mIndex].toInt() + mNativeFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_NEXT_CHANNEL) } ACTION_QUIT -> { mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager Log.i("--- FMRadio Background (OUT) ---") + mNativeFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_THREAD, 0) + mNativeFMInterface.mDevCtl.close() mAudioManager.setParameters(PowerState.FM_POWER_OFF.mAudioParam) mMediaSession.release() stopSelf() } ACTION_OUTPUT -> { - changeOutputDevice(mOutput) - if (mOutput == OutputState.OUTPUT_HEADSET) { - mOutput = OutputState.OUTPUT_SPEAKER - } else if (mOutput == OutputState.OUTPUT_SPEAKER) { - mOutput = OutputState.OUTPUT_HEADSET - } + var mSpeaker = PreferenceManager.getDefaultSharedPreferences(mContext).getBoolean("speaker", false) + mSpeaker = !mSpeaker + changeOutputDevice(mSpeaker) + PreferenceManager.getDefaultSharedPreferences(mContext).edit().putBoolean("speaker", mSpeaker).apply() } ACTION_START -> { mMediaSession = MediaSession(this, "FMRadio") - mNativeFMInterface = NativeFMInterface() mContext = this setPlaybackState() mMediaSession.isActive = true } } } - sendMetaData("FM ${mTracks[mIndex].toFloat() / 1000} Mhz") + sendMetaData("FM ${mNativeFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ).toFloat() / 1000} Mhz") startForeground(51, pushNotification()) - if (mOutput == OutputState.OUTPUT_SPEAKER) { - changeOutputDevice(OutputState.OUTPUT_HEADSET) - } Log.i("--- FMRadio Background (OUT) ---") return START_STICKY } @@ -141,13 +121,10 @@ class FMRadioService : Service() { val close = PendingIntent.getService(mContext, 0, Intent(ACTION_QUIT), PendingIntent.FLAG_IMMUTABLE) val output = PendingIntent.getService(mContext, 0, Intent(ACTION_OUTPUT), PendingIntent.FLAG_IMMUTABLE) val mOutputAction: Notification.Action = Notification.Action.Builder( - when (mOutput) { - OutputState.OUTPUT_HEADSET -> { - Icon.createWithResource(this, R.drawable.ic_volume_up) - } - OutputState.OUTPUT_SPEAKER -> { - Icon.createWithResource(this, R.drawable.ic_headphones) - } + if (PreferenceManager.getDefaultSharedPreferences(mContext).getBoolean("speaker", false)) { + Icon.createWithResource(this, R.drawable.ic_volume_up) + } else { + Icon.createWithResource(this, R.drawable.ic_headphones) }, "Output Configuration", output @@ -196,16 +173,9 @@ class FMRadioService : Service() { private const val ACTION_QUIT = "$PACKAGENAME.QUIT" private const val ACTION_OUTPUT = "$PACKAGENAME.OUTPUT" private var mPlayState: PlayState = PlayState.STATE_PLAYING - private var mOutput: OutputState = MainFragment.mHeadset - private var fd: Int = -1 - private var mIndex = -1 lateinit var mMediaSession: MediaSession } - private fun changeOutputDevice(output: OutputState) { - if (output == OutputState.OUTPUT_SPEAKER) { - mNativeFMInterface.setAudioRoute(false) - } else if (output == OutputState.OUTPUT_HEADSET) { - mNativeFMInterface.setAudioRoute(true) - } + private fun changeOutputDevice(speaker: Boolean) { + mNativeFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, if (speaker) 1 else 0) } } diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/MainActivity.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/MainActivity.kt index 11e1117..527c3c0 100644 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/MainActivity.kt +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/MainActivity.kt @@ -47,7 +47,6 @@ class MainActivity : AppCompatActivity() { private lateinit var mAlertImage: AppCompatImageView private lateinit var mAudioManager: AudioManager override fun onCreate(savedInstanceState: Bundle?) { - MainFragment.fd = mFMInterface.openFMDevice() mAlertView = (getSystemService(LAYOUT_INFLATER_SERVICE) as LayoutInflater) .inflate(R.layout.alertdialog, null) mAlertTitle = mAlertView.findViewById(R.id.alert_title) @@ -55,27 +54,16 @@ class MainActivity : AppCompatActivity() { mAlertDesc = mAlertView.findViewById(R.id.alert_desc) super.onCreate(savedInstanceState) setContentView(R.layout.activity_navigation) - if (MainFragment.fd == -1) { - Log.e("CANNOT OPEN /dev/radio0!!!") - mAlertTitle.text = getString(R.string.radio_io_error) - mAlertDesc.text = getString(R.string.radio_io_error_desc) - mAlertImage.setImageIcon(Icon.createWithResource(this, R.drawable.ic_error)) - val mAlertDialog = AlertDialog.Builder(this) - mAlertDialog - .setCancelable(false) - .setView(mAlertView) - .setNegativeButton(R.string.ok) { _: DialogInterface, _: Int -> - finish() - } - .show() - } DynamicColors.applyToActivitiesIfAvailable(application) + mFMInterface.mDevCtl.open() mAudioManager = getSystemService(AUDIO_SERVICE) as AudioManager + /** * Detects whether wired headphones is connected to this device or no * @see AudioManager.getDevices */ val mAudioDeviceInfo = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS) + for (i in mAudioDeviceInfo.indices) { if (mAudioDeviceInfo[i].type == AudioDeviceInfo.TYPE_WIRED_HEADSET || mAudioDeviceInfo[i].type == AudioDeviceInfo.TYPE_WIRED_HEADPHONES @@ -84,6 +72,7 @@ class MainActivity : AppCompatActivity() { Log.i("Wired Headphones detected") } } + if (MainFragment.mHeadSetPlugged != HeadsetState.HEADSET_STATE_CONNECTED) { mAlertTitle.text = getString(R.string.no_headphones_error) mAlertDesc.text = getString(R.string.no_headphones_error_desc) @@ -183,6 +172,7 @@ class MainActivity : AppCompatActivity() { super.onRestart() stopService(mIntent) } + companion object { private const val ACTION_START = "com.eurekateam.fmradio.START" } diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/NativeFMInterface.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/NativeFMInterface.kt index 4686f54..d6d0d54 100644 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/NativeFMInterface.kt +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/NativeFMInterface.kt @@ -3,38 +3,15 @@ package com.eurekateam.fmradio import android.os.ServiceManager import vendor.eureka.hardware.fmradio.GetType import vendor.eureka.hardware.fmradio.IFMDevControl -import vendor.eureka.hardware.fmradio.SetType class NativeFMInterface { - private val mDevCtl: IFMDevControl - private val mSysfsCtl: IFMDevControl - private val mDefaultCtl: IFMDevControl + val mDevCtl: IFMDevControl + val mSysfsCtl: IFMDevControl + val mDefaultCtl: IFMDevControl init { mDevCtl = IFMDevControl.Stub.asInterface(ServiceManager.waitForDeclaredService("vendor.eureka.hardware.fmradio.IFMDevControl/default")) mSysfsCtl = IFMDevControl.Stub.asInterface(ServiceManager.waitForDeclaredService("vendor.eureka.hardware.fmradio.IFMDevControl/support")) mDefaultCtl = if (mSysfsCtl.getValue(GetType.GET_TYPE_FM_SYSFS_IF) == 0) mSysfsCtl else mDevCtl } - - fun openFMDevice(): Int { - mDevCtl.open() - return 1 - } - - fun getFMFreq(a: Int): Long = mDevCtl.getValue(GetType.GET_TYPE_FM_FREQ).toLong() - fun setFMFreq(a: Int, freq: Int) = mDevCtl.setValue(SetType.SET_TYPE_FM_FREQ, freq) - fun setFMVolume(a: Int, volume: Int) = mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, volume) - fun setFMMute(a: Int, mute: Boolean) = mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, if (mute) 1 else 0) - fun getFmUpper(a: Int): Int = mDevCtl.getValue(GetType.GET_TYPE_FM_UPPER_LIMIT) - fun getFMLower(a: Int): Int = mDevCtl.getValue(GetType.GET_TYPE_FM_LOWER_LIMIT) - fun getRMSSI(a: Int): Int = mDevCtl.getValue(GetType.GET_TYPE_FM_RMSSI) - fun getFMTracks(fd: Int): IntArray = mDefaultCtl.getFreqsList() - fun setFMThread(a: Int, run: Boolean) = mDevCtl.setValue(SetType.SET_TYPE_FM_THREAD, if (run) 1 else 0) - fun getNextChannel(a: Int): Int = mDefaultCtl.getValue(GetType.GET_TYPE_FM_NEXT_CHANNEL) - fun getBeforeChannel(a: Int): Int = mDefaultCtl.getValue(GetType.GET_TYPE_FM_BEFORE_CHANNEL) - fun stopSearching(a: Int) = mDevCtl.setValue(SetType.SET_TYPE_FM_SEARCH_CANCEL, 0) - fun setFMRSSI(a: Int, rssi: Long) = mDevCtl.setValue(SetType.SET_TYPE_FM_RMSSI, rssi.toInt()) - fun closeFMDevice(fd: Int) = mDevCtl.close() - fun getSysfsSupport(): Boolean = mSysfsCtl.getValue(GetType.GET_TYPE_FM_SYSFS_IF) == 0 - fun setAudioRoute(speaker: Boolean) = mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, if (speaker) 1 else 0) } diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/ListViewAdapter.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/ListViewAdapter.kt index 9ddceb2..827bacf 100644 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/ListViewAdapter.kt +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/ListViewAdapter.kt @@ -7,26 +7,28 @@ import android.view.ViewGroup import android.widget.BaseAdapter import androidx.appcompat.widget.AppCompatImageView import androidx.core.content.res.ResourcesCompat -import com.eurekateam.fmradio.* +import androidx.preference.PreferenceManager import com.eurekateam.fmradio.NativeFMInterface -import com.eurekateam.fmradio.fragments.MainFragment -import com.eurekateam.fmradio.utils.FileUtilities import com.eurekateam.fmradio.utils.Log +import com.eurekateam.fmradio.R import com.google.android.material.textview.MaterialTextView +import vendor.eureka.hardware.fmradio.GetType +import vendor.eureka.hardware.fmradio.SetType class ListViewAdapter(private val mContext: Context) : BaseAdapter() { private val mFMInterface = NativeFMInterface() + private val mListChannel = mFMInterface.mDefaultCtl.getFreqsList() private var mListofViews = HashMap(30) override fun getCount(): Int { - return MainFragment.mTracks.size + return 30 } - override fun getItem(p0: Int): Any { - return MainFragment.mTracks[p0] + override fun getItem(p: Int): Any { + return mListChannel[p] } - override fun getItemId(p0: Int): Long { - return p0.toLong() + override fun getItemId(p: Int): Long { + return p.toLong() } override fun getView(id: Int, mConvertView: View?, parent: ViewGroup?): View { @@ -39,16 +41,10 @@ class ListViewAdapter(private val mContext: Context) : BaseAdapter() { mAnotherConvertView.findViewById(R.id.channel_list_title).text = String.format( mContext.getString(R.string.fm_radio_freq), - MainFragment.mTracks[id].toFloat() / 1000 + mListChannel[id].toFloat() / 1000 ) mAnotherConvertView.findViewById(R.id.channel_list_title).setOnClickListener { - mFMInterface.setFMFreq(MainFragment.fd, MainFragment.mTracks[id].toInt()) - MainFragment.mFreqCurrent = MainFragment.mTracks[id].toInt() - FileUtilities.writeToFile( - FileUtilities.mFMFreqFileName, - MainFragment.mFreqCurrent.toString(), - mContext - ) + mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_FREQ, mListChannel[id]) setCurrentFMChannel(id) } mAnotherConvertView.findViewById(R.id.star_button_list).let { @@ -58,17 +54,17 @@ class ListViewAdapter(private val mContext: Context) : BaseAdapter() { R.drawable.ic_star_filled, mContext.theme ) - val mIndex = MainFragment.mTracks[id].toInt() - if (MainFragment.mFavStats[mIndex] == null) { - MainFragment.mFavStats.putIfAbsent(mIndex, false) - } - if (MainFragment.mFavStats[mIndex]!!) { - it.setImageDrawable(mStarFilled) - } else { + val mIndex = mListChannel[id] + val mSharedPref = PreferenceManager.getDefaultSharedPreferences(mContext) + val mBefore = mSharedPref.getBoolean("fav_$mIndex", false) + if (mBefore) { it.setImageDrawable(mStar) + } else { + it.setImageDrawable(mStarFilled) } + mSharedPref.edit().putBoolean("fav_$mIndex", !mBefore).apply() } - if (MainFragment.mFreqCurrent == MainFragment.mTracks[id].toInt()) { + if (mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ) == mListChannel[id]) { setCurrentFMChannel(id) } mListofViews[id] = mAnotherConvertView!! @@ -89,7 +85,7 @@ class ListViewAdapter(private val mContext: Context) : BaseAdapter() { mListofViews[mPosition]?.setBackgroundColor( ResourcesCompat.getColor( mContext.resources, - android.R.color.system_accent3_400, + android.R.color.system_accent2_400, mContext.theme ) ) diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/PebbleLayoutAdapter.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/PebbleLayoutAdapter.kt index 646e1a4..8555f6f 100644 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/PebbleLayoutAdapter.kt +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/adapters/PebbleLayoutAdapter.kt @@ -6,38 +6,34 @@ import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import androidx.core.content.res.ResourcesCompat +import androidx.preference.PreferenceManager import com.eurekateam.fmradio.NativeFMInterface import com.eurekateam.fmradio.PebbleTextView import com.eurekateam.fmradio.R -import com.eurekateam.fmradio.fragments.MainFragment -import com.eurekateam.fmradio.utils.FileUtilities +import vendor.eureka.hardware.fmradio.SetType class PebbleLayoutAdapter(private val mContext: Context) : BaseAdapter() { - private val mFavoriteList: MutableList = emptyList().toMutableList() + private var mFavoriteList: List = emptyList() + private val mFMInterface = NativeFMInterface() + private val mListChannel = mFMInterface.mDefaultCtl.getFreqsList() + private val mSharedPref = PreferenceManager.getDefaultSharedPreferences(mContext) + init { - for (mItem in MainFragment.mFavStats) { - if (mItem.value) { - mFavoriteList.add(mItem.key) - } + for (k in mListChannel) { + if (mSharedPref.getBoolean("fav_$k", false)) mFavoriteList += k } - mFavoriteList.sort() - var mData = "" - for (i in mFavoriteList) { - mData += "$i\n" - } - FileUtilities.writeToFile(FileUtilities.mFavouriteChannelFileName, mData, mContext) } + override fun getCount(): Int { return mFavoriteList.size } - override fun getItem(p0: Int): Any { - return mFavoriteList[p0] + override fun getItem(p: Int): Any { + return mFavoriteList[p] } - private val mFMInterface = NativeFMInterface() - override fun getItemId(p0: Int): Long { - return p0.toLong() + override fun getItemId(p: Int): Long { + return p.toLong() } override fun getView(id: Int, mConvertView: View?, parent: ViewGroup?): View { @@ -55,13 +51,7 @@ class PebbleLayoutAdapter(private val mContext: Context) : BaseAdapter() { mContext.theme ) setOnClickListener { - mFMInterface.setFMFreq(MainFragment.fd, mFavoriteList[id]) - MainFragment.mFreqCurrent = mFavoriteList[id] - FileUtilities.writeToFile( - FileUtilities.mFMFreqFileName, - MainFragment.mFreqCurrent.toString(), - mContext - ) + mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_FREQ, mFavoriteList[id]) } } return mAnotherConvertView diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/enums/OutputState.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/enums/OutputState.kt deleted file mode 100644 index e836a24..0000000 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/enums/OutputState.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.eurekateam.fmradio.enums - -/*** - * [OUTPUT_SPEAKER] : Output to speaker - * - * [OUTPUT_HEADSET] : Output to headset - */ -enum class OutputState { - OUTPUT_SPEAKER, - OUTPUT_HEADSET -} diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/ChannelListFragment.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/ChannelListFragment.kt index 050501d..4b78f05 100644 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/ChannelListFragment.kt +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/ChannelListFragment.kt @@ -5,23 +5,27 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.WindowManager import android.widget.FrameLayout import android.widget.ListView import androidx.fragment.app.Fragment -import com.eurekateam.fmradio.MainActivity +import com.eurekateam.fmradio.NativeFMInterface import com.eurekateam.fmradio.R +import com.eurekateam.fmradio.MainActivity import com.eurekateam.fmradio.adapters.ListViewAdapter +import com.eurekateam.fmradio.utils.IWaitUntil +import com.eurekateam.fmradio.utils.WaitUntil import com.google.android.material.floatingactionbutton.FloatingActionButton -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import vendor.eureka.hardware.fmradio.SetType +import vendor.eureka.hardware.fmradio.GetType class ChannelListFragment : Fragment(R.layout.activity_channel_list), View.OnClickListener { private lateinit var mListView: ListView private lateinit var mFloatingActionButton: FloatingActionButton + private val mNativeIF = NativeFMInterface() + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -51,17 +55,21 @@ class ChannelListFragment : } override fun onClick(v: View?) { - GlobalScope.launch { - withContext(Dispatchers.IO) { - MainFragment.mRefreshTracks() - } - withContext(Dispatchers.Main) { - (requireActivity() as MainActivity).getMySupportFragmentManager().apply { - beginTransaction().remove(this@ChannelListFragment).commit() - executePendingTransactions() - beginTransaction().add(R.id.container_view, this@ChannelListFragment).commit() + mNativeIF.mDefaultCtl.setValue(SetType.SET_TYPE_FM_SEARCH_START, 0) + requireActivity().window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) + WaitUntil.setTimer( + requireActivity(), + object : IWaitUntil { + override fun cond(): Boolean = mNativeIF.mDefaultCtl.getValue(GetType.GET_TYPE_FM_MUTEX_LOCKED) == 0 + override fun todo() { + (requireActivity() as MainActivity).getMySupportFragmentManager().apply { + beginTransaction().remove(this@ChannelListFragment).commit() + executePendingTransactions() + beginTransaction().add(R.id.container_view, this@ChannelListFragment).commit() + } + requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) } } - } + ) } } diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/MainFragment.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/MainFragment.kt index 7ba3282..b051159 100644 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/MainFragment.kt +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/fragments/MainFragment.kt @@ -1,6 +1,7 @@ package com.eurekateam.fmradio.fragments import android.content.Context +import android.content.SharedPreferences import android.content.res.Configuration import android.graphics.drawable.Drawable import android.graphics.drawable.Icon @@ -9,25 +10,25 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.WindowManager import android.widget.FrameLayout import android.widget.SeekBar import android.widget.Toast import androidx.appcompat.widget.AppCompatSeekBar import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.Fragment +import androidx.preference.PreferenceManager import com.eurekateam.fmradio.NativeFMInterface import com.eurekateam.fmradio.R import com.eurekateam.fmradio.enums.HeadsetState -import com.eurekateam.fmradio.enums.OutputState import com.eurekateam.fmradio.enums.PowerState -import com.eurekateam.fmradio.utils.FileUtilities +import com.eurekateam.fmradio.utils.IWaitUntil import com.eurekateam.fmradio.utils.Log +import com.eurekateam.fmradio.utils.WaitUntil import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.textview.MaterialTextView -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext +import vendor.eureka.hardware.fmradio.SetType +import vendor.eureka.hardware.fmradio.GetType import java.text.DecimalFormat class MainFragment : @@ -48,6 +49,9 @@ class MainFragment : private lateinit var mAudioManager: AudioManager private lateinit var mStar: Drawable private lateinit var mStarFilled: Drawable + private lateinit var mFavList: List + private lateinit var mSharedPref: SharedPreferences + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -83,6 +87,7 @@ class MainFragment : mNextChannelBtn.setOnClickListener(this) mOutputSwitch.setOnClickListener(this) mFavButton.setOnClickListener(this) + mSharedPref = PreferenceManager.getDefaultSharedPreferences(requireContext()) var mIsLight = true val nightModeFlags = requireContext().resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK @@ -108,96 +113,33 @@ class MainFragment : setBackgroundColor(resources.getColor(android.R.color.system_accent1_700, requireContext().theme)) } } - GlobalScope.launch { - withContext(Dispatchers.IO) { - if (FileUtilities.checkIfExistFile(FileUtilities.mFavouriteChannelFileName, requireContext())) { - val mFavData = FileUtilities.readFromFile( - FileUtilities.mFavouriteChannelFileName, - requireContext() - ) - for (mItem in mFavData.split("\\r?\\n".toRegex())) { - if (mItem.isNotBlank()) { - mFavStats[mItem.toInt()] = true - } - } - } - var mMute = false - if (mFreqCurrent == -1) { - mAudioManager.setParameters(PowerState.FM_POWER_OFF.mAudioParam) - withContext(Dispatchers.Main) { - mUpdateEnableDisable(false, mRootView) - } - mMute = true - } - - if (FileUtilities.checkIfExistFile(FileUtilities.mFMFreqFileName, requireContext())) { - mFreqCurrent = FileUtilities.readFromFile( - FileUtilities.mFMFreqFileName, - requireContext() - ).toInt() - mFMInterface.setFMFreq(fd, mFreqCurrent) - withContext(Dispatchers.Main) { - mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000) - } - } - if (FileUtilities.checkIfExistFile(FileUtilities.mFMVolumeFileName, requireContext())) { - mVolume = FileUtilities.readFromFile( - FileUtilities.mFMVolumeFileName, - requireContext() - ).toInt() - mFMInterface.setFMVolume(fd, mVolume) - withContext(Dispatchers.Main) { - mSeekBar.progress = mVolume - } - } - withContext(Dispatchers.Main) { - mSeekBar.min = 1 - mSeekBar.max = 15 - } - withContext(Dispatchers.IO) { - if (mVolume == -1) { - mVolume = 8 - mFMInterface.setFMVolume(fd, mVolume) - withContext(Dispatchers.Main) { - mSeekBar.progress = mVolume - } - } - } - if (!mMute) { - mFMInterface.setFMMute(fd, true) - } - mFMInterface.setFMFreq(fd, mFMInterface.getFMLower(fd)) - mRefreshTracks() - if (mFreqCurrent != -1) { - mFMInterface.setFMFreq(fd, mFreqCurrent) - } else { - mFreqCurrent = mFMInterface.getFMLower(fd) - } - mFreqCurrent = mFMInterface.getFMFreq(fd).toInt() - mFMInterface.setFMFreq(fd, mFreqCurrent) - withContext(Dispatchers.Main) { - mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000) - } - if (!mMute) { - mFMInterface.setFMMute(fd, false) - } - if (mFreqCurrent == -1) { - mFMInterface.setFMThread(fd, true) - } - withContext(Dispatchers.Main) { - mFavButton.let { - if (mFavStats[mFreqCurrent] == null) { - mFavStats.putIfAbsent(mFreqCurrent, false) - } - if (mFavStats[mFreqCurrent]!!) { - it.setImageDrawable(mStarFilled) - } else { - it.setImageDrawable(mStar) - } + val mVolume = mSharedPref.getInt("volume", 8) + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, mVolume) + mSeekBar.min = 1 + mSeekBar.max = 15 + mSeekBar.progress = mVolume + val mRestoreFreq = mSharedPref.getInt("freq", mFMInterface.mDevCtl.getValue(GetType.GET_TYPE_FM_LOWER_LIMIT)) + mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_FREQ, mRestoreFreq) + mFMFreq.text = mCleanFormat.format(mRestoreFreq.toFloat() / 1000) + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_THREAD, 1) + Toast.makeText(requireContext(), "Updating freqs list... Please wait", Toast.LENGTH_LONG).show() + requireActivity().window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) + mFMInterface.mDefaultCtl.setValue(SetType.SET_TYPE_FM_SEARCH_START, 0) + WaitUntil.setTimer( + requireActivity(), + object : IWaitUntil { + override fun cond(): Boolean = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_MUTEX_LOCKED) == 0 + override fun todo() { + val mList = mFMInterface.mDefaultCtl.getFreqsList() + for (i in mList) { + if (mSharedPref.getBoolean("fav_$i", false)) mFavList += i } + requireActivity().window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) + Toast.makeText(requireContext(), "Done", Toast.LENGTH_SHORT).show() } } - } + ) + // Update track list and fav button return mRootView } @@ -257,85 +199,55 @@ class MainFragment : override fun onClick(v: View) { when (v.id) { mOutputSwitch.id -> { - if (mHeadset == OutputState.OUTPUT_HEADSET) { + val mCurrent = mSharedPref.getBoolean("speaker", false) + if (!mCurrent) { mOutputSwitch.setImageIcon( Icon.createWithResource( requireContext(), R.drawable.ic_volume_up ) ) - val ret = mFMInterface.setAudioRoute(true) - Log.i("mFMInterface.setAudioRoute return $ret") - } else if (mHeadset == OutputState.OUTPUT_SPEAKER) { + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, 1) + } else { mOutputSwitch.setImageIcon( Icon.createWithResource( requireContext(), R.drawable.ic_headphones ) ) - val ret = mFMInterface.setAudioRoute(false) - Log.i("mFMInterface.setAudioRoute return $ret") - } - if (mHeadset == OutputState.OUTPUT_HEADSET) { - mHeadset = OutputState.OUTPUT_SPEAKER - } else if (mHeadset == OutputState.OUTPUT_SPEAKER) { - mHeadset = OutputState.OUTPUT_HEADSET + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_SPEAKER_ROUTE, 0) } + mSharedPref.edit().putBoolean("speaker", !mCurrent).apply() } mVolumeUp.id -> { - if (mVolume < 15) { - mVolume += 1 + var mCurrentVolume = mSharedPref.getInt("volume", 8) + if (mCurrentVolume < 15) { + mCurrentVolume = mCurrentVolume + 1 } - mFMInterface.setFMVolume(fd, mVolume) - mSeekBar.progress = mVolume - Toast.makeText(requireContext(), "Volume set to $mVolume", Toast.LENGTH_SHORT).show() - FileUtilities.writeToFile( - FileUtilities.mFMVolumeFileName, - mVolume.toString(), - requireContext() - ) + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, mCurrentVolume) + mSeekBar.progress = mCurrentVolume + Toast.makeText(requireContext(), "Volume set to $mCurrentVolume", Toast.LENGTH_SHORT).show() + mSharedPref.edit().putInt("volume", mCurrentVolume).apply() } mVolumeDown.id -> { - if (mVolume > 0) { - mVolume -= 1 + var mCurrentVolume = mSharedPref.getInt("volume", 8) + if (mCurrentVolume > 0) { + mCurrentVolume = mCurrentVolume - 1 } - mFMInterface.setFMVolume(fd, mVolume) - mSeekBar.progress = mVolume - Toast.makeText(requireContext(), "Volume set to $mVolume", Toast.LENGTH_SHORT).show() - FileUtilities.writeToFile( - FileUtilities.mFMVolumeFileName, - mVolume.toString(), - requireContext() - ) + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, mCurrentVolume) + mSeekBar.progress = mCurrentVolume + Toast.makeText(requireContext(), "Volume set to $mCurrentVolume", Toast.LENGTH_SHORT).show() + mSharedPref.edit().putInt("volume", mCurrentVolume).apply() } mBeforeChannelBtn.id -> { - mFMInterface.setFMMute(fd, true) - val mTempFreq = mFMInterface.getBeforeChannel(fd) - if (mTempFreq > mFMInterface.getFMLower(fd) && mTempFreq < mFMInterface.getFmUpper( - fd - ) - ) { - mFreqCurrent = mTempFreq - } - if (!mFMInterface.getSysfsSupport()) { - mFMInterface.setFMFreq(fd, mFreqCurrent) - } - mFMInterface.setFMMute(fd, false) - FileUtilities.writeToFile( - FileUtilities.mFMFreqFileName, - mFreqCurrent.toString(), - requireContext() - ) - mFavButton.let { - if (mFavStats[mFreqCurrent] == null) { - mFavStats.putIfAbsent(mFreqCurrent, false) - } - if (mFavStats[mFreqCurrent]!!) { - it.setImageDrawable(mStarFilled) - } else { - it.setImageDrawable(mStar) - } + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 1) + val mNewFreq = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_BEFORE_CHANNEL) + mFMFreq.text = mCleanFormat.format(mNewFreq.toFloat() / 1000) + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 0) + if (mSharedPref.getBoolean("fav_$mNewFreq", false)) { + mFavButton.setImageDrawable(mStarFilled) } + mSharedPref.edit().putInt("freq", mNewFreq).apply() } mPowerBtn.id -> { if (mFMPower) { @@ -343,89 +255,40 @@ class MainFragment : mFMFreq.text = getText(R.string.inital_freq) } else { mAudioManager.setParameters(PowerState.FM_POWER_ON.mAudioParam) - mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000) + mFMFreq.text = mCleanFormat.format(mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ).toFloat() / 1000) } mUpdateEnableDisable(!mFMPower) mFMPower = !mFMPower } mNextChannelBtn.id -> { - mFMInterface.setFMMute(fd, true) - val mTempFreq = mFMInterface.getNextChannel(fd) - if (mTempFreq > mFMInterface.getFMLower(fd) && mTempFreq < mFMInterface.getFmUpper( - fd - ) - ) { - mFreqCurrent = mTempFreq - } - if (!mFMInterface.getSysfsSupport()) { - mFMInterface.setFMFreq(fd, mFreqCurrent) - } - mFMInterface.setFMMute(fd, false) - FileUtilities.writeToFile( - FileUtilities.mFMFreqFileName, - mFreqCurrent.toString(), - requireContext() - ) - mFavButton.let { - if (mFavStats[mFreqCurrent] == null) { - mFavStats.putIfAbsent(mFreqCurrent, false) - } - if (mFavStats[mFreqCurrent]!!) { - it.setImageDrawable(mStarFilled) - } else { - it.setImageDrawable(mStar) - } + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 1) + val mNewFreq = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_NEXT_CHANNEL) + mFMFreq.text = mCleanFormat.format(mNewFreq.toFloat() / 1000) + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_MUTE, 0) + if (mSharedPref.getBoolean("fav_$mNewFreq", false)) { + mFavButton.setImageDrawable(mStarFilled) } + mSharedPref.edit().putInt("freq", mNewFreq).apply() } mFavButton.id -> { - val mIndex = mFreqCurrent - if (mFavStats[mIndex] == null) { - mFavStats.putIfAbsent(mIndex, false) - } - mFavStats[mIndex] = !mFavStats[mIndex]!! - mFavButton.let { - if (mFavStats[mIndex]!!) { - it.setImageDrawable(mStarFilled) - } else { - it.setImageDrawable(mStar) - } - } - Log.d( - "Fav stats for $mIndex changed. " + - "Current value ${mFavStats[mIndex]}" - ) + val mCurrFreq = mFMInterface.mDefaultCtl.getValue(GetType.GET_TYPE_FM_FREQ) + val mCurr = mSharedPref.getBoolean("fav_$mCurrFreq", false) + if (mCurr) { mFavButton.setImageDrawable(mStar) } else { mFavButton.setImageDrawable(mStarFilled) } + mSharedPref.edit().putBoolean("fav_$mCurrFreq", !mCurr).apply() } } - mFMFreq.text = mCleanFormat.format(mFreqCurrent.toFloat() / 1000) } override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) { - mFMInterface.setFMVolume(fd, p1) - FileUtilities.writeToFile(FileUtilities.mFMVolumeFileName, p1.toString(), requireContext()) - mVolume = p1 + mFMInterface.mDevCtl.setValue(SetType.SET_TYPE_FM_VOLUME, p1) + mSharedPref.edit().putInt("volume", p1).apply() } override fun onStartTrackingTouch(p0: SeekBar?) {} - override fun onStopTrackingTouch(p0: SeekBar?) { - Toast.makeText(requireContext(), "Volume set to $mVolume", Toast.LENGTH_SHORT).show() - } + override fun onStopTrackingTouch(p0: SeekBar?) {} + companion object { - private var mVolume = -1 - var fd = -1 - var mHeadset = OutputState.OUTPUT_SPEAKER - var mFreqCurrent = -1 - private var mFMPower = false + var mFMPower = false var mHeadSetPlugged: HeadsetState = HeadsetState.HEADSET_STATE_DISCONNECTED - var mTracks: IntArray = emptyArray().toIntArray() - fun mRefreshTracks() { - NativeFMInterface().setFMFreq(fd, NativeFMInterface().getFMLower(fd)) - mTracks = NativeFMInterface().getFMTracks(fd) - mTracks = MainFragment().removeZeros(mTracks) - (mFreqCurrent != -1).let { NativeFMInterface().setFMFreq(fd, mFreqCurrent) } - } - fun getIndex(): Int { - return mTracks.indexOf(mFreqCurrent) - } - val mFavStats = HashMap(30) } /** diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/FileUtilities.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/FileUtilities.kt deleted file mode 100644 index 4e57529..0000000 --- a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/FileUtilities.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.eurekateam.fmradio.utils - -import android.content.Context -import java.io.* - -object FileUtilities { - const val mFMFreqFileName = "fm_freq_current" - const val mFMVolumeFileName = "fm_volume_current" - const val mFavouriteChannelFileName = "fm_fav_freqs" - - fun writeToFile(fileName: String, data: String, mContext: Context) { - var os: OutputStream? = null - try { - os = FileOutputStream(File(mContext.filesDir.absolutePath + "/" + fileName)) - os.write(data.toByteArray(), 0, data.length) - } catch (e: IOException) { - e.printStackTrace() - } finally { - try { - os?.close() - } catch (e: IOException) { - e.printStackTrace() - } - } - } - fun readFromFile(fileName: String, mContext: Context): String { - val mFile = File(mContext.filesDir.absolutePath + "/" + fileName) - var os: InputStream? = null - val mByteArray = ByteArray(mFile.length().toInt()) - try { - os = FileInputStream(mFile) - os.read(mByteArray) - } catch (e: IOException) { - e.printStackTrace() - } finally { - try { - os?.close() - } catch (e: IOException) { - e.printStackTrace() - } - } - return String(mByteArray) - } - - fun checkIfExistFile(fileName: String, mContext: Context): Boolean { - return File(mContext.filesDir.absolutePath + "/" + fileName).exists() - } -} diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/IWaitUntil.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/IWaitUntil.kt new file mode 100644 index 0000000..7446b39 --- /dev/null +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/IWaitUntil.kt @@ -0,0 +1,6 @@ +package com.eurekateam.fmradio.utils + +interface IWaitUntil { + fun cond(): Boolean + fun todo() +} diff --git a/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/WaitUntil.kt b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/WaitUntil.kt new file mode 100644 index 0000000..33c6f0b --- /dev/null +++ b/universal7885-common/apps/FMRadio/src/com/eurekateam/fmradio/utils/WaitUntil.kt @@ -0,0 +1,24 @@ +package com.eurekateam.fmradio.utils + +import android.app.Activity + +import java.util.Timer +import java.util.TimerTask + +object WaitUntil { + fun setTimer(act: Activity, todo: IWaitUntil, timeout: Long = 15000) { + Timer().schedule( + object : TimerTask() { + override fun run() { + act.runOnUiThread({ + if (todo.cond()) { + todo.todo() + cancel() + } + }) + } + }, + timeout + ) + } +}