1 /*
2  * Copyright (C) 2014 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.car.media;
18 
19 import android.annotation.SystemApi;
20 import android.media.AudioDevicePort;
21 import android.media.AudioPatch;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import com.android.internal.util.Preconditions;
26 
27 /**
28  * A class to encapsulate the handle for a system level audio patch. This is used
29  * to provide a "safe" way for permitted applications to route automotive audio sources
30  * outside of android.
31  * @hide
32  */
33 @SystemApi
34 public final class CarAudioPatchHandle implements Parcelable {
35 
36     // This is enough information to uniquely identify a patch to the system
37     private final int mHandleId;
38     private final String mSourceAddress;
39     private final String mSinkAddress;
40 
41     /**
42      * Construct a audio patch handle container given the system level handle
43      * NOTE: Assumes (as it true today), that there is exactly one device port in the source
44      * and sink arrays.
45      *
46      * @hide
47      */
CarAudioPatchHandle(AudioPatch patch)48     public CarAudioPatchHandle(AudioPatch patch) {
49         Preconditions.checkArgument(patch.sources().length == 1
50                 && patch.sources()[0].port() instanceof AudioDevicePort,
51                 "Accepts exactly one device port as source");
52         Preconditions.checkArgument(patch.sinks().length == 1
53                 && patch.sinks()[0].port() instanceof AudioDevicePort,
54                 "Accepts exactly one device port as sink");
55 
56         mHandleId = patch.id();
57         mSourceAddress = ((AudioDevicePort) patch.sources()[0].port()).address();
58         mSinkAddress = ((AudioDevicePort) patch.sinks()[0].port()).address();
59     }
60 
61     /**
62      * Returns true if this instance matches the provided AudioPatch object.
63      * This is intended only for use by the CarAudioManager implementation when
64      * communicating with the AudioManager API.
65      *
66      * Effectively only the {@link #mHandleId} is used for comparison,
67      * {@link android.media.AudioSystem#listAudioPatches(java.util.ArrayList, int[])}
68      * does not populate the device type and address properly.
69      *
70      * @hide
71      */
represents(AudioPatch patch)72     public boolean represents(AudioPatch patch) {
73         return patch.id() == mHandleId;
74     }
75 
76     @Override
toString()77     public String toString() {
78         return "Patch (mHandleId=" + mHandleId + "): "
79                 + mSourceAddress + " => " + mSinkAddress;
80     }
81 
82     /**
83      * Given a parcel, populate our data members
84      */
CarAudioPatchHandle(Parcel in)85     private CarAudioPatchHandle(Parcel in) {
86         mHandleId = in.readInt();
87         mSourceAddress = in.readString();
88         mSinkAddress = in.readString();
89     }
90 
91     /**
92      * Serialize our internal data to a parcel
93      */
94     @Override
writeToParcel(Parcel out, int flags)95     public void writeToParcel(Parcel out, int flags) {
96         out.writeInt(mHandleId);
97         out.writeString(mSourceAddress);
98         out.writeString(mSinkAddress);
99     }
100 
101     public static final Parcelable.Creator<CarAudioPatchHandle> CREATOR =
102                 new Parcelable.Creator<CarAudioPatchHandle>() {
103             public CarAudioPatchHandle createFromParcel(Parcel in) {
104                 return new CarAudioPatchHandle(in);
105             }
106 
107             public CarAudioPatchHandle[] newArray(int size) {
108                 return new CarAudioPatchHandle[size];
109             }
110         };
111 
112     @Override
describeContents()113     public int describeContents() {
114         return 0;
115     }
116 }
117