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.media.tv;
18 
19 import static java.lang.annotation.RetentionPolicy.SOURCE;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.SystemApi;
24 import android.hardware.tv.input.V1_0.Constants;
25 import android.media.AudioManager;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 import android.util.Log;
29 
30 import java.lang.annotation.Retention;
31 
32 /**
33  * Simple container for information about TV input hardware.
34  * Not for third-party developers.
35  *
36  * @hide
37  */
38 @SystemApi
39 public final class TvInputHardwareInfo implements Parcelable {
40     static final String TAG = "TvInputHardwareInfo";
41 
42     // Match hardware/libhardware/include/hardware/tv_input.h
43     public static final int TV_INPUT_TYPE_OTHER_HARDWARE = Constants.TV_INPUT_TYPE_OTHER;
44     public static final int TV_INPUT_TYPE_TUNER          = Constants.TV_INPUT_TYPE_TUNER;
45     public static final int TV_INPUT_TYPE_COMPOSITE      = Constants.TV_INPUT_TYPE_COMPOSITE;
46     public static final int TV_INPUT_TYPE_SVIDEO         = Constants.TV_INPUT_TYPE_SVIDEO;
47     public static final int TV_INPUT_TYPE_SCART          = Constants.TV_INPUT_TYPE_SCART;
48     public static final int TV_INPUT_TYPE_COMPONENT      = Constants.TV_INPUT_TYPE_COMPONENT;
49     public static final int TV_INPUT_TYPE_VGA            = Constants.TV_INPUT_TYPE_VGA;
50     public static final int TV_INPUT_TYPE_DVI            = Constants.TV_INPUT_TYPE_DVI;
51     public static final int TV_INPUT_TYPE_HDMI           = Constants.TV_INPUT_TYPE_HDMI;
52     public static final int TV_INPUT_TYPE_DISPLAY_PORT   = Constants.TV_INPUT_TYPE_DISPLAY_PORT;
53 
54     /** @hide */
55     @Retention(SOURCE)
56     @IntDef({CABLE_CONNECTION_STATUS_UNKNOWN, CABLE_CONNECTION_STATUS_CONNECTED,
57         CABLE_CONNECTION_STATUS_DISCONNECTED})
58     public @interface CableConnectionStatus {}
59 
60     // Match hardware/interfaces/tv/input/1.0/types.hal
61     /**
62      * The hardware is unsure about the connection status or does not support cable detection.
63      */
64     public static final int CABLE_CONNECTION_STATUS_UNKNOWN =
65             Constants.CABLE_CONNECTION_STATUS_UNKNOWN;
66 
67     /**
68      * Cable is connected to the hardware.
69      */
70     public static final int CABLE_CONNECTION_STATUS_CONNECTED =
71             Constants.CABLE_CONNECTION_STATUS_CONNECTED;
72 
73     /**
74      * Cable is disconnected to the hardware.
75      */
76     public static final int CABLE_CONNECTION_STATUS_DISCONNECTED =
77             Constants.CABLE_CONNECTION_STATUS_DISCONNECTED;
78 
79     public static final @android.annotation.NonNull Parcelable.Creator<TvInputHardwareInfo> CREATOR =
80             new Parcelable.Creator<TvInputHardwareInfo>() {
81         @Override
82         public TvInputHardwareInfo createFromParcel(Parcel source) {
83             try {
84                 TvInputHardwareInfo info = new TvInputHardwareInfo();
85                 info.readFromParcel(source);
86                 return info;
87             } catch (Exception e) {
88                 Log.e(TAG, "Exception creating TvInputHardwareInfo from parcel", e);
89                 return null;
90             }
91         }
92 
93         @Override
94         public TvInputHardwareInfo[] newArray(int size) {
95             return new TvInputHardwareInfo[size];
96         }
97     };
98 
99     private int mDeviceId;
100     private int mType;
101     private int mAudioType;
102     private String mAudioAddress;
103     private int mHdmiPortId;
104     @CableConnectionStatus
105     private int mCableConnectionStatus;
106 
TvInputHardwareInfo()107     private TvInputHardwareInfo() {
108     }
109 
getDeviceId()110     public int getDeviceId() {
111         return mDeviceId;
112     }
113 
getType()114     public int getType() {
115         return mType;
116     }
117 
getAudioType()118     public int getAudioType() {
119         return mAudioType;
120     }
121 
getAudioAddress()122     public String getAudioAddress() {
123         return mAudioAddress;
124     }
125 
getHdmiPortId()126     public int getHdmiPortId() {
127         if (mType != TV_INPUT_TYPE_HDMI) {
128             throw new IllegalStateException();
129         }
130         return mHdmiPortId;
131     }
132 
133     /**
134      * Gets the cable connection status of the hardware.
135      *
136      * @return {@code CABLE_CONNECTION_STATUS_CONNECTED} if cable is connected.
137      *         {@code CABLE_CONNECTION_STATUS_DISCONNECTED} if cable is disconnected.
138      *         {@code CABLE_CONNECTION_STATUS_UNKNOWN} if the hardware is unsure about the
139      *         connection status or does not support cable detection.
140      */
141     @CableConnectionStatus
getCableConnectionStatus()142     public int getCableConnectionStatus() {
143         return mCableConnectionStatus;
144     }
145 
146     @NonNull
147     @Override
toString()148     public String toString() {
149         StringBuilder b = new StringBuilder(128);
150         b.append("TvInputHardwareInfo {id=").append(mDeviceId);
151         b.append(", type=").append(mType);
152         b.append(", audio_type=").append(mAudioType);
153         b.append(", audio_addr=").append(mAudioAddress);
154         if (mType == TV_INPUT_TYPE_HDMI) {
155             b.append(", hdmi_port=").append(mHdmiPortId);
156         }
157         b.append(", cable_connection_status=").append(mCableConnectionStatus);
158         b.append("}");
159         return b.toString();
160     }
161 
162     // Parcelable
163     @Override
describeContents()164     public int describeContents() {
165         return 0;
166     }
167 
168     @Override
writeToParcel(Parcel dest, int flags)169     public void writeToParcel(Parcel dest, int flags) {
170         dest.writeInt(mDeviceId);
171         dest.writeInt(mType);
172         dest.writeInt(mAudioType);
173         dest.writeString(mAudioAddress);
174         if (mType == TV_INPUT_TYPE_HDMI) {
175             dest.writeInt(mHdmiPortId);
176         }
177         dest.writeInt(mCableConnectionStatus);
178     }
179 
readFromParcel(Parcel source)180     public void readFromParcel(Parcel source) {
181         mDeviceId = source.readInt();
182         mType = source.readInt();
183         mAudioType = source.readInt();
184         mAudioAddress = source.readString();
185         if (mType == TV_INPUT_TYPE_HDMI) {
186             mHdmiPortId = source.readInt();
187         }
188         mCableConnectionStatus = source.readInt();
189     }
190 
191     /** @hide */
toBuilder()192     public Builder toBuilder() {
193         Builder newBuilder = new Builder()
194             .deviceId(mDeviceId)
195             .type(mType)
196             .audioType(mAudioType)
197             .audioAddress(mAudioAddress)
198             .cableConnectionStatus(mCableConnectionStatus);
199         if (mType == TV_INPUT_TYPE_HDMI) {
200             newBuilder.hdmiPortId(mHdmiPortId);
201         }
202         return newBuilder;
203     }
204 
205     public static final class Builder {
206         private Integer mDeviceId = null;
207         private Integer mType = null;
208         private int mAudioType = AudioManager.DEVICE_NONE;
209         private String mAudioAddress = "";
210         private Integer mHdmiPortId = null;
211         private Integer mCableConnectionStatus = CABLE_CONNECTION_STATUS_UNKNOWN;
212 
Builder()213         public Builder() {
214         }
215 
deviceId(int deviceId)216         public Builder deviceId(int deviceId) {
217             mDeviceId = deviceId;
218             return this;
219         }
220 
type(int type)221         public Builder type(int type) {
222             mType = type;
223             return this;
224         }
225 
audioType(int audioType)226         public Builder audioType(int audioType) {
227             mAudioType = audioType;
228             return this;
229         }
230 
audioAddress(String audioAddress)231         public Builder audioAddress(String audioAddress) {
232             mAudioAddress = audioAddress;
233             return this;
234         }
235 
hdmiPortId(int hdmiPortId)236         public Builder hdmiPortId(int hdmiPortId) {
237             mHdmiPortId = hdmiPortId;
238             return this;
239         }
240 
241         /**
242          * Sets cable connection status.
243          */
cableConnectionStatus(@ableConnectionStatus int cableConnectionStatus)244         public Builder cableConnectionStatus(@CableConnectionStatus int cableConnectionStatus) {
245             mCableConnectionStatus = cableConnectionStatus;
246             return this;
247         }
248 
build()249         public TvInputHardwareInfo build() {
250             if (mDeviceId == null || mType == null) {
251                 throw new UnsupportedOperationException();
252             }
253             if ((mType == TV_INPUT_TYPE_HDMI && mHdmiPortId == null) ||
254                     (mType != TV_INPUT_TYPE_HDMI && mHdmiPortId != null)) {
255                 throw new UnsupportedOperationException();
256             }
257 
258             TvInputHardwareInfo info = new TvInputHardwareInfo();
259             info.mDeviceId = mDeviceId;
260             info.mType = mType;
261             info.mAudioType = mAudioType;
262             if (info.mAudioType != AudioManager.DEVICE_NONE) {
263                 info.mAudioAddress = mAudioAddress;
264             }
265             if (mHdmiPortId != null) {
266                 info.mHdmiPortId = mHdmiPortId;
267             }
268             info.mCableConnectionStatus = mCableConnectionStatus;
269             return info;
270         }
271     }
272 }
273