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