1 /* 2 * Copyright 2018 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 android.media; 18 19 import android.annotation.NonNull; 20 import android.os.Binder; 21 import android.os.Bundle; 22 import android.os.IBinder; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.os.RemoteException; 26 import android.os.ResultReceiver; 27 import android.util.Log; 28 29 import java.util.Objects; 30 31 /** 32 * Handles incoming commands from {@link MediaController2} to {@link MediaSession2}. 33 * @hide 34 */ 35 // @SystemApi 36 public final class Session2Link implements Parcelable { 37 private static final String TAG = "Session2Link"; 38 private static final boolean DEBUG = MediaSession2.DEBUG; 39 40 public static final @android.annotation.NonNull Parcelable.Creator<Session2Link> CREATOR = 41 new Parcelable.Creator<Session2Link>() { 42 @Override 43 public Session2Link createFromParcel(Parcel in) { 44 return new Session2Link(in); 45 } 46 47 @Override 48 public Session2Link[] newArray(int size) { 49 return new Session2Link[size]; 50 } 51 }; 52 53 private final MediaSession2 mSession; 54 private final IMediaSession2 mISession; 55 Session2Link(MediaSession2 session)56 public Session2Link(MediaSession2 session) { 57 mSession = session; 58 mISession = new Session2Stub(); 59 } 60 Session2Link(Parcel in)61 Session2Link(Parcel in) { 62 mSession = null; 63 mISession = IMediaSession2.Stub.asInterface(in.readStrongBinder()); 64 } 65 66 @Override describeContents()67 public int describeContents() { 68 return 0; 69 } 70 71 @Override writeToParcel(Parcel dest, int flags)72 public void writeToParcel(Parcel dest, int flags) { 73 dest.writeStrongBinder(mISession.asBinder()); 74 } 75 76 @Override hashCode()77 public int hashCode() { 78 return mISession.asBinder().hashCode(); 79 } 80 81 @Override equals(Object obj)82 public boolean equals(Object obj) { 83 if (!(obj instanceof Session2Link)) { 84 return false; 85 } 86 Session2Link other = (Session2Link) obj; 87 return Objects.equals(mISession.asBinder(), other.mISession.asBinder()); 88 } 89 90 /** Link to death with mISession */ linkToDeath(@onNull IBinder.DeathRecipient recipient, int flags)91 public void linkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) { 92 if (mISession != null) { 93 try { 94 mISession.asBinder().linkToDeath(recipient, flags); 95 } catch (RemoteException e) { 96 if (DEBUG) { 97 Log.d(TAG, "Session died too early.", e); 98 } 99 } 100 } 101 } 102 103 /** Unlink to death with mISession */ unlinkToDeath(@onNull IBinder.DeathRecipient recipient, int flags)104 public boolean unlinkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) { 105 if (mISession != null) { 106 return mISession.asBinder().unlinkToDeath(recipient, flags); 107 } 108 return true; 109 } 110 111 /** Interface method for IMediaSession2.connect */ connect(final Controller2Link caller, int seq, Bundle connectionRequest)112 public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) { 113 try { 114 mISession.connect(caller, seq, connectionRequest); 115 } catch (RemoteException e) { 116 throw new RuntimeException(e); 117 } 118 } 119 120 /** Interface method for IMediaSession2.disconnect */ disconnect(final Controller2Link caller, int seq)121 public void disconnect(final Controller2Link caller, int seq) { 122 try { 123 mISession.disconnect(caller, seq); 124 } catch (RemoteException e) { 125 throw new RuntimeException(e); 126 } 127 } 128 129 /** Interface method for IMediaSession2.sendSessionCommand */ sendSessionCommand(final Controller2Link caller, final int seq, final Session2Command command, final Bundle args, ResultReceiver resultReceiver)130 public void sendSessionCommand(final Controller2Link caller, final int seq, 131 final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { 132 try { 133 mISession.sendSessionCommand(caller, seq, command, args, resultReceiver); 134 } catch (RemoteException e) { 135 throw new RuntimeException(e); 136 } 137 } 138 139 /** Interface method for IMediaSession2.sendSessionCommand */ cancelSessionCommand(final Controller2Link caller, final int seq)140 public void cancelSessionCommand(final Controller2Link caller, final int seq) { 141 try { 142 mISession.cancelSessionCommand(caller, seq); 143 } catch (RemoteException e) { 144 throw new RuntimeException(e); 145 } 146 } 147 148 /** Stub implementation for IMediaSession2.connect */ onConnect(final Controller2Link caller, int pid, int uid, int seq, Bundle connectionRequest)149 public void onConnect(final Controller2Link caller, int pid, int uid, int seq, 150 Bundle connectionRequest) { 151 mSession.onConnect(caller, pid, uid, seq, connectionRequest); 152 } 153 154 /** Stub implementation for IMediaSession2.disconnect */ onDisconnect(final Controller2Link caller, int seq)155 public void onDisconnect(final Controller2Link caller, int seq) { 156 mSession.onDisconnect(caller, seq); 157 } 158 159 /** Stub implementation for IMediaSession2.sendSessionCommand */ onSessionCommand(final Controller2Link caller, final int seq, final Session2Command command, final Bundle args, ResultReceiver resultReceiver)160 public void onSessionCommand(final Controller2Link caller, final int seq, 161 final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { 162 mSession.onSessionCommand(caller, seq, command, args, resultReceiver); 163 } 164 165 /** Stub implementation for IMediaSession2.cancelSessionCommand */ onCancelCommand(final Controller2Link caller, final int seq)166 public void onCancelCommand(final Controller2Link caller, final int seq) { 167 mSession.onCancelCommand(caller, seq); 168 } 169 170 private class Session2Stub extends IMediaSession2.Stub { 171 @Override connect(final Controller2Link caller, int seq, Bundle connectionRequest)172 public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) { 173 if (caller == null || connectionRequest == null) { 174 return; 175 } 176 final int pid = Binder.getCallingPid(); 177 final int uid = Binder.getCallingUid(); 178 final long token = Binder.clearCallingIdentity(); 179 try { 180 Session2Link.this.onConnect(caller, pid, uid, seq, connectionRequest); 181 } finally { 182 Binder.restoreCallingIdentity(token); 183 } 184 } 185 186 @Override disconnect(final Controller2Link caller, int seq)187 public void disconnect(final Controller2Link caller, int seq) { 188 if (caller == null) { 189 return; 190 } 191 final long token = Binder.clearCallingIdentity(); 192 try { 193 Session2Link.this.onDisconnect(caller, seq); 194 } finally { 195 Binder.restoreCallingIdentity(token); 196 } 197 } 198 199 @Override sendSessionCommand(final Controller2Link caller, final int seq, final Session2Command command, final Bundle args, ResultReceiver resultReceiver)200 public void sendSessionCommand(final Controller2Link caller, final int seq, 201 final Session2Command command, final Bundle args, ResultReceiver resultReceiver) { 202 if (caller == null) { 203 return; 204 } 205 final long token = Binder.clearCallingIdentity(); 206 try { 207 Session2Link.this.onSessionCommand(caller, seq, command, args, resultReceiver); 208 } finally { 209 Binder.restoreCallingIdentity(token); 210 } 211 } 212 213 @Override cancelSessionCommand(final Controller2Link caller, final int seq)214 public void cancelSessionCommand(final Controller2Link caller, final int seq) { 215 if (caller == null) { 216 return; 217 } 218 final long token = Binder.clearCallingIdentity(); 219 try { 220 Session2Link.this.onCancelCommand(caller, seq); 221 } finally { 222 Binder.restoreCallingIdentity(token); 223 } 224 } 225 } 226 } 227