13957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo/* 23957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Copyright (C) 2014 The Android Open Source Project 33957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 43957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Licensed under the Apache License, Version 2.0 (the "License"); 53957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * you may not use this file except in compliance with the License. 63957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * You may obtain a copy of the License at 73957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 83957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * http://www.apache.org/licenses/LICENSE-2.0 93957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 103957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Unless required by applicable law or agreed to in writing, software 113957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * distributed under the License is distributed on an "AS IS" BASIS, 123957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * See the License for the specific language governing permissions and 143957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * limitations under the License. 153957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 163957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 17d5cc4a281e7ce29d1e8687ff3394b57a3a549260Jae Seopackage android.media.tv; 183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 19a759b111a1c9cb00284038f8a1554bf29709b952Jae Seoimport android.annotation.SystemApi; 209a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Choimport android.graphics.Rect; 213957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.net.Uri; 22832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Choimport android.os.Bundle; 233957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.os.Handler; 243957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.os.IBinder; 256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.os.Looper; 266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.os.Message; 273957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.os.RemoteException; 28969167dc05a6485a32d160895871cff46fd81884Wonsik Kimimport android.util.ArrayMap; 293957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.util.Log; 306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.util.Pools.Pool; 316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.util.Pools.SimplePool; 323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.util.SparseArray; 336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.view.InputChannel; 346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.view.InputEvent; 356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.view.InputEventSender; 36d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kimimport android.view.KeyEvent; 373957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.view.Surface; 389a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Choimport android.view.View; 393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 403957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.ArrayList; 413957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.Iterator; 42969167dc05a6485a32d160895871cff46fd81884Wonsik Kimimport java.util.LinkedList; 433957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.List; 443957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.Map; 453957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 463957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo/** 473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Central system API to the overall TV input framework (TIF) architecture, which arbitrates 483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * interaction between applications and the selected TV inputs. 493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seopublic final class TvInputManager { 513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private static final String TAG = "TvInputManager"; 523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 536057102dbb746593a7d59cf377c969b62e38c664Jae Seo static final int VIDEO_UNAVAILABLE_REASON_START = 0; 546057102dbb746593a7d59cf377c969b62e38c664Jae Seo static final int VIDEO_UNAVAILABLE_REASON_END = 3; 556057102dbb746593a7d59cf377c969b62e38c664Jae Seo 569b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 579b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * A generic reason. Video is not available due to an unspecified error. 589b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 596057102dbb746593a7d59cf377c969b62e38c664Jae Seo public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = VIDEO_UNAVAILABLE_REASON_START; 609b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 616e62a1508cb7a5efcdde2ae9e51672fea4296dcaJae Seo * Video is not available because the TV input is in the middle of tuning to a new channel. 629b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 636e62a1508cb7a5efcdde2ae9e51672fea4296dcaJae Seo public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1; 649b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 659b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * Video is not available due to the weak TV signal. 669b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 679b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2; 689b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 699b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * Video is not available because the TV input stopped the playback temporarily to buffer more 709b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * data. 719b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 726057102dbb746593a7d59cf377c969b62e38c664Jae Seo public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = VIDEO_UNAVAILABLE_REASON_END; 739b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 74969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 75993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang * The TV input is in unknown state. 76993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang * <p> 77993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang * State for denoting unknown TV input state. The typical use case is when a requested TV 78993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang * input is removed from the device or it is not registered. Used in 79993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang * {@code ITvInputManager.getTvInputState()}. 80993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang * </p> 81993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang * @hide 82993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang */ 83993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang public static final int INPUT_STATE_UNKNOWN = -1; 84993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang 85993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang /** 86969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * The TV input is connected. 87969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <p> 88969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * State for {@link #getInputState} and {@link 892778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * TvInputManager.TvInputCallback#onInputStateChanged}. 90969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </p> 91969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 92969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_CONNECTED = 0; 93969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 94969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * The TV input is connected but in standby mode. It would take a while until it becomes 95969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * fully ready. 96969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <p> 97969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * State for {@link #getInputState} and {@link 982778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * TvInputManager.TvInputCallback#onInputStateChanged}. 99969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </p> 100969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 101969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_CONNECTED_STANDBY = 1; 102969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 103969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * The TV input is disconnected. 104969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <p> 105969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * State for {@link #getInputState} and {@link 1062778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * TvInputManager.TvInputCallback#onInputStateChanged}. 107969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </p> 108969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 109969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_DISCONNECTED = 2; 110969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 111783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 112783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Broadcast intent action when the user blocked content ratings change. For use with the 113783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * {@link #isRatingBlocked}. 114783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 115783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public static final String ACTION_BLOCKED_RATINGS_CHANGED = 1162778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.BLOCKED_RATINGS_CHANGED"; 117783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 118783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 119783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Broadcast intent action when the parental controls enabled state changes. For use with the 120783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * {@link #isParentalControlsEnabled}. 121783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 122783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public static final String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = 1232778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED"; 1249c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo 1259c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo /** 1269c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Broadcast intent action used to query available content rating systems. 1279c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <p> 1289c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * The TV input manager service locates available content rating systems by querying broadcast 1299c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * receivers that are registered for this action. An application can offer additional content 1309c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * rating systems to the user by declaring a suitable broadcast receiver in its manifest. 1319c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </p><p> 1329c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Here is an example broadcast receiver declaration that an application might include in its 1339c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * AndroidManifest.xml to advertise custom content rating systems. The meta-data specifies a 1349c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * resource that contains a description of each content rating system that is provided by the 1359c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * application. 1369c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <p><pre class="prettyprint"> 1379c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * {@literal 1389c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <receiver android:name=".TvInputReceiver"> 1399c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <intent-filter> 1409c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <action android:name= 1414e389e557efb7806b73d2059d46e2809c1a9f83dSungsoo Lim * "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS" /> 1429c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </intent-filter> 1439c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <meta-data 1444e389e557efb7806b73d2059d46e2809c1a9f83dSungsoo Lim * android:name="android.media.tv.metadata.CONTENT_RATING_SYSTEMS" 1459c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * android:resource="@xml/tv_content_rating_systems" /> 1469c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </receiver>}</pre></p> 1479c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * In the above example, the <code>@xml/tv_content_rating_systems</code> resource refers to an 1489c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * XML resource whose root element is <code><rating-system-definitions></code> that 1499c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * contains zero or more <code><rating-system-definition></code> elements. Each <code> 1509c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <rating-system-definition></code> element specifies the ratings, sub-ratings and rating 1519c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * orders of a particular content rating system. 1529c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </p> 1539c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * 1549c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * @see TvContentRating 1559c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo */ 1569c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public static final String ACTION_QUERY_CONTENT_RATING_SYSTEMS = 1572778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS"; 1589c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo 1599c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo /** 1609c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Content rating systems metadata associated with {@link #ACTION_QUERY_CONTENT_RATING_SYSTEMS}. 1619c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <p> 1629c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Specifies the resource ID of an XML resource that describes the content rating systems that 1639c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * are provided by the application. 1649c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </p> 1659c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo */ 1669c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public static final String META_DATA_CONTENT_RATING_SYSTEMS = 1672778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.metadata.CONTENT_RATING_SYSTEMS"; 168783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputManager mService; 1703957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 171969167dc05a6485a32d160895871cff46fd81884Wonsik Kim private final Object mLock = new Object(); 172969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 1736320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mLock") 1742778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private final List<TvInputCallbackRecord> mCallbackRecords = 1752778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo new LinkedList<TvInputCallbackRecord>(); 176969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 177969167dc05a6485a32d160895871cff46fd81884Wonsik Kim // A mapping from TV input ID to the state of corresponding input. 1786320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mLock") 179969167dc05a6485a32d160895871cff46fd81884Wonsik Kim private final Map<String, Integer> mStateMap = new ArrayMap<String, Integer>(); 1803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1812b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim // A mapping from the sequence number of a session to its SessionCallbackRecord. 1822b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap = 1832b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim new SparseArray<SessionCallbackRecord>(); 1843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1853957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo // A sequence number for the next session to be created. Should be protected by a lock 1862b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim // {@code mSessionCallbackRecordMap}. 1873957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private int mNextSeq; 1883957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1893957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputClient mClient; 1903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1912778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private final ITvInputManagerCallback mManagerCallback; 192969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 1933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final int mUserId; 1943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1953957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1963957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Interface used to receive the created session. 197b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 1983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 19915bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 2002b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public abstract static class SessionCallback { 2013957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 2023957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * This is called after {@link TvInputManager#createSession} has been processed. 2033957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 2043957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param session A {@link TvInputManager.Session} instance created. This can be 2053957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * {@code null} if the creation request failed. 2063957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 2072b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionCreated(Session session) { 2082b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 2092b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 2102b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim /** 2112b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * This is called when {@link TvInputManager.Session} is released. 2122b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * This typically happens when the process hosting the session has crashed or been killed. 2132b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * 2142b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * @param session A {@link TvInputManager.Session} instance released. 2152b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim */ 2162b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionReleased(Session session) { 2172b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 218832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 219832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho /** 2201f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * This is called when the channel of this session is changed by the underlying TV input 2216320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * without any {@link TvInputManager.Session#tune(Uri)} request. 222a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang * 223d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2241f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * @param channelUri The URI of a channel. 225a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang */ 2261f213914c45c23c653f721690da2ce0718e63139Dongwon Kang public void onChannelRetuned(Session session, Uri channelUri) { 227832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 228832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 229832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho /** 2301f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * This is called when the track information of the session has been changed. 231b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang * 232d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2331f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * @param tracks A list which includes track information. 234b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang */ 23510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTracksChanged(Session session, List<TvTrackInfo> tracks) { 236b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 237b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 238b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang /** 23910d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * This is called when a track for a given type is selected. 2409b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * 2416320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 24210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the selected track. The type can be 24310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or 24410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_SUBTITLE}. 24510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param trackId The ID of the selected track. When {@code null} the currently selected 24610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * track for a given type should be unselected. 247d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo */ 24810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTrackSelected(Session session, int type, String trackId) { 249d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 250d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 251d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo /** 2526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * This is invoked when the video size has been changed. It is also called when the first 2536320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * time video size information becomes available after the session is tuned to a specific 2546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * channel. 2556320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * 2566320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2576320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param width The width of the video. 2586320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param height The height of the video. 2596320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 2606320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo public void onVideoSizeChanged(Session session, int width, int height) { 2616320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 2626320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 2636320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 264d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * This is called when the video is available, so the TV input starts the playback. 265d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * 266d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2679b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 2689b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoAvailable(Session session) { 2699b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 2709b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 2719b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 2729b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * This is called when the video is not available, so the TV input stops the playback. 2739b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * 2749b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback 2759b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * @param reason The reason why the TV input stopped the playback: 2769b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <ul> 2779b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN} 2786e62a1508cb7a5efcdde2ae9e51672fea4296dcaJae Seo * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING} 2799b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL} 2809b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING} 2819b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * </ul> 2829b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 2839b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoUnavailable(Session session, int reason) { 2849b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 2859b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 2869b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 287bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * This is called when the current program content turns out to be allowed to watch since 288bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * its content rating is not blocked by parental controls. 289bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * 290bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback 291bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo */ 292bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void onContentAllowed(Session session) { 293bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 294bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 295bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo /** 296bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * This is called when the current program content turns out to be not allowed to watch 297bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * since its content rating is blocked by parental controls. 2986057102dbb746593a7d59cf377c969b62e38c664Jae Seo * 2996057102dbb746593a7d59cf377c969b62e38c664Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback 3006057102dbb746593a7d59cf377c969b62e38c664Jae Seo * @param rating The content ration of the blocked program. 3016057102dbb746593a7d59cf377c969b62e38c664Jae Seo */ 3026057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void onContentBlocked(Session session, TvContentRating rating) { 3036057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 3046057102dbb746593a7d59cf377c969b62e38c664Jae Seo 3056057102dbb746593a7d59cf377c969b62e38c664Jae Seo /** 3065b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * This is called when {@link TvInputService.Session#layoutSurface} is called to change the 3075b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * layout of surface. 308ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho * 309ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho * @param session A {@link TvInputManager.Session} associated with this callback 3105b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param left Left position. 3115b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param top Top position. 3125b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param right Right position. 3135b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param bottom Bottom position. 314ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho * @hide 315ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho */ 316ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @SystemApi 317ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void onLayoutSurface(Session session, int left, int top, int right, int bottom) { 318ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 319ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 320ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho /** 321832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * This is called when a custom event has been sent from this session. 322832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * 323832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param session A {@link TvInputManager.Session} associated with this callback 324832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param eventType The type of the event. 325832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param eventArgs Optional arguments of the event. 326832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @hide 327832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho */ 32815bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 329832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void onSessionEvent(Session session, String eventType, Bundle eventArgs) { 330832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 3313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 3323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3332b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private static final class SessionCallbackRecord { 3342b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SessionCallback mSessionCallback; 3353957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final Handler mHandler; 3362b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private Session mSession; 3373957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3386320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo SessionCallbackRecord(SessionCallback sessionCallback, 3393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Handler handler) { 3402b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback = sessionCallback; 3413957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler = handler; 3423957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 3433957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3446320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionCreated(final Session session) { 3452b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSession = session; 3463957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler.post(new Runnable() { 3473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 3483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void run() { 3492b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback.onSessionCreated(session); 3502b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 3512b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim }); 3522b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 3532b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 3546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionReleased() { 3552b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mHandler.post(new Runnable() { 3562b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim @Override 3572b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void run() { 3582b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback.onSessionReleased(mSession); 3593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 3603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }); 3613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 362832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 3636320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postChannelRetuned(final Uri channelUri) { 364832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mHandler.post(new Runnable() { 365832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 366832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void run() { 3671f213914c45c23c653f721690da2ce0718e63139Dongwon Kang mSessionCallback.onChannelRetuned(mSession, channelUri); 368832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 369832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho }); 370832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 371832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 3726320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postTracksChanged(final List<TvTrackInfo> tracks) { 373b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang mHandler.post(new Runnable() { 374b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang @Override 375b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang public void run() { 37610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mSessionCallback.onTracksChanged(mSession, tracks); 377b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 378b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang }); 379b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 380b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 3816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postTrackSelected(final int type, final String trackId) { 382d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo mHandler.post(new Runnable() { 383d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo @Override 384d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo public void run() { 38510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mSessionCallback.onTrackSelected(mSession, type, trackId); 386d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 387d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo }); 388d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 389d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 3906320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoSizeChanged(final int width, final int height) { 3916320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mHandler.post(new Runnable() { 3926320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo @Override 3936320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo public void run() { 3946320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSessionCallback.onVideoSizeChanged(mSession, width, height); 3956320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 3966320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo }); 3976320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 3986320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 3996320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoAvailable() { 4009b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mHandler.post(new Runnable() { 4019b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 4029b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void run() { 4039b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mSessionCallback.onVideoAvailable(mSession); 4049b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4059b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang }); 4069b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4079b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 4086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoUnavailable(final int reason) { 4099b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mHandler.post(new Runnable() { 4109b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 4119b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void run() { 4129b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mSessionCallback.onVideoUnavailable(mSession, reason); 4139b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4149b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang }); 4159b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4169b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 4176320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postContentAllowed() { 418bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo mHandler.post(new Runnable() { 419bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo @Override 420bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void run() { 421bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo mSessionCallback.onContentAllowed(mSession); 422bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 423bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo }); 424bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 425bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 4266320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postContentBlocked(final TvContentRating rating) { 4276057102dbb746593a7d59cf377c969b62e38c664Jae Seo mHandler.post(new Runnable() { 4286057102dbb746593a7d59cf377c969b62e38c664Jae Seo @Override 4296057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void run() { 4306057102dbb746593a7d59cf377c969b62e38c664Jae Seo mSessionCallback.onContentBlocked(mSession, rating); 4316057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 4326057102dbb746593a7d59cf377c969b62e38c664Jae Seo }); 4336057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 4346057102dbb746593a7d59cf377c969b62e38c664Jae Seo 4356320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postLayoutSurface(final int left, final int top, final int right, 436ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho final int bottom) { 437ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho mHandler.post(new Runnable() { 438ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @Override 439ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void run() { 440ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho mSessionCallback.onLayoutSurface(mSession, left, top, right, bottom); 441ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 442ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho }); 443ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 444ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 4456320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionEvent(final String eventType, final Bundle eventArgs) { 446832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mHandler.post(new Runnable() { 447832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 448832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void run() { 449832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mSessionCallback.onSessionEvent(mSession, eventType, eventArgs); 450832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 451832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho }); 452832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 4533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 4543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 4553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 4562778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Callback used to monitor status of the TV input. 4573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 4582778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public abstract static class TvInputCallback { 4593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 460969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * This is called when the state of a given TV input is changed. 4613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 4628e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 4638e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param state State of the TV input. The value is one of the following: 464969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <ul> 465969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_CONNECTED} 466969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_CONNECTED_STANDBY} 467969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_DISCONNECTED} 468969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </ul> 4693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 470969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public void onInputStateChanged(String inputId, int state) { 4713957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 4728e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 4738e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim /** 4748e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * This is called when a TV input is added. 4758e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * 4768e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 4778e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim */ 4788e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputAdded(String inputId) { 4798e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 4808e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 4818e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim /** 4828e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * This is called when a TV input is removed. 4838e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * 4848e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 4858e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim */ 4868e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputRemoved(String inputId) { 4878e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 48819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 48919ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee /** 49019ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * This is called when a TV input is updated. The update of TV input happens when it is 49119ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * reinstalled or the media on which the newer version of TV input exists is 49219ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * available/unavailable. 49319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * 49419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * @param inputId The id of the TV input. 49519ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * @hide 49619ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee */ 49719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @SystemApi 49819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void onInputUpdated(String inputId) { 49919ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 5003957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5013957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5022778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private static final class TvInputCallbackRecord { 5032778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private final TvInputCallback mCallback; 5043957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final Handler mHandler; 5053957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5062778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public TvInputCallbackRecord(TvInputCallback callback, Handler handler) { 5072778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback = callback; 5083957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler = handler; 5093957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5103957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5112778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public TvInputCallback getCallback() { 5122778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo return mCallback; 5138e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5148e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 5158e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void postInputStateChanged(final String inputId, final int state) { 5168e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mHandler.post(new Runnable() { 5178e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 5188e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void run() { 5192778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback.onInputStateChanged(inputId, state); 5208e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5218e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim }); 5228e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5238e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 5248e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void postInputAdded(final String inputId) { 5258e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mHandler.post(new Runnable() { 5268e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 5278e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void run() { 5282778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback.onInputAdded(inputId); 5298e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5308e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim }); 5313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5338e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void postInputRemoved(final String inputId) { 5343957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler.post(new Runnable() { 5353957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 5363957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void run() { 5372778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback.onInputRemoved(inputId); 5383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }); 5403957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 54119ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 54219ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void postInputUpdated(final String inputId) { 54319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee mHandler.post(new Runnable() { 54419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @Override 54519ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void run() { 546db8f7ab752de641b147015a2b4a134913fbcb594Youngsang Cho mCallback.onInputUpdated(inputId); 54719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 54819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee }); 54919ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 5503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 553d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Interface used to receive events from Hardware objects. 554d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 555d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 556d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 557d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract static class HardwareCallback { 558d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract void onReleased(); 559d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract void onStreamConfigChanged(TvStreamConfig[] configs); 560d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 561d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 562d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 5633957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @hide 5643957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 5653957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public TvInputManager(ITvInputManager service, int userId) { 5663957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService = service; 5673957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mUserId = userId; 5683957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mClient = new ITvInputClient.Stub() { 5693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 570d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim public void onSessionCreated(String inputId, IBinder token, InputChannel channel, 5716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int seq) { 5722b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 5732b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 5743957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (record == null) { 5753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Log.e(TAG, "Callback not found for " + token); 5763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo return; 5773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Session session = null; 5793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (token != null) { 5802b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim session = new Session(token, channel, mService, mUserId, seq, 5812b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap); 5823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5833957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo record.postSessionCreated(session); 5843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5853957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5863957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5873957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 5882b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionReleased(int seq) { 5892b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 5902b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 5912b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.delete(seq); 5922b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (record == null) { 5932b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim Log.e(TAG, "Callback not found for seq:" + seq); 5942b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim return; 5952b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 5962b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim record.mSession.releaseInternal(); 5972b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim record.postSessionReleased(); 5982b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 5992b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 6002b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 6012b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim @Override 6021f213914c45c23c653f721690da2ce0718e63139Dongwon Kang public void onChannelRetuned(Uri channelUri, int seq) { 603a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang synchronized (mSessionCallbackRecordMap) { 604a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 605a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang if (record == null) { 606a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 607a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang return; 608a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 6091f213914c45c23c653f721690da2ce0718e63139Dongwon Kang record.postChannelRetuned(channelUri); 610a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 611a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 612a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang 613a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang @Override 61410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTracksChanged(List<TvTrackInfo> tracks, int seq) { 615832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho synchronized (mSessionCallbackRecordMap) { 616832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 617832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho if (record == null) { 618832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho Log.e(TAG, "Callback not found for seq " + seq); 619832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho return; 620832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 6216320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (record.mSession.updateTracks(tracks)) { 6226320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postTracksChanged(tracks); 6236320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo postVideoSizeChangedIfNeededLocked(record); 6246320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 625b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 626b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 627b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 628b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang @Override 62910d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTrackSelected(int type, String trackId, int seq) { 630d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo synchronized (mSessionCallbackRecordMap) { 631d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 632d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo if (record == null) { 633d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 634d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo return; 635d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 6366320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (record.mSession.updateTrackSelection(type, trackId)) { 6376320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postTrackSelected(type, trackId); 6386320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo postVideoSizeChangedIfNeededLocked(record); 6396320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6406320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6416320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6426320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 6436320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private void postVideoSizeChangedIfNeededLocked(SessionCallbackRecord record) { 6446320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo TvTrackInfo track = record.mSession.getVideoTrackToNotify(); 6456320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track != null) { 6466320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postVideoSizeChanged(track.getVideoWidth(), track.getVideoHeight()); 647d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 648d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 649d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 650d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo @Override 6519b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoAvailable(int seq) { 6529b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang synchronized (mSessionCallbackRecordMap) { 6539b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 6549b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang if (record == null) { 6559b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 6569b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang return; 6579b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6589b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang record.postVideoAvailable(); 6599b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6609b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6619b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 6629b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 6639b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoUnavailable(int reason, int seq) { 6649b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang synchronized (mSessionCallbackRecordMap) { 6659b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 6669b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang if (record == null) { 6679b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 6689b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang return; 6699b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6709b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang record.postVideoUnavailable(reason); 6719b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6729b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6739b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 6749b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 675bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void onContentAllowed(int seq) { 676bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo synchronized (mSessionCallbackRecordMap) { 677bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 678bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo if (record == null) { 679bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 680bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo return; 681bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 682bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo record.postContentAllowed(); 683bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 684bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 685bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 686bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo @Override 6876057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void onContentBlocked(String rating, int seq) { 6886057102dbb746593a7d59cf377c969b62e38c664Jae Seo synchronized (mSessionCallbackRecordMap) { 6896057102dbb746593a7d59cf377c969b62e38c664Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 6906057102dbb746593a7d59cf377c969b62e38c664Jae Seo if (record == null) { 6916057102dbb746593a7d59cf377c969b62e38c664Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 6926057102dbb746593a7d59cf377c969b62e38c664Jae Seo return; 6936057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6946057102dbb746593a7d59cf377c969b62e38c664Jae Seo record.postContentBlocked(TvContentRating.unflattenFromString(rating)); 6956057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6966057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6976057102dbb746593a7d59cf377c969b62e38c664Jae Seo 6986057102dbb746593a7d59cf377c969b62e38c664Jae Seo @Override 699ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void onLayoutSurface(int left, int top, int right, int bottom, int seq) { 700ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho synchronized (mSessionCallbackRecordMap) { 701ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 702ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho if (record == null) { 703ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho Log.e(TAG, "Callback not found for seq " + seq); 704ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho return; 705ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 706ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho record.postLayoutSurface(left, top, right, bottom); 707ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 708ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 709ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 710ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @Override 711832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void onSessionEvent(String eventType, Bundle eventArgs, int seq) { 712832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho synchronized (mSessionCallbackRecordMap) { 713832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 714832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho if (record == null) { 715832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho Log.e(TAG, "Callback not found for seq " + seq); 716832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho return; 717832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 718832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho record.postSessionEvent(eventType, eventArgs); 719832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 720832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 721969167dc05a6485a32d160895871cff46fd81884Wonsik Kim }; 7222778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mManagerCallback = new ITvInputManagerCallback.Stub() { 723832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 724969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public void onInputStateChanged(String inputId, int state) { 725969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 726969167dc05a6485a32d160895871cff46fd81884Wonsik Kim mStateMap.put(inputId, state); 7272778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 7288e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputStateChanged(inputId, state); 7298e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7308e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7318e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7328e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 7338e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 7348e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputAdded(String inputId) { 7358e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim synchronized (mLock) { 7368e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mStateMap.put(inputId, INPUT_STATE_CONNECTED); 7372778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 7388e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputAdded(inputId); 7398e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7408e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7418e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7428e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 7438e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 7448e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputRemoved(String inputId) { 7458e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim synchronized (mLock) { 7468e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mStateMap.remove(inputId); 7472778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 7488e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputRemoved(inputId); 7493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 75219ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 75319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @Override 75419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void onInputUpdated(String inputId) { 75519ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee synchronized (mLock) { 756db8f7ab752de641b147015a2b4a134913fbcb594Youngsang Cho for (TvInputCallbackRecord record : mCallbackRecords) { 75719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee record.postInputUpdated(inputId); 75819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 75919ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 76019ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 7613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }; 762969167dc05a6485a32d160895871cff46fd81884Wonsik Kim try { 7639127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo if (mService != null) { 7649127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo mService.registerCallback(mManagerCallback, mUserId); 765993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang List<TvInputInfo> infos = mService.getTvInputList(mUserId); 766993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang synchronized (mLock) { 767993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang for (TvInputInfo info : infos) { 768993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang String inputId = info.getId(); 769993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang int state = mService.getTvInputState(inputId, mUserId); 770993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang if (state != INPUT_STATE_UNKNOWN) { 771993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang mStateMap.put(inputId, state); 772993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang } 773993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang } 774993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang } 7759127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo } 776969167dc05a6485a32d160895871cff46fd81884Wonsik Kim } catch (RemoteException e) { 777993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang Log.e(TAG, "TvInputManager initialization failed: " + e); 778969167dc05a6485a32d160895871cff46fd81884Wonsik Kim } 7793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 7813957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 7823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Returns the complete list of TV inputs on the system. 7833957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 7843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @return List of {@link TvInputInfo} for each TV input that describes its meta information. 7853957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 7863957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public List<TvInputInfo> getTvInputList() { 7873957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 7883957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo return mService.getTvInputList(mUserId); 7893957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 7903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 7913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7923957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 7943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 795b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * Returns the {@link TvInputInfo} for a given TV input. 796b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * 797b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * @param inputId The ID of the TV input. 798b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * @return the {@link TvInputInfo} for a given TV input. {@code null} if not found. 799b375805f3b1672e68d1511565af4700e5fa8491dJae Seo */ 800b375805f3b1672e68d1511565af4700e5fa8491dJae Seo public TvInputInfo getTvInputInfo(String inputId) { 801783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (inputId == null) { 802783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("inputId cannot be null"); 803783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 804b375805f3b1672e68d1511565af4700e5fa8491dJae Seo try { 805b375805f3b1672e68d1511565af4700e5fa8491dJae Seo return mService.getTvInputInfo(inputId, mUserId); 806b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } catch (RemoteException e) { 807b375805f3b1672e68d1511565af4700e5fa8491dJae Seo throw new RuntimeException(e); 808b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } 809b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } 810b375805f3b1672e68d1511565af4700e5fa8491dJae Seo 811b375805f3b1672e68d1511565af4700e5fa8491dJae Seo /** 8126320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns the state of a given TV input. It returns one of the following: 813969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <ul> 814969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_CONNECTED} 815969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_CONNECTED_STANDBY} 816969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_DISCONNECTED} 817969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </ul> 8183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 8198e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 820969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * @throws IllegalArgumentException if the argument is {@code null} or if there is no 821969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * {@link TvInputInfo} corresponding to {@code inputId}. 8223957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 823969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public int getInputState(String inputId) { 824d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim if (inputId == null) { 825783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("inputId cannot be null"); 8263957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 827969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 828969167dc05a6485a32d160895871cff46fd81884Wonsik Kim Integer state = mStateMap.get(inputId); 829969167dc05a6485a32d160895871cff46fd81884Wonsik Kim if (state == null) { 830969167dc05a6485a32d160895871cff46fd81884Wonsik Kim throw new IllegalArgumentException("Unrecognized input ID: " + inputId); 8313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 832969167dc05a6485a32d160895871cff46fd81884Wonsik Kim return state.intValue(); 8333957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8343957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8353957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8363957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 8372778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Registers a {@link TvInputCallback}. 8383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 8392778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * @param callback A callback used to monitor status of the TV inputs. 8408e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the status change will be delivered to. 8413957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if any of the arguments is {@code null}. 8423957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 8432778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public void registerCallback(TvInputCallback callback, Handler handler) { 8442778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo if (callback == null) { 8458e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim throw new IllegalArgumentException("callback cannot be null"); 8463957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (handler == null) { 8483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("handler cannot be null"); 8493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 850969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 8512778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallbackRecords.add(new TvInputCallbackRecord(callback, handler)); 8523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 8562778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Unregisters the existing {@link TvInputCallback}. 8573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 8582778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * @param callback The existing callback to remove. 8593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if any of the arguments is {@code null}. 8603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 8612778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public void unregisterCallback(final TvInputCallback callback) { 8622778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo if (callback == null) { 8638e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim throw new IllegalArgumentException("callback cannot be null"); 8643957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 865969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 8662778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (Iterator<TvInputCallbackRecord> it = mCallbackRecords.iterator(); 867969167dc05a6485a32d160895871cff46fd81884Wonsik Kim it.hasNext(); ) { 8682778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo TvInputCallbackRecord record = it.next(); 8692778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo if (record.getCallback() == callback) { 8703957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo it.remove(); 871969167dc05a6485a32d160895871cff46fd81884Wonsik Kim break; 8723957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8743957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 878783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Returns the user's parental controls enabled state. 879783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 880783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return {@code true} if the user enabled the parental controls, {@code false} otherwise. 881783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 882783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public boolean isParentalControlsEnabled() { 883783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 884783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return mService.isParentalControlsEnabled(mUserId); 885783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 886783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 887783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 888783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 889783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 890783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 891783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Sets the user's parental controls enabled state. 892783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 893783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param enabled The user's parental controls enabled state. {@code true} if the user enabled 894783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * the parental controls, {@code false} otherwise. 895783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isParentalControlsEnabled 896783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 897783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 898783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 899783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public void setParentalControlsEnabled(boolean enabled) { 900783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 901783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.setParentalControlsEnabled(enabled, mUserId); 902783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 903783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 904783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 905783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 906783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 907783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 908783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Checks whether a given TV content rating is blocked by the user. 909783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 910783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The TV content rating to check. 911783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return {@code true} if the given TV content rating is blocked, {@code false} otherwise. 912783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 913783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public boolean isRatingBlocked(TvContentRating rating) { 914783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (rating == null) { 915783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("rating cannot be null"); 916783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 917783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 918783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return mService.isRatingBlocked(rating.flattenToString(), mUserId); 919783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 920783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 921783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 922783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 923783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 924783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 925783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Returns the list of blocked content ratings. 926783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 927783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return the list of content ratings blocked by the user. 928783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 929783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 930783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 931783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public List<TvContentRating> getBlockedRatings() { 932783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 933783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo List<TvContentRating> ratings = new ArrayList<TvContentRating>(); 934783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo for (String rating : mService.getBlockedRatings(mUserId)) { 935783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo ratings.add(TvContentRating.unflattenFromString(rating)); 936783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 937783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return ratings; 938783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 939783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 940783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 941783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 942783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 943783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 944783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Adds a user blocked content rating. 945783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 946783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The content rating to block. 947783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isRatingBlocked 948783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #removeBlockedRating 949783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 950783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 951783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 952783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public void addBlockedRating(TvContentRating rating) { 953783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (rating == null) { 954783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("rating cannot be null"); 955783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 956783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 957783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.addBlockedRating(rating.flattenToString(), mUserId); 958783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 959783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 960783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 961783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 962783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 963783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 964783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Removes a user blocked content rating. 965783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 966783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The content rating to unblock. 967783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isRatingBlocked 968783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #addBlockedRating 969783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 970783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 971783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 972783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public void removeBlockedRating(TvContentRating rating) { 973783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (rating == null) { 974783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("rating cannot be null"); 975783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 976783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 977783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.removeBlockedRating(rating.flattenToString(), mUserId); 978783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 979783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 980783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 981783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 982783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 983783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 9849c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Returns the list of all TV content rating systems defined. 9855c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim * @hide 9865c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim */ 9875c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim @SystemApi 9889c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public List<TvContentRatingSystemInfo> getTvContentRatingSystemList() { 9895c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim try { 9909c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo return mService.getTvContentRatingSystemList(mUserId); 9915c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } catch (RemoteException e) { 9925c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim throw new RuntimeException(e); 9935c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } 9945c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } 9955c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim 9965c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim /** 997674e96216d6a60f0d87d3a6a0d62f358a101532bYoungsang Cho * Creates a {@link Session} for a given TV input. 9983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * <p> 9993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * The number of sessions that can be created at the same time is limited by the capability of 10003957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * the given TV input. 10013957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * </p> 10023957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 10038e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 10048e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param callback A callback used to receive the created session. 10058e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the session creation will be delivered to. 10063957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if any of the arguments is {@code null}. 1007b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 10083957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 100915bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 10102b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void createSession(String inputId, final SessionCallback callback, 10113957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Handler handler) { 1012d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim if (inputId == null) { 1013d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim throw new IllegalArgumentException("id cannot be null"); 10143957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10153957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (callback == null) { 10163957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("callback cannot be null"); 10173957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (handler == null) { 10193957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("handler cannot be null"); 10203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10212b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = new SessionCallbackRecord(callback, handler); 10222b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 10233957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo int seq = mNextSeq++; 10242b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.put(seq, record); 10253957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 1026d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim mService.createSession(mClient, inputId, seq, mUserId); 10273957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 10283957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 10293957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10303957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1033b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo /** 1034c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * Returns the TvStreamConfig list of the given TV input. 1035c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * 103690e733385d466acd87730676c83c080a17ff495fWonsik Kim * If you are using {@link Hardware} object from {@link 103790e733385d466acd87730676c83c080a17ff495fWonsik Kim * #acquireTvInputHardware}, you should get the list of available streams 103890e733385d466acd87730676c83c080a17ff495fWonsik Kim * from {@link HardwareCallback#onStreamConfigChanged} method, not from 103990e733385d466acd87730676c83c080a17ff495fWonsik Kim * here. This method is designed to be used with {@link #captureFrame} in 104090e733385d466acd87730676c83c080a17ff495fWonsik Kim * capture scenarios specifically and not suitable for any other use. 104190e733385d466acd87730676c83c080a17ff495fWonsik Kim * 1042c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param inputId the id of the TV input. 1043c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @return List of {@link TvStreamConfig} which is available for capturing 1044c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * of the given TV input. 1045c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @hide 1046c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo */ 1047c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo @SystemApi 1048c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId) { 1049c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo try { 1050c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo return mService.getAvailableTvStreamConfigList(inputId, mUserId); 1051c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } catch (RemoteException e) { 1052c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo throw new RuntimeException(e); 1053c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1054c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1055c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo 1056c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo /** 1057c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * Take a snapshot of the given TV input into the provided Surface. 1058c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * 1059c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param inputId the id of the TV input. 1060c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param surface the {@link Surface} to which the snapshot is captured. 1061c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param config the {@link TvStreamConfig} which is used for capturing. 1062c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @return true when the {@link Surface} is ready to be captured. 1063c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @hide 1064c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo */ 1065c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo @SystemApi 1066c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo public boolean captureFrame(String inputId, Surface surface, TvStreamConfig config) { 1067c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo try { 1068c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo return mService.captureFrame(inputId, surface, config, mUserId); 1069c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } catch (RemoteException e) { 1070c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo throw new RuntimeException(e); 1071df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } 1072df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } 1073df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo 1074df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo /** 1075df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * Returns true if there is only a single TV input session. 1076df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * 1077df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * @hide 1078df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo */ 1079df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo @SystemApi 1080df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo public boolean isSingleSessionActive() { 1081df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo try { 1082df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo return mService.isSingleSessionActive(mUserId); 1083df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } catch (RemoteException e) { 1084df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo throw new RuntimeException(e); 1085c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1086c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1087c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo 1088c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo /** 1089d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Returns a list of TvInputHardwareInfo objects representing available hardware. 1090d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1091d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1092d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1093d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1094d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public List<TvInputHardwareInfo> getHardwareList() { 1095d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1096d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mService.getHardwareList(); 1097d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1098d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1099d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1100d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1101d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1102d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1103d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Returns acquired TvInputManager.Hardware object for given deviceId. 1104d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1105d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * If there are other Hardware object acquired for the same deviceId, calling this method will 1106d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * preempt the previously acquired object and report {@link HardwareCallback#onReleased} to the 1107d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * old object. 1108d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1109d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1110d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1111d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1112d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public Hardware acquireTvInputHardware(int deviceId, final HardwareCallback callback, 1113d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim TvInputInfo info) { 1114d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1115d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return new Hardware( 1116d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mService.acquireTvInputHardware(deviceId, new ITvInputHardwareCallback.Stub() { 1117d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @Override 1118d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void onReleased() { 1119d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim callback.onReleased(); 1120d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1121d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1122d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @Override 1123d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void onStreamConfigChanged(TvStreamConfig[] configs) { 1124d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim callback.onStreamConfigChanged(configs); 1125d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1126d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim }, info, mUserId)); 1127d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1128d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1129d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1130d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1131d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1132d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1133d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Releases previously acquired hardware object. 1134d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1135d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1136d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1137d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1138d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void releaseTvInputHardware(int deviceId, Hardware hardware) { 1139d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1140d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mService.releaseTvInputHardware(deviceId, hardware.getInterface(), mUserId); 1141d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1142d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1143d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1144d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1145d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1146d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1147b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * The Session provides the per-session functionality of TV inputs. 1148b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 1149b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo */ 115015bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 11513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public static final class Session { 11526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_IN_PROGRESS = -1; 11536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_NOT_HANDLED = 0; 11546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_HANDLED = 1; 11556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private static final long INPUT_SESSION_NOT_RESPONDING_TIMEOUT = 2500; 11576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputManager mService; 11593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final int mUserId; 11602b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final int mSeq; 11616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // For scheduling input event handling on the main thread. This also serves as a lock to 11636a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // protect pending input events and the input channel. 11646a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final InputEventHandler mHandler = new InputEventHandler(Looper.getMainLooper()); 11656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final Pool<PendingEvent> mPendingEventPool = new SimplePool<PendingEvent>(20); 11676a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final SparseArray<PendingEvent> mPendingEvents = new SparseArray<PendingEvent>(20); 11682b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap; 11696a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11709a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho private IBinder mToken; 11716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private TvInputEventSender mSender; 11726a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private InputChannel mChannel; 11736320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 11746320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private final Object mTrackLock = new Object(); 11756320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 117610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private final List<TvTrackInfo> mAudioTracks = new ArrayList<TvTrackInfo>(); 11776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 117810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private final List<TvTrackInfo> mVideoTracks = new ArrayList<TvTrackInfo>(); 11796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 118010d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<TvTrackInfo>(); 11816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 118210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedAudioTrackId; 11836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 118410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedVideoTrackId; 11856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 118610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedSubtitleTrackId; 11876320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 11886320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private int mVideoWidth; 11896320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 11906320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private int mVideoHeight; 11913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 11922b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId, 11932b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) { 11943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mToken = token; 11956a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mChannel = channel; 11963957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService = service; 11973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mUserId = userId; 11982b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSeq = seq; 11992b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap = sessionCallbackRecordMap; 12003957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12013957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12023957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 12033957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Releases this session. 12043957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 12053957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void release() { 12069a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1207dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1208dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 12099a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 12103957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 12113957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.releaseSession(mToken, mUserId); 12123957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 12133957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 12143957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12156a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 12162b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim releaseInternal(); 12173957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12193957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 122015c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * Sets this as the main session. The main session is a session whose corresponding TV 122115c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * input determines the HDMI-CEC active source device. 122215c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * 122315c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * @see TvView#setMain 12244c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee */ 122515c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee void setMain() { 12264c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee if (mToken == null) { 12274c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee Log.w(TAG, "The session has been already released"); 12284c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee return; 12294c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 12304c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee try { 12314c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee mService.setMainSession(mToken, mUserId); 12324c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } catch (RemoteException e) { 12334c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee throw new RuntimeException(e); 12344c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 12354c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 12364c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee 12374c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee /** 12383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Sets the {@link android.view.Surface} for this session. 12393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 12403957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param surface A {@link android.view.Surface} used to render video. 12413957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1242f1c025cbcd98f2366d384c5aac114c330090a645Wonsik Kim public void setSurface(Surface surface) { 12439a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1244dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1245dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 12469a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 12473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo // surface can be null. 12483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 12493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.setSurface(mToken, surface, mUserId); 12503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 12513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 12523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1256e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * Notifies of any structural changes (format or size) of the {@link Surface} 1257e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * passed by {@link #setSurface}. 1258e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * 1259e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @param format The new PixelFormat of the {@link Surface}. 1260e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @param width The new width of the {@link Surface}. 1261e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @param height The new height of the {@link Surface}. 1262e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @hide 1263e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho */ 126415bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 1265e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho public void dispatchSurfaceChanged(int format, int width, int height) { 1266e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho if (mToken == null) { 1267e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho Log.w(TAG, "The session has been already released"); 1268e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho return; 1269e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1270e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho try { 1271e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho mService.dispatchSurfaceChanged(mToken, format, width, height, mUserId); 1272e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } catch (RemoteException e) { 1273e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho throw new RuntimeException(e); 1274e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1275e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1276e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho 1277e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho /** 1278782f7345471072b630e58c7abd3579b0015273b1Jae Seo * Sets the relative stream volume of this session to handle a change of audio focus. 12793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 12803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param volume A volume value between 0.0f to 1.0f. 12813957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if the volume value is out of range. 12823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1283782f7345471072b630e58c7abd3579b0015273b1Jae Seo public void setStreamVolume(float volume) { 12849a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1285dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1286dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 12879a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 12883957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 12893957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (volume < 0.0f || volume > 1.0f) { 12903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("volume should be between 0.0f and 1.0f"); 12913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12923957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.setVolume(mToken, volume, mUserId); 12933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 12943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 12953957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12963957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 12993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Tunes to a given channel. 13003957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 13013957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param channelUri The URI of a channel. 13023957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if the argument is {@code null}. 13033957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 13043957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void tune(Uri channelUri) { 13051a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim tune(channelUri, null); 13061a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim } 13071a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim 13081a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim /** 13091a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * Tunes to a given channel. 13101a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * 13111a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @param channelUri The URI of a channel. 13121a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @param params A set of extra parameters which might be handled with this tune event. 13131a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @throws IllegalArgumentException if {@code channelUri} is {@code null}. 13141a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @hide 13151a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim */ 13161a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim @SystemApi 13171a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim public void tune(Uri channelUri, Bundle params) { 13183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (channelUri == null) { 13193957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("channelUri cannot be null"); 13203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 13219a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1322dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1323dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 13249a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 13256320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 13266320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.clear(); 13276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.clear(); 13286320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.clear(); 13296320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedAudioTrackId = null; 13306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedVideoTrackId = null; 13316320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedSubtitleTrackId = null; 13326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoWidth = 0; 13336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoHeight = 0; 13346320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13353957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 13361a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim mService.tune(mToken, channelUri, params, mUserId); 13373957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 13383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 13393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 13403957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 13419a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 13429a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 13432c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * Enables or disables the caption for this session. 13442c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * 13452c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * @param enabled {@code true} to enable, {@code false} to disable. 13462c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo */ 13472c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo public void setCaptionEnabled(boolean enabled) { 13482c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo if (mToken == null) { 13492c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo Log.w(TAG, "The session has been already released"); 13502c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo return; 13512c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 13522c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo try { 13532c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo mService.setCaptionEnabled(mToken, enabled, mUserId); 13542c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } catch (RemoteException e) { 13552c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo throw new RuntimeException(e); 13562c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 13572c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 13582c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo 13592c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo /** 13601f81b1040f40a3233981f34268b11e5c9ad9f34cDongwon Kang * Selects a track. 13611f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * 136210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the track to select. The type can be 136310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or 136410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_SUBTITLE}. 136510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param trackId The ID of the track to select. When {@code null}, the currently selected 136610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * track of the given type will be unselected. 13675b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @see #getTracks 13681f213914c45c23c653f721690da2ce0718e63139Dongwon Kang */ 136910d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void selectTrack(int type, String trackId) { 13706320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 13716320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 13726320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mAudioTracks, trackId)) { 13736320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid audio trackId: " + trackId); 13746320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 13756320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13766320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 13776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mVideoTracks, trackId)) { 13786320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid video trackId: " + trackId); 13796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 13806320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 13826320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mSubtitleTracks, trackId)) { 13836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid subtitle trackId: " + trackId); 13846320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 13856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13866320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else { 13876320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo throw new IllegalArgumentException("invalid type: " + type); 138810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo } 13891f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 13901f213914c45c23c653f721690da2ce0718e63139Dongwon Kang if (mToken == null) { 13911f213914c45c23c653f721690da2ce0718e63139Dongwon Kang Log.w(TAG, "The session has been already released"); 13921f213914c45c23c653f721690da2ce0718e63139Dongwon Kang return; 13931f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 13941f213914c45c23c653f721690da2ce0718e63139Dongwon Kang try { 139510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mService.selectTrack(mToken, type, trackId, mUserId); 13961f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } catch (RemoteException e) { 13971f213914c45c23c653f721690da2ce0718e63139Dongwon Kang throw new RuntimeException(e); 13981f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 13991f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 14001f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 1401984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee private boolean containsTrack(List<TvTrackInfo> tracks, String trackId) { 1402984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee for (TvTrackInfo track : tracks) { 1403984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee if (track.getId().equals(trackId)) { 1404984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee return true; 1405984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1406984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1407984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee return false; 1408984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1409984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee 14101f213914c45c23c653f721690da2ce0718e63139Dongwon Kang /** 141110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * Returns the list of tracks for a given type. Returns {@code null} if the information is 141210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * not available. 14131f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * 141410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO}, 141510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}. 141610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @return the list of tracks for the given type. 14171f213914c45c23c653f721690da2ce0718e63139Dongwon Kang */ 141810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public List<TvTrackInfo> getTracks(int type) { 14196320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14206320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 14216320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mAudioTracks == null) { 14226320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 14236320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14246320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return new ArrayList<TvTrackInfo>(mAudioTracks); 14256320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 14266320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mVideoTracks == null) { 14276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 14286320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14296320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return new ArrayList<TvTrackInfo>(mVideoTracks); 14306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 14316320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mSubtitleTracks == null) { 14326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 14336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14346320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return new ArrayList<TvTrackInfo>(mSubtitleTracks); 143510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo } 14361f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 143710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo throw new IllegalArgumentException("invalid type: " + type); 14381f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 14391f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 1440d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo /** 144110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * Returns the selected track for a given type. Returns {@code null} if the information is 144210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * not available or any of the tracks for the given type is not selected. 144310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * 144410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @return the ID of the selected track. 144510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @see #selectTrack 1446d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo */ 144710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public String getSelectedTrack(int type) { 14486320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14496320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 14506320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedAudioTrackId; 14516320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 14526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedVideoTrackId; 14536320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 14546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedSubtitleTrackId; 14556320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 1456d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 145710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo throw new IllegalArgumentException("invalid type: " + type); 14581f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 14591f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 14601f213914c45c23c653f721690da2ce0718e63139Dongwon Kang /** 14616320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Responds to onTracksChanged() and updates the internal track information. Returns true if 14626320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * there is an update. 14636320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 14646320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo boolean updateTracks(List<TvTrackInfo> tracks) { 14656320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14666320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.clear(); 14676320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.clear(); 14686320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.clear(); 14696320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo for (TvTrackInfo track : tracks) { 14706320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track.getType() == TvTrackInfo.TYPE_AUDIO) { 14716320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.add(track); 14726320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) { 14736320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.add(track); 14746320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) { 14756320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.add(track); 14766320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14786320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return !mAudioTracks.isEmpty() || !mVideoTracks.isEmpty() 14796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo || !mSubtitleTracks.isEmpty(); 14806320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14826320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 14836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 14846320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Responds to onTrackSelected() and updates the internal track selection information. 14856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns true if there is an update. 14866320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 14876320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo boolean updateTrackSelection(int type, String trackId) { 14886320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14896320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO && trackId != mSelectedAudioTrackId) { 14906320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedAudioTrackId = trackId; 14916320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 14926320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO && trackId != mSelectedVideoTrackId) { 14936320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedVideoTrackId = trackId; 14946320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 14956320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE 14966320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo && trackId != mSelectedSubtitleTrackId) { 14976320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedSubtitleTrackId = trackId; 14986320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 14996320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15006320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15016320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return false; 15026320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15036320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 15046320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 15056320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns the new/updated video track that contains new video size information. Returns 15066320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * null if there is no video track to notify. Subsequent calls of this method results in a 15076320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * non-null video track returned only by the first call and null returned by following 15086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * calls. The caller should immediately notify of the video size change upon receiving the 15096320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * track. 15106320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 15116320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo TvTrackInfo getVideoTrackToNotify() { 15126320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 15136320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (!mVideoTracks.isEmpty() && mSelectedVideoTrackId != null) { 15146320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo for (TvTrackInfo track : mVideoTracks) { 15156320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track.getId().equals(mSelectedVideoTrackId)) { 15166320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo int videoWidth = track.getVideoWidth(); 15176320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo int videoHeight = track.getVideoHeight(); 15186320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mVideoWidth != videoWidth || mVideoHeight != videoHeight) { 15196320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoWidth = videoWidth; 15206320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoHeight = videoHeight; 15216320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return track; 15226320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15236320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15246320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15256320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15266320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 15286320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15296320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 15306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 15311f81b1040f40a3233981f34268b11e5c9ad9f34cDongwon Kang * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle) 1532a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * TvInputService.Session.appPrivateCommand()} on the current TvView. 1533a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * 1534a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @param action Name of the command to be performed. This <em>must</em> be a scoped name, 1535a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * i.e. prefixed with a package name you own, so that different developers will 1536a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * not create conflicting commands. 1537a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @param data Any data to include with the command. 1538a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @hide 1539a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo */ 1540a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo @SystemApi 1541a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo public void sendAppPrivateCommand(String action, Bundle data) { 1542a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo if (mToken == null) { 1543a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo Log.w(TAG, "The session has been already released"); 1544a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo return; 1545a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 1546a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo try { 1547a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo mService.sendAppPrivateCommand(mToken, action, data, mUserId); 1548a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } catch (RemoteException e) { 1549a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo throw new RuntimeException(e); 1550a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 1551a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 1552a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo 1553a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo /** 15549a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Creates an overlay view. Once the overlay view is created, {@link #relayoutOverlayView} 15559a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * should be called whenever the layout of its containing view is changed. 15569a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * {@link #removeOverlayView()} should be called to remove the overlay view. 15579a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Since a session can have only one overlay view, this method should be called only once 15589a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * or it can be called again after calling {@link #removeOverlayView()}. 15599a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * 15609a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param view A view playing TV. 15619a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param frame A position of the overlay view. 15629a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @throws IllegalArgumentException if any of the arguments is {@code null}. 1563dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim * @throws IllegalStateException if {@code view} is not attached to a window. 15649a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 15659a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho void createOverlayView(View view, Rect frame) { 15669a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (view == null) { 15679a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalArgumentException("view cannot be null"); 15689a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15699a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (frame == null) { 15709a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalArgumentException("frame cannot be null"); 15719a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15729a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (view.getWindowToken() == null) { 15739a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalStateException("view must be attached to a window"); 15749a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15759a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1576dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1577dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 15789a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15799a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 15809a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.createOverlayView(mToken, view.getWindowToken(), frame, mUserId); 15819a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 15829a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new RuntimeException(e); 15839a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15849a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15859a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 15869a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 15879a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Relayouts the current overlay view. 15889a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * 15899a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param frame A new position of the overlay view. 15909a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @throws IllegalArgumentException if the arguments is {@code null}. 15919a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 15929a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho void relayoutOverlayView(Rect frame) { 15939a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (frame == null) { 15949a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalArgumentException("frame cannot be null"); 15959a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15969a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1597dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1598dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 15999a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 16009a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 16019a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.relayoutOverlayView(mToken, frame, mUserId); 16029a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 16039a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new RuntimeException(e); 16049a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 16059a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 16069a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 16079a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 16089a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Removes the current overlay view. 16099a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 16109a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho void removeOverlayView() { 16119a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1612dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1613dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 16149a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 16159a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 16169a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.removeOverlayView(mToken, mUserId); 16179a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 16189a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new RuntimeException(e); 16199a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 16209a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 16216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 16239bf671f8ee72b156f16fcf05a3d1c6e093ecba67Sungsoo Lim * Requests to unblock content blocked by parental controls. 1624903d6b72cd572665309633e925485464d08bb25aJaewan Kim */ 16259bf671f8ee72b156f16fcf05a3d1c6e093ecba67Sungsoo Lim void requestUnblockContent(TvContentRating unblockedRating) { 1626903d6b72cd572665309633e925485464d08bb25aJaewan Kim if (mToken == null) { 1627903d6b72cd572665309633e925485464d08bb25aJaewan Kim Log.w(TAG, "The session has been already released"); 1628903d6b72cd572665309633e925485464d08bb25aJaewan Kim return; 1629903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 1630a42be3c95021c5fb7e4ac0a8fbfc542f841f44ddJaewan Kim if (unblockedRating == null) { 1631a42be3c95021c5fb7e4ac0a8fbfc542f841f44ddJaewan Kim throw new IllegalArgumentException("unblockedRating cannot be null"); 1632a42be3c95021c5fb7e4ac0a8fbfc542f841f44ddJaewan Kim } 1633903d6b72cd572665309633e925485464d08bb25aJaewan Kim try { 16349bf671f8ee72b156f16fcf05a3d1c6e093ecba67Sungsoo Lim mService.requestUnblockContent(mToken, unblockedRating.flattenToString(), mUserId); 1635903d6b72cd572665309633e925485464d08bb25aJaewan Kim } catch (RemoteException e) { 1636903d6b72cd572665309633e925485464d08bb25aJaewan Kim throw new RuntimeException(e); 1637903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 1638903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 1639903d6b72cd572665309633e925485464d08bb25aJaewan Kim 1640903d6b72cd572665309633e925485464d08bb25aJaewan Kim /** 16416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Dispatches an input event to this session. 16426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 16438e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param event An {@link InputEvent} to dispatch. 16446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param token A token used to identify the input event later in the callback. 16456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param callback A callback used to receive the dispatch result. 16468e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the dispatch result will be delivered to. 16476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns 16486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns 16496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will 16506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * be invoked later. 16516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @throws IllegalArgumentException if any of the necessary arguments is {@code null}. 16526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @hide 16536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 16546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public int dispatchInputEvent(InputEvent event, Object token, 16556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo FinishedInputEventCallback callback, Handler handler) { 16566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (event == null) { 16576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo throw new IllegalArgumentException("event cannot be null"); 16586a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (callback != null && handler == null) { 16606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo throw new IllegalArgumentException("handler cannot be null"); 16616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 16636a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mChannel == null) { 16646a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_NOT_HANDLED; 16656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo PendingEvent p = obtainPendingEventLocked(event, token, callback, handler); 16676a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (Looper.myLooper() == Looper.getMainLooper()) { 16686a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Already running on the main thread so we can send the event immediately. 16696a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return sendInputEventOnMainLooperLocked(p); 16706a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16726a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Post the event to the main thread. 16736a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_SEND_INPUT_EVENT, p); 16746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 16756a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.sendMessage(msg); 16766a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_IN_PROGRESS; 16776a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16786a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16796a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16806a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 16816a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Callback that is invoked when an input event that was dispatched to this session has been 16826a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * finished. 16836a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 16846a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @hide 16856a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 16866a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public interface FinishedInputEventCallback { 16876a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 16886a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Called when the dispatched input event is finished. 16896a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 16908e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param token A token passed to {@link #dispatchInputEvent}. 16916a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param handled {@code true} if the dispatched input event was handled properly. 16926a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@code false} otherwise. 16936a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 16946a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void onFinishedInputEvent(Object token, boolean handled); 16956a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16966a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16976a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Must be called on the main looper 16986a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void sendInputEventAndReportResultOnMainLooper(PendingEvent p) { 16996a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 17006a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int result = sendInputEventOnMainLooperLocked(p); 17016a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (result == DISPATCH_IN_PROGRESS) { 17026a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 17036a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17046a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17056a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17066a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo invokeFinishedInputEventCallback(p, false); 17076a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17086a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17096a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private int sendInputEventOnMainLooperLocked(PendingEvent p) { 17106a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mChannel != null) { 17116a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mSender == null) { 17126a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mSender = new TvInputEventSender(mChannel, mHandler.getLooper()); 17136a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17146a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17156a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final InputEvent event = p.mEvent; 17166a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final int seq = event.getSequenceNumber(); 17176a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mSender.sendInputEvent(seq, event)) { 17186a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEvents.put(seq, p); 17196a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p); 17206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 17216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.sendMessageDelayed(msg, INPUT_SESSION_NOT_RESPONDING_TIMEOUT); 17226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_IN_PROGRESS; 17236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Log.w(TAG, "Unable to send input event to session: " + mToken + " dropping:" 17266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo + event); 17276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_NOT_HANDLED; 17296a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo void finishedInputEvent(int seq, boolean handled, boolean timeout) { 17326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final PendingEvent p; 17336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 17346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int index = mPendingEvents.indexOfKey(seq); 17356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (index < 0) { 17366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; // spurious, event already finished or timed out 17376a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p = mPendingEvents.valueAt(index); 17406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEvents.removeAt(index); 17416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (timeout) { 17436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Log.w(TAG, "Timeout waiting for seesion to handle input event after " 17446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo + INPUT_SESSION_NOT_RESPONDING_TIMEOUT + " ms: " + mToken); 17456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } else { 17466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.removeMessages(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p); 17476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo invokeFinishedInputEventCallback(p, handled); 17516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Assumes the event has already been removed from the queue. 17546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) { 17556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mHandled = handled; 17565b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo if (p.mEventHandler.getLooper().isCurrentThread()) { 17576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Already running on the callback handler thread so we can send the callback 17586a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // immediately. 17596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.run(); 17606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } else { 17616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Post the event to the callback handler thread. 17626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // In this case, the callback will be responsible for recycling the event. 17635b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo Message msg = Message.obtain(p.mEventHandler, p); 17646a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 17656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.sendToTarget(); 17666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17676a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17686a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17696a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void flushPendingEventsLocked() { 17706a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.removeMessages(InputEventHandler.MSG_FLUSH_INPUT_EVENT); 17716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17726a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final int count = mPendingEvents.size(); 17736a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo for (int i = 0; i < count; i++) { 17746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int seq = mPendingEvents.keyAt(i); 17756a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_FLUSH_INPUT_EVENT, seq, 0); 17766a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 17776a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.sendToTarget(); 17786a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17796a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17806a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17816a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private PendingEvent obtainPendingEventLocked(InputEvent event, Object token, 17826a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo FinishedInputEventCallback callback, Handler handler) { 17836a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo PendingEvent p = mPendingEventPool.acquire(); 17846a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (p == null) { 17856a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p = new PendingEvent(); 17866a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17876a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mEvent = event; 17885b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo p.mEventToken = token; 17896a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mCallback = callback; 17905b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo p.mEventHandler = handler; 17916a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return p; 17926a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17936a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17946a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void recyclePendingEventLocked(PendingEvent p) { 17956a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.recycle(); 17966a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEventPool.release(p); 17976a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17986a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 1799bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang IBinder getToken() { 1800bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang return mToken; 1801bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang } 1802bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang 18032b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private void releaseInternal() { 18042b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mToken = null; 18052b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mHandler) { 18062b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (mChannel != null) { 18072b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (mSender != null) { 18082b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim flushPendingEventsLocked(); 18092b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSender.dispose(); 18102b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSender = null; 18112b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 18122b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mChannel.dispose(); 18132b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mChannel = null; 18142b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 18152b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 18162b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 18172b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.remove(mSeq); 18182b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 18192b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 18202b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 18216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class InputEventHandler extends Handler { 18226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_SEND_INPUT_EVENT = 1; 18236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_TIMEOUT_INPUT_EVENT = 2; 18246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_FLUSH_INPUT_EVENT = 3; 18256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo InputEventHandler(Looper looper) { 18276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo super(looper, null, true); 18286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18296a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 18316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void handleMessage(Message msg) { 18326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo switch (msg.what) { 18336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_SEND_INPUT_EVENT: { 18346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo sendInputEventAndReportResultOnMainLooper((PendingEvent) msg.obj); 18356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 18366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18376a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_TIMEOUT_INPUT_EVENT: { 18386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(msg.arg1, false, true); 18396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 18406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_FLUSH_INPUT_EVENT: { 18426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(msg.arg1, false, false); 18436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 18446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class TvInputEventSender extends InputEventSender { 18506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public TvInputEventSender(InputChannel inputChannel, Looper looper) { 18516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo super(inputChannel, looper); 18526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 18556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void onInputEventFinished(int seq, boolean handled) { 18566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(seq, handled, false); 18576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18586a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class PendingEvent implements Runnable { 18616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public InputEvent mEvent; 18625b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo public Object mEventToken; 18636a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public FinishedInputEventCallback mCallback; 18645b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo public Handler mEventHandler; 18656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public boolean mHandled; 18666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18676a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void recycle() { 18686a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mEvent = null; 18695b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mEventToken = null; 18706a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mCallback = null; 18715b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mEventHandler = null; 18726a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandled = false; 18736a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18756a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 18766a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void run() { 18775b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mCallback.onFinishedInputEvent(mEventToken, mHandled); 18786a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18795b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo synchronized (mEventHandler) { 18806a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo recyclePendingEventLocked(this); 18816a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18826a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18836a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 1885d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1886d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1887d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * The Hardware provides the per-hardware functionality of TV hardware. 1888d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1889d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * TV hardware is physical hardware attached to the Android device; for example, HDMI ports, 1890d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Component/Composite ports, etc. Specifically, logical devices such as HDMI CEC logical 1891d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * devices don't fall into this category. 1892d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1893d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1894d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1895d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1896d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public final static class Hardware { 1897d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private final ITvInputHardware mInterface; 1898d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1899d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private Hardware(ITvInputHardware hardwareInterface) { 1900d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface = hardwareInterface; 1901d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1902d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1903d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private ITvInputHardware getInterface() { 1904d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface; 1905d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1906d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1907d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public boolean setSurface(Surface surface, TvStreamConfig config) { 1908d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1909d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface.setSurface(surface, config); 1910d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1911d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1912d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1913d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1914d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1915d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void setStreamVolume(float volume) { 1916d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1917d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface.setStreamVolume(volume); 1918d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1919d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1920d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1921d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1922d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1923d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public boolean dispatchKeyEventToHdmi(KeyEvent event) { 1924d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1925d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface.dispatchKeyEventToHdmi(event); 1926d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1927d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1928d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1929d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1930d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1931d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void overrideAudioSink(int audioType, String audioAddress, int samplingRate, 1932d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim int channelMask, int format) { 1933d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1934d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface.overrideAudioSink(audioType, audioAddress, samplingRate, channelMask, 1935d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim format); 1936d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1937d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1938d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1939d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1940d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 19413957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo} 1942