/* * Copyright (c) 2016, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.car.radio; import android.content.Context; import android.hardware.radio.ProgramSelector; import android.view.View; import android.widget.TextView; import androidx.annotation.NonNull; import com.android.car.radio.bands.ProgramType; import com.android.car.radio.bands.RegionConfig; import com.android.car.radio.widget.BandSelectorFlat; import java.util.ArrayList; import java.util.List; import java.util.Objects; public class ManualTunerController { private final Object mLock = new Object(); private final List mDigitButtons = new ArrayList<>(); private final View mEnterButton; private final TextView mChannelDisplay; private BandSelectorFlat mBandSelector; private ProgramType mProgramType; private final RegionConfig mRegionConfig; private final TuningDoneListener mDoneListener; private int mEnteredDigits; /** * Listener for manual tuning done event. */ public interface TuningDoneListener { /** * Called when the user accepted channel selection. */ void onDone(@NonNull ProgramSelector sel); } public ManualTunerController(Context context, View container, @NonNull RegionConfig regionConfig, @NonNull TuningDoneListener doneListener) { mRegionConfig = Objects.requireNonNull(regionConfig); mDoneListener = Objects.requireNonNull(doneListener); mChannelDisplay = Objects.requireNonNull(container.findViewById(R.id.manual_tuner_channel)); mEnterButton = container.findViewById(R.id.manual_tuner_done_button); mBandSelector = container.findViewById(R.id.manual_tuner_band_selector); mEnterButton.setOnClickListener(this::onDoneClick); mBandSelector.setCallback(this::switchProgramType); mBandSelector.setSupportedProgramTypes(regionConfig.getSupportedProgramTypes()); View dialpad = container.findViewById(R.id.dialpad_layout); View.OnClickListener digitClickListener = this::onDigitClick; for (int i = 0; i <= 9; i++) { View btn = dialpad.findViewWithTag(Integer.toString(i)); btn.setOnClickListener(digitClickListener); mDigitButtons.add(i, btn); } View backspace = dialpad.findViewById(R.id.manual_tuner_backspace); backspace.setOnClickListener(this::onBackspaceClick); switchProgramType(ProgramType.FM); } private void updateDisplay() { synchronized (mLock) { mChannelDisplay.setText(mProgramType.format(mEnteredDigits)); mEnterButton.setEnabled(mProgramType.isComplete(mRegionConfig, mEnteredDigits)); boolean[] valid = mProgramType.getValidAppendices(mRegionConfig, mEnteredDigits); for (int i = 0; i < 10; i++) { mDigitButtons.get(i).setEnabled(valid[i]); } } } private void onDigitClick(View btn) { int digit = Integer.parseInt((String) btn.getTag()); synchronized (mLock) { mEnteredDigits *= 10; mEnteredDigits += digit; } updateDisplay(); } private void onBackspaceClick(View btn) { synchronized (mLock) { mEnteredDigits /= 10; } updateDisplay(); } private void onDoneClick(View btn) { synchronized (mLock) { mDoneListener.onDone(mProgramType.parseDigits(mEnteredDigits)); mEnteredDigits = 0; } updateDisplay(); } /** * Switches program type (band). */ public void switchProgramType(@NonNull ProgramType pt) { Objects.requireNonNull(pt); synchronized (mLock) { if (mProgramType == pt) return; mProgramType = pt; mEnteredDigits = 0; mBandSelector.setType(pt); } updateDisplay(); } }