1 /** 2 * Copyright (C) 2021 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 package com.android.car.voicecontrol; 17 18 import android.os.Bundle; 19 import android.os.Parcelable; 20 import android.service.voice.VoiceInteractionSession; 21 import android.support.v4.media.session.PlaybackStateCompat; 22 23 import java.util.ArrayList; 24 import java.util.HashMap; 25 import java.util.List; 26 import java.util.Map; 27 28 /** 29 * Logging utility methods. 30 */ 31 public class LogUtils { LogUtils()32 private LogUtils() {} 33 34 /** 35 * Converts {@link VoiceInteractionSession#onShow(Bundle, int)} flags to human readable string. 36 */ flagsToString(int showFlags)37 public static String flagsToString(int showFlags) { 38 List<String> parsedFlags = new ArrayList<>(); 39 if ((showFlags & VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE) != 0) { 40 parsedFlags.add("SOURCE_ASSIST_GESTURE"); 41 } 42 if ((showFlags & VoiceInteractionSession.SHOW_SOURCE_APPLICATION) != 0) { 43 parsedFlags.add("SOURCE_APPLICATION"); 44 } 45 if ((showFlags & VoiceInteractionSession.SHOW_SOURCE_ACTIVITY) != 0) { 46 parsedFlags.add("SOURCE_ACTIVITY"); 47 } 48 if ((showFlags & VoiceInteractionSession.SHOW_SOURCE_PUSH_TO_TALK) != 0) { 49 parsedFlags.add("SOURCE_PUSH_TO_TALK"); 50 } 51 if ((showFlags & VoiceInteractionSession.SHOW_SOURCE_NOTIFICATION) != 0) { 52 parsedFlags.add("SOURCE_NOTIFICATION"); 53 } 54 if ((showFlags & VoiceInteractionSession.SHOW_SOURCE_AUTOMOTIVE_SYSTEM_UI) != 0) { 55 parsedFlags.add("SOURCE_AUTOMOTIVE_SYSTEM_UI"); 56 } 57 if ((showFlags & VoiceInteractionSession.SHOW_WITH_ASSIST) != 0) { 58 parsedFlags.add("WITH_ASSIST"); 59 } 60 if ((showFlags & VoiceInteractionSession.SHOW_WITH_SCREENSHOT) != 0) { 61 parsedFlags.add("WITH_SCREENSHOT"); 62 } 63 64 return String.join(", ", parsedFlags); 65 } 66 67 /** 68 * Converts a {@link Parcelable} to human readable string. 69 */ parcelableToString(Parcelable p)70 public static String parcelableToString(Parcelable p) { 71 StringBuilder sb = new StringBuilder(); 72 parcelableToString(p, sb); 73 return sb.toString(); 74 } 75 parcelableToString(Parcelable p, StringBuilder sb)76 private static void parcelableToString(Parcelable p, StringBuilder sb) { 77 sb.append("["); 78 if (p instanceof Bundle) { 79 Bundle b = (Bundle) p; 80 for (String key : b.keySet()) { 81 Object value = b.get(key); 82 if (sb.length() != 0) { 83 sb.append(", "); 84 } 85 sb.append(key); 86 sb.append("="); 87 if (value instanceof Parcelable) { 88 parcelableToString((Parcelable) value, sb); 89 } else { 90 sb.append(value); 91 } 92 } 93 } else { 94 sb.append(p); 95 } 96 sb.append("]"); 97 } 98 99 private static final Map<Long, String> PLAYBACK_STATES = Map.ofEntries( 100 Map.entry(PlaybackStateCompat.ACTION_STOP, "STOP"), 101 Map.entry(PlaybackStateCompat.ACTION_PAUSE, "ACTION_PAUSE"), 102 Map.entry(PlaybackStateCompat.ACTION_PLAY, "ACTION_PLAY"), 103 Map.entry(PlaybackStateCompat.ACTION_REWIND, "ACTION_REWIND"), 104 Map.entry(PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS, "ACTION_SKIP_TO_PREVIOUS"), 105 Map.entry(PlaybackStateCompat.ACTION_SKIP_TO_NEXT, "ACTION_SKIP_TO_NEXT"), 106 Map.entry(PlaybackStateCompat.ACTION_FAST_FORWARD, "ACTION_FAST_FORWARD"), 107 Map.entry(PlaybackStateCompat.ACTION_SET_RATING, "ACTION_SET_RATING"), 108 Map.entry(PlaybackStateCompat.ACTION_SEEK_TO, "ACTION_SEEK_TO"), 109 Map.entry(PlaybackStateCompat.ACTION_PLAY_PAUSE, "ACTION_PLAY_PAUSE"), 110 Map.entry(PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID, "ACTION_PLAY_FROM_MEDIA_ID"), 111 Map.entry(PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH, "ACTION_PLAY_FROM_SEARCH"), 112 Map.entry(PlaybackStateCompat.ACTION_SKIP_TO_QUEUE_ITEM, "ACTION_SKIP_TO_QUEUE_ITEM"), 113 Map.entry(PlaybackStateCompat.ACTION_PLAY_FROM_URI, "ACTION_PLAY_FROM_URI"), 114 Map.entry(PlaybackStateCompat.ACTION_PREPARE, "ACTION_PREPARE"), 115 Map.entry( 116 PlaybackStateCompat.ACTION_PREPARE_FROM_MEDIA_ID, 117 "ACTION_PREPARE_FROM_MEDIA_ID"), 118 Map.entry(PlaybackStateCompat.ACTION_PREPARE_FROM_SEARCH, "ACTION_PREPARE_FROM_SEARCH"), 119 Map.entry(PlaybackStateCompat.ACTION_PREPARE_FROM_URI, "ACTION_PREPARE_FROM_URI"), 120 Map.entry(PlaybackStateCompat.ACTION_SET_REPEAT_MODE, "ACTION_SET_REPEAT_MODE"), 121 Map.entry( 122 PlaybackStateCompat.ACTION_SET_CAPTIONING_ENABLED, 123 "ACTION_SET_CAPTIONING_ENABLED"), 124 Map.entry(PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE, "ACTION_SET_SHUFFLE_MODE") 125 ); 126 127 /** 128 * Converts a {@link PlaybackStateCompat} action to readable string. 129 */ playbackActionToString(long action)130 public static String playbackActionToString(long action) { 131 List<String> actions = new ArrayList<>(); 132 for (Map.Entry<Long, String> e : PLAYBACK_STATES.entrySet()) { 133 if ((e.getKey() & action) != 0) { 134 actions.add(e.getValue()); 135 } 136 } 137 return String.join(", ", actions); 138 } 139 } 140