blob: f9c8a8c05797a766db33d27f3cfb97432adae52a [file] [log] [blame]
/*
* 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<View> 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();
}
}