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