1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.volume;
18
19import android.content.Context;
20import android.media.AudioManager;
21import android.media.MediaMetadata;
22import android.media.VolumeProvider;
23import android.media.session.MediaController.PlaybackInfo;
24import android.media.session.PlaybackState;
25import android.telephony.TelephonyManager;
26import android.view.View;
27import android.widget.TextView;
28
29import java.text.SimpleDateFormat;
30import java.util.Date;
31import java.util.Locale;
32import java.util.Objects;
33
34/**
35 * Static helpers for the volume dialog.
36 */
37class Util {
38
39    // Note: currently not shown (only used in the text footer)
40    private static final SimpleDateFormat HMMAA = new SimpleDateFormat("h:mm aa", Locale.US);
41
42    private static int[] AUDIO_MANAGER_FLAGS = new int[] {
43        AudioManager.FLAG_SHOW_UI,
44        AudioManager.FLAG_VIBRATE,
45        AudioManager.FLAG_PLAY_SOUND,
46        AudioManager.FLAG_ALLOW_RINGER_MODES,
47        AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE,
48        AudioManager.FLAG_SHOW_VIBRATE_HINT,
49        AudioManager.FLAG_SHOW_SILENT_HINT,
50        AudioManager.FLAG_FROM_KEY,
51        AudioManager.FLAG_SHOW_UI_WARNINGS,
52    };
53
54    private static String[] AUDIO_MANAGER_FLAG_NAMES = new String[] {
55        "SHOW_UI",
56        "VIBRATE",
57        "PLAY_SOUND",
58        "ALLOW_RINGER_MODES",
59        "REMOVE_SOUND_AND_VIBRATE",
60        "SHOW_VIBRATE_HINT",
61        "SHOW_SILENT_HINT",
62        "FROM_KEY",
63        "SHOW_UI_WARNINGS",
64    };
65
66    public static String logTag(Class<?> c) {
67        final String tag = "vol." + c.getSimpleName();
68        return tag.length() < 23 ? tag : tag.substring(0, 23);
69    }
70
71    public static String ringerModeToString(int ringerMode) {
72        switch (ringerMode) {
73            case AudioManager.RINGER_MODE_SILENT: return "RINGER_MODE_SILENT";
74            case AudioManager.RINGER_MODE_VIBRATE: return "RINGER_MODE_VIBRATE";
75            case AudioManager.RINGER_MODE_NORMAL: return "RINGER_MODE_NORMAL";
76            default: return "RINGER_MODE_UNKNOWN_" + ringerMode;
77        }
78    }
79
80    public static String mediaMetadataToString(MediaMetadata metadata) {
81        return metadata.getDescription().toString();
82    }
83
84    public static String playbackInfoToString(PlaybackInfo info) {
85        if (info == null) return null;
86        final String type = playbackInfoTypeToString(info.getPlaybackType());
87        final String vc = volumeProviderControlToString(info.getVolumeControl());
88        return String.format("PlaybackInfo[vol=%s,max=%s,type=%s,vc=%s],atts=%s",
89                info.getCurrentVolume(), info.getMaxVolume(), type, vc, info.getAudioAttributes());
90    }
91
92    public static String playbackInfoTypeToString(int type) {
93        switch (type) {
94            case PlaybackInfo.PLAYBACK_TYPE_LOCAL: return "LOCAL";
95            case PlaybackInfo.PLAYBACK_TYPE_REMOTE: return "REMOTE";
96            default: return "UNKNOWN_" + type;
97        }
98    }
99
100    public static String playbackStateStateToString(int state) {
101        switch (state) {
102            case PlaybackState.STATE_NONE: return "STATE_NONE";
103            case PlaybackState.STATE_STOPPED: return "STATE_STOPPED";
104            case PlaybackState.STATE_PAUSED: return "STATE_PAUSED";
105            case PlaybackState.STATE_PLAYING: return "STATE_PLAYING";
106            default: return "UNKNOWN_" + state;
107        }
108    }
109
110    public static String volumeProviderControlToString(int control) {
111        switch (control) {
112            case VolumeProvider.VOLUME_CONTROL_ABSOLUTE: return "VOLUME_CONTROL_ABSOLUTE";
113            case VolumeProvider.VOLUME_CONTROL_FIXED: return "VOLUME_CONTROL_FIXED";
114            case VolumeProvider.VOLUME_CONTROL_RELATIVE: return "VOLUME_CONTROL_RELATIVE";
115            default: return "VOLUME_CONTROL_UNKNOWN_" + control;
116        }
117    }
118
119    public static String playbackStateToString(PlaybackState playbackState) {
120        if (playbackState == null) return null;
121        return playbackStateStateToString(playbackState.getState()) + " " + playbackState;
122    }
123
124    public static String audioManagerFlagsToString(int value) {
125        return bitFieldToString(value, AUDIO_MANAGER_FLAGS, AUDIO_MANAGER_FLAG_NAMES);
126    }
127
128    private static String bitFieldToString(int value, int[] values, String[] names) {
129        if (value == 0) return "";
130        final StringBuilder sb = new StringBuilder();
131        for (int i = 0; i < values.length; i++) {
132            if ((value & values[i]) != 0) {
133                if (sb.length() > 0) sb.append(',');
134                sb.append(names[i]);
135            }
136            value &= ~values[i];
137        }
138        if (value != 0) {
139            if (sb.length() > 0) sb.append(',');
140            sb.append("UNKNOWN_").append(value);
141        }
142        return sb.toString();
143    }
144
145    public static String getShortTime(long millis) {
146        return HMMAA.format(new Date(millis));
147    }
148
149    private static CharSequence emptyToNull(CharSequence str) {
150        return str == null || str.length() == 0 ? null : str;
151    }
152
153    public static boolean setText(TextView tv, CharSequence text) {
154        if (Objects.equals(emptyToNull(tv.getText()), emptyToNull(text))) return false;
155        tv.setText(text);
156        return true;
157    }
158
159    public static final void setVisOrGone(View v, boolean vis) {
160        if (v == null || (v.getVisibility() == View.VISIBLE) == vis) return;
161        v.setVisibility(vis ? View.VISIBLE : View.GONE);
162    }
163
164    public static final void setVisOrInvis(View v, boolean vis) {
165        if (v == null || (v.getVisibility() == View.VISIBLE) == vis) return;
166        v.setVisibility(vis ? View.VISIBLE : View.INVISIBLE);
167    }
168
169    public static boolean isVoiceCapable(Context context) {
170        final TelephonyManager telephony =
171                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
172        return telephony != null && telephony.isVoiceCapable();
173    }
174}
175