1 /* 2 * Copyright 2019 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 17 package com.android.car.media.testmediaapp; 18 19 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_ACTION_ABORTED; 20 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_APP_ERROR; 21 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_AUTHENTICATION_EXPIRED; 22 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_CONCURRENT_STREAM_LIMIT; 23 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_CONTENT_ALREADY_PLAYING; 24 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_END_OF_QUEUE; 25 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION; 26 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_NOT_SUPPORTED; 27 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_PARENTAL_CONTROL_RESTRICTED; 28 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED; 29 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_SKIP_LIMIT_REACHED; 30 import static android.support.v4.media.session.PlaybackStateCompat.ERROR_CODE_UNKNOWN_ERROR; 31 import static android.support.v4.media.session.PlaybackStateCompat.STATE_BUFFERING; 32 import static android.support.v4.media.session.PlaybackStateCompat.STATE_CONNECTING; 33 import static android.support.v4.media.session.PlaybackStateCompat.STATE_ERROR; 34 import static android.support.v4.media.session.PlaybackStateCompat.STATE_FAST_FORWARDING; 35 import static android.support.v4.media.session.PlaybackStateCompat.STATE_NONE; 36 import static android.support.v4.media.session.PlaybackStateCompat.STATE_PAUSED; 37 import static android.support.v4.media.session.PlaybackStateCompat.STATE_PLAYING; 38 import static android.support.v4.media.session.PlaybackStateCompat.STATE_REWINDING; 39 import static android.support.v4.media.session.PlaybackStateCompat.STATE_SKIPPING_TO_NEXT; 40 import static android.support.v4.media.session.PlaybackStateCompat.STATE_SKIPPING_TO_PREVIOUS; 41 import static android.support.v4.media.session.PlaybackStateCompat.STATE_SKIPPING_TO_QUEUE_ITEM; 42 import static android.support.v4.media.session.PlaybackStateCompat.STATE_STOPPED; 43 44 import android.support.v4.media.session.PlaybackStateCompat.State; 45 import android.util.Log; 46 47 /** 48 * Contains the info needed to generate a new playback state. 49 */ 50 public class TmaMediaEvent { 51 52 private static final String TAG = "TmaMediaEvent"; 53 54 public static final TmaMediaEvent INSTANT_PLAYBACK = 55 new TmaMediaEvent(EventState.PLAYING, StateErrorCode.UNKNOWN_ERROR, null, null, 56 ResolutionIntent.NONE, Action.NONE, 0, null); 57 58 /** The name of each entry is the value used in the json file. */ 59 public enum EventState { 60 NONE (STATE_NONE), 61 STOPPED (STATE_STOPPED), 62 PAUSED (STATE_PAUSED), 63 PLAYING (STATE_PLAYING), 64 FAST_FORWARDING (STATE_FAST_FORWARDING), 65 REWINDING (STATE_REWINDING), 66 BUFFERING (STATE_BUFFERING), 67 ERROR (STATE_ERROR), 68 CONNECTING (STATE_CONNECTING), 69 SKIPPING_TO_PREVIOUS (STATE_SKIPPING_TO_PREVIOUS), 70 SKIPPING_TO_NEXT (STATE_SKIPPING_TO_NEXT), 71 SKIPPING_TO_QUEUE_ITEM (STATE_SKIPPING_TO_QUEUE_ITEM); 72 73 @State final int mValue; 74 EventState(@tate int value)75 EventState(@State int value) { 76 mValue = value; 77 } 78 } 79 80 /** The name of each entry is the value used in the json file. */ 81 public enum StateErrorCode { 82 UNKNOWN_ERROR (ERROR_CODE_UNKNOWN_ERROR), 83 APP_ERROR (ERROR_CODE_APP_ERROR), 84 NOT_SUPPORTED (ERROR_CODE_NOT_SUPPORTED), 85 AUTHENTICATION_EXPIRED (ERROR_CODE_AUTHENTICATION_EXPIRED), 86 PREMIUM_ACCOUNT_REQUIRED (ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED), 87 CONCURRENT_STREAM_LIMIT (ERROR_CODE_CONCURRENT_STREAM_LIMIT), 88 PARENTAL_CONTROL_RESTRICTED (ERROR_CODE_PARENTAL_CONTROL_RESTRICTED), 89 NOT_AVAILABLE_IN_REGION (ERROR_CODE_NOT_AVAILABLE_IN_REGION), 90 CONTENT_ALREADY_PLAYING (ERROR_CODE_CONTENT_ALREADY_PLAYING), 91 SKIP_LIMIT_REACHED (ERROR_CODE_SKIP_LIMIT_REACHED), 92 ACTION_ABORTED (ERROR_CODE_ACTION_ABORTED), 93 END_OF_QUEUE (ERROR_CODE_END_OF_QUEUE); 94 95 @State final int mValue; 96 StateErrorCode(@tate int value)97 StateErrorCode(@State int value) { 98 mValue = value; 99 } 100 } 101 102 /** The name of each entry is the value used in the json file. */ 103 public enum ResolutionIntent { 104 NONE, 105 PREFS 106 } 107 108 /** The name of each entry is the value used in the json file. */ 109 public enum Action { 110 NONE, 111 RESET_METADATA 112 } 113 114 final EventState mState; 115 final StateErrorCode mErrorCode; 116 final String mErrorMessage; 117 final String mActionLabel; 118 final ResolutionIntent mResolutionIntent; 119 final Action mAction; 120 /** How long to wait before sending the event to the app. */ 121 final int mPostDelayMs; 122 private final String mExceptionClass; 123 TmaMediaEvent(EventState state, StateErrorCode errorCode, String errorMessage, String actionLabel, ResolutionIntent resolutionIntent, Action action, int postDelayMs, String exceptionClass)124 public TmaMediaEvent(EventState state, StateErrorCode errorCode, String errorMessage, 125 String actionLabel, ResolutionIntent resolutionIntent, Action action, int postDelayMs, 126 String exceptionClass) { 127 mState = state; 128 mErrorCode = errorCode; 129 mErrorMessage = errorMessage; 130 mActionLabel = actionLabel; 131 mResolutionIntent = resolutionIntent; 132 mAction = action; 133 mPostDelayMs = postDelayMs; 134 mExceptionClass = exceptionClass; 135 } 136 premiumAccountRequired()137 boolean premiumAccountRequired() { 138 return mState == EventState.ERROR && mErrorCode == StateErrorCode.PREMIUM_ACCOUNT_REQUIRED; 139 } 140 maybeThrow()141 void maybeThrow() { 142 if (mExceptionClass != null) { 143 RuntimeException exception = null; 144 try { 145 Class aClass = Class.forName(mExceptionClass); 146 exception = (RuntimeException) aClass.newInstance(); 147 } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { 148 Log.e(TAG, "Class error for " + mExceptionClass + " : " + e); 149 } 150 151 if (exception != null) throw exception; 152 } 153 } 154 155 @Override toString()156 public String toString() { 157 return "TmaMediaEvent{" + 158 "mState=" + mState + 159 ", mErrorCode=" + mErrorCode + 160 ", mErrorMessage='" + mErrorMessage + '\'' + 161 ", mActionLabel='" + mActionLabel + '\'' + 162 ", mResolutionIntent=" + mResolutionIntent + 163 ", mAction=" + mAction + 164 ", mPostDelayMs=" + mPostDelayMs + 165 ", mExceptionClass=" + mExceptionClass + 166 '}'; 167 } 168 } 169