• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 package android.car.media;
17 
18 import android.annotation.IntDef;
19 import android.annotation.NonNull;
20 import android.annotation.RequiresPermission;
21 import android.annotation.SystemApi;
22 import android.car.Car;
23 import android.car.CarManagerBase;
24 import android.car.annotation.AddedInOrBefore;
25 import android.content.ComponentName;
26 import android.os.IBinder;
27 import android.os.RemoteException;
28 
29 import com.android.internal.annotations.GuardedBy;
30 
31 import java.lang.annotation.Retention;
32 import java.lang.annotation.RetentionPolicy;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 
37 /**
38  * API for updating and receiving updates to the primary media source in the car.
39  * @hide
40  */
41 @SystemApi
42 public final class CarMediaManager extends CarManagerBase {
43 
44     @AddedInOrBefore(majorVersion = 33)
45     public static final int MEDIA_SOURCE_MODE_PLAYBACK = 0;
46     @AddedInOrBefore(majorVersion = 33)
47     public static final int MEDIA_SOURCE_MODE_BROWSE = 1;
48 
49     /** @hide */
50     @IntDef(prefix = { "MEDIA_SOURCE_MODE_" }, value = {
51             MEDIA_SOURCE_MODE_PLAYBACK,
52             MEDIA_SOURCE_MODE_BROWSE
53     })
54     @Retention(RetentionPolicy.SOURCE)
55     public @interface MediaSourceMode {}
56 
57     private final Object mLock = new Object();
58 
59     private final ICarMedia mService;
60     @GuardedBy("mLock")
61     private Map<MediaSourceChangedListener, ICarMediaSourceListener> mCallbackMap = new HashMap();
62 
63     /**
64      * Get an instance of the CarMediaManager.
65      *
66      * Should not be obtained directly by clients, use {@link Car#getCarManager(String)} instead.
67      * @hide
68      */
CarMediaManager(Car car, IBinder service)69     public CarMediaManager(Car car, IBinder service) {
70         super(car);
71         mService = ICarMedia.Stub.asInterface(service);
72     }
73 
74     /**
75      * Listener for updates to the primary media source
76      */
77     public interface MediaSourceChangedListener {
78 
79         /**
80          * Called when the primary media source is changed
81          */
82         @AddedInOrBefore(majorVersion = 33)
onMediaSourceChanged(@onNull ComponentName componentName)83         void onMediaSourceChanged(@NonNull ComponentName componentName);
84     }
85 
86     /**
87      * Gets the currently active media source for the provided mode
88      *
89      * @param mode the mode (playback or browse) for which the media source is active in.
90      * @return the active media source in the provided mode, will be non-{@code null}.
91      */
92     @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
93     @AddedInOrBefore(majorVersion = 33)
getMediaSource(@ediaSourceMode int mode)94     public @NonNull ComponentName getMediaSource(@MediaSourceMode int mode) {
95         try {
96             return mService.getMediaSource(mode);
97         } catch (RemoteException e) {
98             return handleRemoteExceptionFromCarService(e, null);
99         }
100     }
101 
102     /**
103      * Sets the currently active media source for the provided mode
104      *
105      * @param mode the mode (playback or browse) for which the media source is active in.
106      */
107     @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
108     @AddedInOrBefore(majorVersion = 33)
setMediaSource(@onNull ComponentName componentName, @MediaSourceMode int mode)109     public void setMediaSource(@NonNull ComponentName componentName, @MediaSourceMode int mode) {
110         try {
111             mService.setMediaSource(componentName, mode);
112         } catch (RemoteException e) {
113             handleRemoteExceptionFromCarService(e);
114         }
115     }
116 
117     /**
118      * Register a callback that receives updates to the active media source.
119      *
120      * @param callback the callback to receive active media source updates.
121      * @param mode the mode to receive updates for.
122      */
123     @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
124     @AddedInOrBefore(majorVersion = 33)
addMediaSourceListener(@onNull MediaSourceChangedListener callback, @MediaSourceMode int mode)125     public void addMediaSourceListener(@NonNull MediaSourceChangedListener callback,
126             @MediaSourceMode int mode) {
127         try {
128             ICarMediaSourceListener binderCallback = new ICarMediaSourceListener.Stub() {
129                 @Override
130                 public void onMediaSourceChanged(ComponentName componentName) {
131                     callback.onMediaSourceChanged(componentName);
132                 }
133             };
134             synchronized (mLock) {
135                 mCallbackMap.put(callback, binderCallback);
136             }
137             mService.registerMediaSourceListener(binderCallback, mode);
138         } catch (RemoteException e) {
139             handleRemoteExceptionFromCarService(e);
140         }
141     }
142 
143     /**
144      * Unregister a callback that receives updates to the active media source.
145      *
146      * @param callback the callback to be unregistered.
147      * @param mode the mode that the callback was registered to receive updates for.
148      */
149     @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
150     @AddedInOrBefore(majorVersion = 33)
removeMediaSourceListener(@onNull MediaSourceChangedListener callback, @MediaSourceMode int mode)151     public void removeMediaSourceListener(@NonNull MediaSourceChangedListener callback,
152             @MediaSourceMode int mode) {
153         try {
154             synchronized (mLock) {
155                 ICarMediaSourceListener binderCallback = mCallbackMap.remove(callback);
156                 mService.unregisterMediaSourceListener(binderCallback, mode);
157             }
158         } catch (RemoteException e) {
159             handleRemoteExceptionFromCarService(e);
160         }
161     }
162 
163     /**
164      * Retrieve a list of media sources, ordered by most recently used.
165      *
166      * @param mode the mode (playback or browse) for which to retrieve media sources from.
167      * @return non-{@code null} list of media sources, ordered by most recently used
168      */
169     @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
170     @AddedInOrBefore(majorVersion = 33)
getLastMediaSources(@ediaSourceMode int mode)171     public @NonNull List<ComponentName> getLastMediaSources(@MediaSourceMode int mode) {
172         try {
173             return mService.getLastMediaSources(mode);
174         } catch (RemoteException e) {
175             return handleRemoteExceptionFromCarService(e, null);
176         }
177     }
178 
179     /** @hide */
180     @Override
181     @AddedInOrBefore(majorVersion = 33)
onCarDisconnected()182     public void onCarDisconnected() {
183         synchronized (mLock) {
184             mCallbackMap.clear();
185         }
186     }
187 
188     /**
189      * Returns whether the browse and playback sources can be changed independently.
190      * @return true if the browse and playback sources can be changed independently, false if it
191      * isn't or if the value could not be determined.
192      * @hide
193      */
194     @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
195     @AddedInOrBefore(majorVersion = 33)
isIndependentPlaybackConfig()196     public boolean isIndependentPlaybackConfig() {
197         try {
198             return mService.isIndependentPlaybackConfig();
199         } catch (RemoteException e) {
200             return handleRemoteExceptionFromCarService(e, null);
201         }
202     }
203 
204     /**
205      * Sets whether the browse and playback sources can be changed independently.
206      * @param independent whether the browse and playback sources can be changed independently.
207      * @hide
208      */
209     @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
210     @AddedInOrBefore(majorVersion = 33)
setIndependentPlaybackConfig(boolean independent)211     public void setIndependentPlaybackConfig(boolean independent) {
212         try {
213             mService.setIndependentPlaybackConfig(independent);
214         } catch (RemoteException e) {
215             handleRemoteExceptionFromCarService(e);
216         }
217     }
218 }
219