MediaRouteProviderService.java revision 129abf73ce9be1bc172b945263c7975ad1a3006f
1fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown/* 2fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Copyright (C) 2013 The Android Open Source Project 3fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * 4fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * you may not use this file except in compliance with the License. 6fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * You may obtain a copy of the License at 7fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * 8fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * 10fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Unless required by applicable law or agreed to in writing, software 11fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * See the License for the specific language governing permissions and 14fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * limitations under the License. 15fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 16fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 17b507e525a61ed761eecfc2eaaf19af7e8db5dca5Jeff Brownpackage android.support.v7.media; 18fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 19fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.app.Service; 20fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.content.Intent; 21fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.Handler; 22fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.IBinder; 23fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.IBinder.DeathRecipient; 24fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.Bundle; 25fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.DeadObjectException; 26fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.Message; 27fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.Messenger; 28fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.os.RemoteException; 29b507e525a61ed761eecfc2eaaf19af7e8db5dca5Jeff Brownimport android.support.v7.media.MediaRouteProvider.ProviderDescriptor; 30fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.util.Log; 31fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport android.util.SparseArray; 32fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 33fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport java.lang.ref.WeakReference; 34fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownimport java.util.ArrayList; 35fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 36fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown/** 37fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Base class for media route provider services. 38fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * <p> 39fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * To implement your own media route provider service, extend this class and 40fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * override the {@link #onCreateMediaRouteProvider} method to return an 41fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * instance of your {@link MediaRouteProvider}. 42fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </p><p> 43fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Declare your media route provider service in your application manifest 44fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * like this: 45fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </p> 46fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * <pre> 47fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * <service android:name=".MyMediaRouteProviderService" 48fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * android:label="@string/my_media_route_provider_service"> 49fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * <intent-filter> 50fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * <action android:name="android.media.MediaRouteProviderService" /> 51fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </intent-filter> 52fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </service> 53fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </pre> 54fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 55fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brownpublic abstract class MediaRouteProviderService extends Service { 56fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static final String TAG = "MediaRouteProviderService"; 57fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static final boolean DEBUG = true; 58fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 59fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final ArrayList<ClientRecord> mClients = new ArrayList<ClientRecord>(); 60fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final ReceiveHandler mReceiveHandler; 61fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final Messenger mReceiveMessenger; 62fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final PrivateHandler mPrivateHandler; 63fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final ProviderCallback mProviderCallback; 64fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 65fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private MediaRouteProvider mProvider; 66fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 67fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** 68fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * The {@link Intent} that must be declared as handled by the service. 69fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Put this in your manifest. 70fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 71fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public static final String SERVICE_INTERFACE = 72fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown "android.media.MediaRouteProviderService"; 73fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 74fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /* 75fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Messages sent from the client to the service. 76fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * DO NOT RENUMBER THESE! 77fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 78fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 79fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 80fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Register client. 81fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 82fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 83fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : client version 84fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 85fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_REGISTER = 1; 86fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 87fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 88fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Unregister client. 89fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 90fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 91fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 92fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_UNREGISTER = 2; 93fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 94fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 95fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Create route controller. 96fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 97fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 98fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : route controller id 99fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - CLIENT_DATA_ROUTE_ID : route id string 100fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 101fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_CREATE_ROUTE_CONTROLLER = 3; 102fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 103fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 104fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Release route controller. 105fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 106fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 107fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : route controller id 108fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 109fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_RELEASE_ROUTE_CONTROLLER = 4; 110fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 111fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 112fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Select route. 113fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 114fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 115fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : route controller id 116fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 117fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_SELECT_ROUTE = 5; 118fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 119fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 120fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Unselect route. 121fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 122fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 123fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : route controller id 124fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 125fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_UNSELECT_ROUTE = 6; 126fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 127fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 128fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Set route volume. 129fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 130fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 131fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : route controller id 132fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - CLIENT_DATA_VOLUME : volume integer 133fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 134fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_SET_ROUTE_VOLUME = 7; 135fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 136fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 137fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Update route volume. 138fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 139fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 140fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : route controller id 141fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - CLIENT_DATA_VOLUME : volume delta integer 142fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 143fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_UPDATE_ROUTE_VOLUME = 8; 144fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 145fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (client v1) 146fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Route control request. 147fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - replyTo : client messenger 148fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 149fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : route controller id 150fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - obj : media control intent 151fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 152fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_MSG_ROUTE_CONTROL_REQUEST = 9; 153fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 154fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final String CLIENT_DATA_ROUTE_ID = "routeId"; 155fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final String CLIENT_DATA_VOLUME = "volume"; 156fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 157fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /* 158fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Messages sent from the service to the client. 159fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * DO NOT RENUMBER THESE! 160fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 161fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 162fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (service v1) 163fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Generic failure sent in response to any unrecognized or malformed request. 164fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 165fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 166fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int SERVICE_MSG_GENERIC_FAILURE = 0; 167fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 168fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (service v1) 169fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Generic failure sent in response to a successful message. 170fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 171fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 172fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int SERVICE_MSG_GENERIC_SUCCESS = 1; 173fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 174fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (service v1) 175fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Registration succeeded. 176fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 177fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : server version 178fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - obj : route provider descriptor bundle, or null 179fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 180fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int SERVICE_MSG_REGISTERED = 2; 181fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 182fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (service v1) 183fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Route control request result. 184fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : request id 185fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg2 : result code 186fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - obj : result data bundle, or null 187fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 188fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int SERVICE_MSG_CONTROL_RESULT = 3; 189fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 190fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** (service v1) 191fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Route provider descriptor changed. (unsolicited event) 192fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - arg1 : reserved (0) 193fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * - obj : route provider descriptor bundle, or null 194fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 195fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int SERVICE_MSG_DESCRIPTOR_CHANGED = 4; 196fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 197fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /* 198fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Recognized client version numbers. (Reserved for future use.) 199fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * DO NOT RENUMBER THESE! 200fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 201fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 202fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_VERSION_1 = 1; 203fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int CLIENT_VERSION_CURRENT = CLIENT_VERSION_1; 204fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 205fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /* 206fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Recognized server version numbers. (Reserved for future use.) 207fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * DO NOT RENUMBER THESE! 208fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 209fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 210fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int SERVICE_VERSION_1 = 1; 211fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static final int SERVICE_VERSION_CURRENT = SERVICE_VERSION_1; 212fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 213fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /* 214fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Private messages used internally. (Yes, you can renumber these.) 215fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 216fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 217fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static final int PRIVATE_MSG_CLIENT_DIED = 1; 218fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 219fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** 220fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Creates a media route provider service. 221fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 222fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public MediaRouteProviderService() { 223fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mReceiveHandler = new ReceiveHandler(this); 224fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mReceiveMessenger = new Messenger(mReceiveHandler); 225fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mPrivateHandler = new PrivateHandler(); 226fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mProviderCallback = new ProviderCallback(); 227fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 228fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 229fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** 230fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Called by the system when it is time to create the media route provider. 231fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * 232fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * @return The media route provider offered by this service, or null if 233fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * this service has decided not to offer a media route provider. 234fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 235fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public abstract MediaRouteProvider onCreateMediaRouteProvider(); 236fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 237fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** 238fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Gets the media route provider offered by this service. 239fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * 240fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * @return The media route provider offered by this service, or null if 241fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * it has not yet been created. 242fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * 243fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * @see #onCreateMediaRouteProvider() 244fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 245fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public MediaRouteProvider getMediaRouteProvider() { 246fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return mProvider; 247fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 248fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 249fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown @Override 250fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public IBinder onBind(Intent intent) { 251fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (intent.getAction().equals(SERVICE_INTERFACE)) { 252fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (mProvider == null) { 253fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider provider = onCreateMediaRouteProvider(); 254fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (provider != null) { 255fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown String providerPackage = provider.getMetadata().getPackageName(); 256fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (!providerPackage.equals(getPackageName())) { 257fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown throw new IllegalStateException("onCreateMediaRouteProvider() returned " 258fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + "a provider whose package name does not match the package " 259fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + "name of the service. A media route provider service can " 260fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + "only export its own media route providers. " 261fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + "Provider package name: " + providerPackage 262fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ". Service package name: " + getPackageName() + "."); 263fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 264350ba6e4a1b5ec28721a098e50eaf6a508eb28f0Jeff Brown mProvider = provider; 265350ba6e4a1b5ec28721a098e50eaf6a508eb28f0Jeff Brown mProvider.addCallback(mProviderCallback); 266fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 267fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 268fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (mProvider != null) { 269fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return mReceiveMessenger.getBinder(); 270fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 271fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 272fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return null; 273fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 274fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 275fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onRegisterClient(Messenger messenger, int requestId, int version) { 276fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (version >= CLIENT_VERSION_1) { 277fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int index = findClient(messenger); 278fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (index < 0) { 279fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = new ClientRecord(messenger, version); 280fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client.register()) { 281fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mClients.add(client); 282fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 283fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Registered, version=" + version); 284fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 285fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (requestId != 0) { 286fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ProviderDescriptor descriptor = mProvider.getDescriptor(); 287fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendReply(messenger, SERVICE_MSG_REGISTERED, 288fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown requestId, SERVICE_VERSION_CURRENT, 289fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown descriptor != null ? descriptor.asBundle() : null, null); 290fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 291fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 292fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 293fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 294fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 295fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 296fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 297fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 298fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onUnregisterClient(Messenger messenger, int requestId) { 299fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int index = findClient(messenger); 300fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (index >= 0) { 301fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = mClients.remove(index); 302fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 303fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Unregistered"); 304fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 305fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown client.dispose(); 306fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericSuccess(messenger, requestId); 307fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 308fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 309fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 310fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 311fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 312fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private void onBinderDied(Messenger messenger) { 313fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int index = findClient(messenger); 314fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (index >= 0) { 315fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = mClients.remove(index); 316fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 317fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Binder died"); 318fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 319fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown client.dispose(); 320fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 321fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 322fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 323fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onCreateRouteController(Messenger messenger, int requestId, 324fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int controllerId, String routeId) { 325fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = getClient(messenger); 326fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client != null) { 327fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client.createRouteController(routeId, controllerId)) { 328fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 329fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route controller created" 330fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId + ", routeId=" + routeId); 331fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 332fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericSuccess(messenger, requestId); 333fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 334fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 335fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 336fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 337fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 338fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 339fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onReleaseRouteController(Messenger messenger, int requestId, 340fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int controllerId) { 341fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = getClient(messenger); 342fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client != null) { 343fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client.releaseRouteController(controllerId)) { 344fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 345fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route controller released" 346fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId); 347fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 348fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericSuccess(messenger, requestId); 349fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 350fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 351fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 352fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 353fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 354fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 355fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onSelectRoute(Messenger messenger, int requestId, 356fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int controllerId) { 357fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = getClient(messenger); 358fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client != null) { 359fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider.RouteController controller = 360fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown client.getRouteController(controllerId); 361fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (controller != null) { 362129abf73ce9be1bc172b945263c7975ad1a3006fJeff Brown controller.onSelect(); 363fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 364fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route selected" 365fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId); 366fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 367fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericSuccess(messenger, requestId); 368fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 369fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 370fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 371fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 372fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 373fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 374fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onUnselectRoute(Messenger messenger, int requestId, 375fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int controllerId) { 376fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = getClient(messenger); 377fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client != null) { 378fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider.RouteController controller = 379fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown client.getRouteController(controllerId); 380fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (controller != null) { 381129abf73ce9be1bc172b945263c7975ad1a3006fJeff Brown controller.onUnselect(); 382fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 383fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route unselected" 384fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId); 385fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 386fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericSuccess(messenger, requestId); 387fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 388fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 389fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 390fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 391fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 392fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 393fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onSetRouteVolume(Messenger messenger, int requestId, 394fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int controllerId, int volume) { 395fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = getClient(messenger); 396fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client != null) { 397fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider.RouteController controller = 398fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown client.getRouteController(controllerId); 399fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (controller != null) { 400129abf73ce9be1bc172b945263c7975ad1a3006fJeff Brown controller.onSetVolume(volume); 401fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 402fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route volume changed" 403fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId + ", volume=" + volume); 404fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 405fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericSuccess(messenger, requestId); 406fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 407fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 408fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 409fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 410fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 411fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 412fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onUpdateRouteVolume(Messenger messenger, int requestId, 413fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int controllerId, int delta) { 414fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = getClient(messenger); 415fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client != null) { 416fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider.RouteController controller = 417fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown client.getRouteController(controllerId); 418fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (controller != null) { 419129abf73ce9be1bc172b945263c7975ad1a3006fJeff Brown controller.onUpdateVolume(delta); 420fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 421fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route volume updated" 422fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId + ", delta=" + delta); 423fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 424fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericSuccess(messenger, requestId); 425fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 426fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 427fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 428fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 429fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 430fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 431fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean onRouteControlRequest(final Messenger messenger, final int requestId, 432fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final int controllerId, final Intent intent) { 433fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final ClientRecord client = getClient(messenger); 434fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client != null) { 435fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider.RouteController controller = 436fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown client.getRouteController(controllerId); 437fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (controller != null) { 438fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouter.ControlRequestCallback callback = null; 439fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (requestId != 0) { 440fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown callback = new MediaRouter.ControlRequestCallback() { 441fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown @Override 442fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public void onResult(int result, Bundle data) { 443fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 444fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route control request finished" 445fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId 446fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", intent=" + intent 447fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", result=" + result + ", data=" + data); 448fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 449fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (findClient(messenger) >= 0) { 450fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendReply(messenger, SERVICE_MSG_CONTROL_RESULT, 451fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown requestId, result, data, null); 452fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 453fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 454fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown }; 455fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 456129abf73ce9be1bc172b945263c7975ad1a3006fJeff Brown if (controller.onControlRequest(intent, callback)) { 457fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 458fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Route control request delivered" 459fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", controllerId=" + controllerId + ", intent=" + intent); 460fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 461fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 462fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 463fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 464fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 465fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 466fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 467fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 468fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private void sendDescriptorChanged(MediaRouteProvider.ProviderDescriptor descriptor) { 469fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Bundle descriptorBundle = descriptor != null ? descriptor.asBundle() : null; 470fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final int count = mClients.size(); 471fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown for (int i = 0; i < count; i++) { 472fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = mClients.get(i); 473fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendReply(client.mMessenger, SERVICE_MSG_DESCRIPTOR_CHANGED, 0, 0, 474fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown descriptorBundle, null); 475fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 476fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, client + ": Sent descriptor change event, descriptor=" + descriptor); 477fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 478fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 479fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 480fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 481fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private ClientRecord getClient(Messenger messenger) { 482fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int index = findClient(messenger); 483fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return index >= 0 ? mClients.get(index) : null; 484fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 485fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 486fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private int findClient(Messenger messenger) { 487fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final int count = mClients.size(); 488fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown for (int i = 0; i < count; i++) { 489fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ClientRecord client = mClients.get(i); 490fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (client.hasMessenger(messenger)) { 491fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return i; 492fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 493fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 494fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return -1; 495fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 496fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 497fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static void sendGenericFailure(Messenger messenger, int requestId) { 498fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (requestId != 0) { 499fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendReply(messenger, SERVICE_MSG_GENERIC_FAILURE, requestId, 0, null, null); 500fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 501fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 502fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 503fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static void sendGenericSuccess(Messenger messenger, int requestId) { 504fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (requestId != 0) { 505fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendReply(messenger, SERVICE_MSG_GENERIC_SUCCESS, requestId, 0, null, null); 506fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 507fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 508fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 509fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static void sendReply(Messenger messenger, int what, 510fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int requestId, int arg, Object obj, Bundle data) { 511fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Message msg = Message.obtain(); 512fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown msg.what = what; 513fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown msg.arg1 = requestId; 514fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown msg.arg2 = arg; 515fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown msg.obj = obj; 516fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown msg.setData(data); 517fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown try { 518fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown messenger.send(msg); 519fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } catch (DeadObjectException ex) { 520fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown // The client died. 521fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } catch (RemoteException ex) { 522fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.e(TAG, "Could not send message to " + getClientId(messenger), ex); 523fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 524fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 525fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 526fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static String getClientId(Messenger messenger) { 527fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return "Client connection " + messenger.getBinder().toString(); 528fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 529fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 530fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** 531fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Returns true if the messenger object is valid. 532fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * <p> 533fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * The messenger contructor and unparceling code does not check whether the 534fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * provided IBinder is a valid IMessenger object. As a result, it's possible 535fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * for a peer to send an invalid IBinder that will result in crashes downstream. 536fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * This method checks that the messenger is in a valid state. 537fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </p> 538fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 539fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown static boolean isValidRemoteMessenger(Messenger messenger) { 540fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown try { 541fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return messenger != null && messenger.getBinder() != null; 542fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } catch (NullPointerException ex) { 543fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown // If the messenger was constructed with a binder interface other than 544fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown // IMessenger then the call to getBinder() will crash with an NPE. 545fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 546fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 547fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 548fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 549fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final class PrivateHandler extends Handler { 550fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown @Override 551fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public void handleMessage(Message msg) { 552fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown switch (msg.what) { 553fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case PRIVATE_MSG_CLIENT_DIED: 554fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown onBinderDied((Messenger)msg.obj); 555fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown break; 556fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 557fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 558fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 559fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 560fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final class ProviderCallback extends MediaRouteProvider.Callback { 561fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown @Override 562fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public void onDescriptorChanged(MediaRouteProvider provider, 563fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown ProviderDescriptor descriptor) { 564fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendDescriptorChanged(descriptor); 565fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 566fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 567fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 568fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final class ClientRecord implements DeathRecipient { 569fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public final Messenger mMessenger; 570fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public final int mVersion; 571fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 572fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final SparseArray<MediaRouteProvider.RouteController> mControllers = 573fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown new SparseArray<MediaRouteProvider.RouteController>(); 574fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 575fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public ClientRecord(Messenger messenger, int version) { 576fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mMessenger = messenger; 577fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mVersion = version; 578fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 579fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 580fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public boolean register() { 581fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown try { 582fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mMessenger.getBinder().linkToDeath(this, 0); 583fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 584fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } catch (RemoteException ex) { 585fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown binderDied(); 586fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 587fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 588fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 589fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 590fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public void dispose() { 591fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int count = mControllers.size(); 592fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown for (int i = 0; i < count; i++) { 593129abf73ce9be1bc172b945263c7975ad1a3006fJeff Brown mControllers.valueAt(i).onRelease(); 594fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 595fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mControllers.clear(); 596fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 597fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mMessenger.getBinder().unlinkToDeath(this, 0); 598fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 599fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 600fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public boolean hasMessenger(Messenger other) { 601fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return mMessenger.getBinder() == other.getBinder(); 602fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 603fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 604fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public boolean createRouteController(String routeId, int controllerId) { 605fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (mControllers.indexOfKey(controllerId) < 0) { 606fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider.RouteController controller = 607fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mProvider.onCreateRouteController(routeId); 608fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mControllers.put(controllerId, controller); 609fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 610fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 611fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 612fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 613fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 614fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public boolean releaseRouteController(int controllerId) { 615fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProvider.RouteController controller = mControllers.get(controllerId); 616fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (controller != null) { 617fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mControllers.remove(controllerId); 618129abf73ce9be1bc172b945263c7975ad1a3006fJeff Brown controller.onRelease(); 619fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return true; 620fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 621fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 622fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 623fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 624fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public MediaRouteProvider.RouteController getRouteController(int controllerId) { 625fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return mControllers.get(controllerId); 626fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 627fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 628fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown @Override 629fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public void binderDied() { 630fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mPrivateHandler.obtainMessage(PRIVATE_MSG_CLIENT_DIED, mMessenger).sendToTarget(); 631fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 632fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 633fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown @Override 634fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public String toString() { 635fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return getClientId(mMessenger); 636fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 637fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 638fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 639fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown /** 640fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * Handler that receives messages from clients. 641fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * <p> 642fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * This inner class is static and only retains a weak reference to the service 643fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * to prevent the service from being leaked in case one of the clients is holding an 644fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * active reference to the server's messenger. 645fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </p><p> 646fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * This handler should not be used to handle any messages other than those 647fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * that come from the client. 648fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown * </p> 649fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown */ 650fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private static final class ReceiveHandler extends Handler { 651fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private final WeakReference<MediaRouteProviderService> mServiceRef; 652fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 653fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public ReceiveHandler(MediaRouteProviderService service) { 654fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown mServiceRef = new WeakReference<MediaRouteProviderService>(service); 655fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 656fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 657fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown @Override 658fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown public void handleMessage(Message msg) { 659fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final Messenger messenger = msg.replyTo; 660fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (isValidRemoteMessenger(messenger)) { 661fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final int what = msg.what; 662fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final int requestId = msg.arg1; 663fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final int arg = msg.arg2; 664fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final Object obj = msg.obj; 665fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown final Bundle data = msg.peekData(); 666fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (!processMessage(what, messenger, requestId, arg, obj, data)) { 667fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 668fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, getClientId(messenger) + ": Message failed, what=" + what 669fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", requestId=" + requestId + ", arg=" + arg 670fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown + ", obj=" + obj + ", data=" + data); 671fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 672fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown sendGenericFailure(messenger, requestId); 673fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 674fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } else { 675fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (DEBUG) { 676fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Log.d(TAG, "Ignoring message without valid reply messenger."); 677fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 678fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 679fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 680fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 681fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown private boolean processMessage(int what, 682fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown Messenger messenger, int requestId, int arg, Object obj, Bundle data) { 683fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown MediaRouteProviderService service = mServiceRef.get(); 684fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (service != null) { 685fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown switch (what) { 686fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_REGISTER: 687fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onRegisterClient(messenger, requestId, arg); 688fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 689fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_UNREGISTER: 690fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onUnregisterClient(messenger, requestId); 691fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 692fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_CREATE_ROUTE_CONTROLLER: { 693fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown String routeId = data.getString(CLIENT_DATA_ROUTE_ID); 694fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (routeId != null) { 695fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onCreateRouteController( 696fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown messenger, requestId, arg, routeId); 697fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 698fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown break; 699fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 700fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 701fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_RELEASE_ROUTE_CONTROLLER: 702fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onReleaseRouteController(messenger, requestId, arg); 703fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 704fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_SELECT_ROUTE: 705fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onSelectRoute(messenger, requestId, arg); 706fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 707fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_UNSELECT_ROUTE: 708fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onUnselectRoute(messenger, requestId, arg); 709fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 710fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_SET_ROUTE_VOLUME: { 711fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int volume = data.getInt(CLIENT_DATA_VOLUME, -1); 712fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (volume >= 0) { 713fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onSetRouteVolume( 714fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown messenger, requestId, arg, volume); 715fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 716fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown break; 717fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 718fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 719fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_UPDATE_ROUTE_VOLUME: { 720fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown int delta = data.getInt(CLIENT_DATA_VOLUME, 0); 721fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (delta != 0) { 722fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onUpdateRouteVolume( 723fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown messenger, requestId, arg, delta); 724fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 725fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown break; 726fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 727fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown 728fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown case CLIENT_MSG_ROUTE_CONTROL_REQUEST: 729fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown if (obj instanceof Intent) { 730fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return service.onRouteControlRequest( 731fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown messenger, requestId, arg, (Intent)obj); 732fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 733fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown break; 734fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 735fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 736fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown return false; 737fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 738fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown } 739fa326a4649d9d0e8113e315f6c8251fe686abce4Jeff Brown} 740