1package android.support.v17.leanback.widget;
2
3import android.content.Context;
4import android.content.res.Resources;
5import android.graphics.Color;
6import android.support.v17.leanback.R;
7import android.util.AttributeSet;
8
9/**
10 * A subclass of {@link SearchOrbView} that visualizes the state of an ongoing speech recognition.
11 */
12public class SpeechOrbView extends SearchOrbView {
13    private final float mSoundLevelMaxZoom;
14    private final Colors mListeningOrbColors;
15    private final Colors mNotListeningOrbColors;
16
17    private int mCurrentLevel = 0;
18    private boolean mListening = false;
19
20    public SpeechOrbView(Context context) {
21        this(context, null);
22    }
23
24    public SpeechOrbView(Context context, AttributeSet attrs) {
25        this(context, attrs, 0);
26    }
27
28    public SpeechOrbView(Context context, AttributeSet attrs, int defStyle) {
29        super(context, attrs, defStyle);
30
31        Resources resources = context.getResources();
32        mSoundLevelMaxZoom =
33                resources.getFraction(R.fraction.lb_search_bar_speech_orb_max_level_zoom, 1, 1);
34
35        mNotListeningOrbColors = new Colors(resources.getColor(R.color.lb_speech_orb_not_recording),
36                resources.getColor(R.color.lb_speech_orb_not_recording_pulsed),
37                resources.getColor(R.color.lb_speech_orb_not_recording_icon));
38        mListeningOrbColors = new Colors(resources.getColor(R.color.lb_speech_orb_recording),
39                resources.getColor(R.color.lb_speech_orb_recording),
40                Color.TRANSPARENT);
41
42        showNotListening();
43    }
44
45    @Override
46    int getLayoutResourceId() {
47        return R.layout.lb_speech_orb;
48    }
49
50    /**
51     * Sets the view to display listening state.
52     */
53    public void showListening() {
54        setOrbColors(mListeningOrbColors);
55        setOrbIcon(getResources().getDrawable(R.drawable.lb_ic_search_mic));
56        // Assume focused
57        animateOnFocus(true);
58        enableOrbColorAnimation(false);
59        scaleOrbViewOnly(1f);
60        mCurrentLevel = 0;
61        mListening = true;
62    }
63
64    /**
65     * Sets the view to display the not-listening state.
66     */
67    public void showNotListening() {
68        setOrbColors(mNotListeningOrbColors);
69        setOrbIcon(getResources().getDrawable(R.drawable.lb_ic_search_mic_out));
70        animateOnFocus(hasFocus());
71        scaleOrbViewOnly(1f);
72        mListening = false;
73    }
74
75    /**
76     * Sets the sound level while listening to speech.
77     */
78    public void setSoundLevel(int level) {
79        if (!mListening) return;
80
81        // Either ease towards the target level, or decay away from it depending on whether
82        // its higher or lower than the current.
83        if (level > mCurrentLevel) {
84            mCurrentLevel = mCurrentLevel + ((level - mCurrentLevel) / 2);
85        } else {
86            mCurrentLevel = (int) (mCurrentLevel * 0.7f);
87        }
88
89        float zoom = 1f + (mSoundLevelMaxZoom - getFocusedZoom()) * mCurrentLevel / 100;
90
91        scaleOrbViewOnly(zoom);
92    }
93}
94