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, 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     final String mMediaItemIdToToggle;
124 
TmaMediaEvent(EventState state, StateErrorCode errorCode, String errorMessage, String actionLabel, ResolutionIntent resolutionIntent, Action action, int postDelayMs, String exceptionClass, String mediaItemIdToToggle)125     public TmaMediaEvent(EventState state, StateErrorCode errorCode, String errorMessage,
126             String actionLabel, ResolutionIntent resolutionIntent, Action action, int postDelayMs,
127             String exceptionClass, String mediaItemIdToToggle) {
128         mState = state;
129         mErrorCode = errorCode;
130         mErrorMessage = errorMessage;
131         mActionLabel = actionLabel;
132         mResolutionIntent = resolutionIntent;
133         mAction = action;
134         mPostDelayMs = postDelayMs;
135         mExceptionClass = exceptionClass;
136         mMediaItemIdToToggle = mediaItemIdToToggle;
137     }
138 
premiumAccountRequired()139     boolean premiumAccountRequired() {
140         return mState == EventState.ERROR && mErrorCode == StateErrorCode.PREMIUM_ACCOUNT_REQUIRED;
141     }
142 
maybeThrow()143     void maybeThrow() {
144         if (mExceptionClass != null) {
145             RuntimeException exception = null;
146             try {
147                 Class aClass = Class.forName(mExceptionClass);
148                 exception = (RuntimeException) aClass.newInstance();
149             } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
150                 Log.e(TAG, "Class error for " + mExceptionClass + " : " + e);
151             }
152 
153             if (exception != null) throw exception;
154         }
155     }
156 
157     @Override
toString()158     public String toString() {
159         return "TmaMediaEvent{" +
160                 "mState=" + mState +
161                 ", mErrorCode=" + mErrorCode +
162                 ", mErrorMessage='" + mErrorMessage + '\'' +
163                 ", mActionLabel='" + mActionLabel + '\'' +
164                 ", mResolutionIntent=" + mResolutionIntent +
165                 ", mAction=" + mAction +
166                 ", mPostDelayMs=" + mPostDelayMs +
167                 ", mExceptionClass=" + mExceptionClass +
168                 '}';
169     }
170 }
171