TvInputManager.java revision 4e389e557efb7806b73d2059d46e2809c1a9f83d
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 /** 75969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * The TV input is connected. 76969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <p> 77969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * State for {@link #getInputState} and {@link 782778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * TvInputManager.TvInputCallback#onInputStateChanged}. 79969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </p> 80969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 81969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_CONNECTED = 0; 82969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 83969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * The TV input is connected but in standby mode. It would take a while until it becomes 84969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * fully ready. 85969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <p> 86969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * State for {@link #getInputState} and {@link 872778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * TvInputManager.TvInputCallback#onInputStateChanged}. 88969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </p> 89969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 90969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_CONNECTED_STANDBY = 1; 91969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 92969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * The TV input is disconnected. 93969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <p> 94969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * State for {@link #getInputState} and {@link 952778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * TvInputManager.TvInputCallback#onInputStateChanged}. 96969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </p> 97969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 98969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_DISCONNECTED = 2; 99969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 100783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 101783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Broadcast intent action when the user blocked content ratings change. For use with the 102783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * {@link #isRatingBlocked}. 103783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 104783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public static final String ACTION_BLOCKED_RATINGS_CHANGED = 1052778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.BLOCKED_RATINGS_CHANGED"; 106783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 107783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 108783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Broadcast intent action when the parental controls enabled state changes. For use with the 109783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * {@link #isParentalControlsEnabled}. 110783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 111783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public static final String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = 1122778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED"; 1139c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo 1149c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo /** 1159c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Broadcast intent action used to query available content rating systems. 1169c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <p> 1179c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * The TV input manager service locates available content rating systems by querying broadcast 1189c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * receivers that are registered for this action. An application can offer additional content 1199c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * rating systems to the user by declaring a suitable broadcast receiver in its manifest. 1209c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </p><p> 1219c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Here is an example broadcast receiver declaration that an application might include in its 1229c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * AndroidManifest.xml to advertise custom content rating systems. The meta-data specifies a 1239c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * resource that contains a description of each content rating system that is provided by the 1249c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * application. 1259c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <p><pre class="prettyprint"> 1269c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * {@literal 1279c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <receiver android:name=".TvInputReceiver"> 1289c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <intent-filter> 1299c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <action android:name= 1304e389e557efb7806b73d2059d46e2809c1a9f83dSungsoo Lim * "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS" /> 1319c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </intent-filter> 1329c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <meta-data 1334e389e557efb7806b73d2059d46e2809c1a9f83dSungsoo Lim * android:name="android.media.tv.metadata.CONTENT_RATING_SYSTEMS" 1349c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * android:resource="@xml/tv_content_rating_systems" /> 1359c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </receiver>}</pre></p> 1369c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * In the above example, the <code>@xml/tv_content_rating_systems</code> resource refers to an 1379c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * XML resource whose root element is <code><rating-system-definitions></code> that 1389c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * contains zero or more <code><rating-system-definition></code> elements. Each <code> 1399c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <rating-system-definition></code> element specifies the ratings, sub-ratings and rating 1409c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * orders of a particular content rating system. 1419c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </p> 1429c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * 1439c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * @see TvContentRating 1449c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo */ 1459c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public static final String ACTION_QUERY_CONTENT_RATING_SYSTEMS = 1462778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS"; 1479c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo 1489c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo /** 1499c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Content rating systems metadata associated with {@link #ACTION_QUERY_CONTENT_RATING_SYSTEMS}. 1509c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <p> 1519c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Specifies the resource ID of an XML resource that describes the content rating systems that 1529c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * are provided by the application. 1539c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </p> 1549c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo */ 1559c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public static final String META_DATA_CONTENT_RATING_SYSTEMS = 1562778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.metadata.CONTENT_RATING_SYSTEMS"; 157783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputManager mService; 1593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 160969167dc05a6485a32d160895871cff46fd81884Wonsik Kim private final Object mLock = new Object(); 161969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 1626320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mLock") 1632778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private final List<TvInputCallbackRecord> mCallbackRecords = 1642778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo new LinkedList<TvInputCallbackRecord>(); 165969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 166969167dc05a6485a32d160895871cff46fd81884Wonsik Kim // A mapping from TV input ID to the state of corresponding input. 1676320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mLock") 168969167dc05a6485a32d160895871cff46fd81884Wonsik Kim private final Map<String, Integer> mStateMap = new ArrayMap<String, Integer>(); 1693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1702b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim // A mapping from the sequence number of a session to its SessionCallbackRecord. 1712b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap = 1722b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim new SparseArray<SessionCallbackRecord>(); 1733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1743957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo // A sequence number for the next session to be created. Should be protected by a lock 1752b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim // {@code mSessionCallbackRecordMap}. 1763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private int mNextSeq; 1773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputClient mClient; 1793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1802778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private final ITvInputManagerCallback mManagerCallback; 181969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 1823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final int mUserId; 1833957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1853957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Interface used to receive the created session. 186b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 1873957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 18815bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 1892b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public abstract static class SessionCallback { 1903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * This is called after {@link TvInputManager#createSession} has been processed. 1923957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 1933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param session A {@link TvInputManager.Session} instance created. This can be 1943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * {@code null} if the creation request failed. 1953957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1962b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionCreated(Session session) { 1972b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 1982b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 1992b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim /** 2002b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * This is called when {@link TvInputManager.Session} is released. 2012b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * This typically happens when the process hosting the session has crashed or been killed. 2022b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * 2032b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * @param session A {@link TvInputManager.Session} instance released. 2042b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim */ 2052b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionReleased(Session session) { 2062b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 207832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 208832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho /** 2091f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * This is called when the channel of this session is changed by the underlying TV input 2106320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * without any {@link TvInputManager.Session#tune(Uri)} request. 211a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang * 212d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2131f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * @param channelUri The URI of a channel. 214a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang */ 2151f213914c45c23c653f721690da2ce0718e63139Dongwon Kang public void onChannelRetuned(Session session, Uri channelUri) { 216832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 217832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 218832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho /** 2191f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * This is called when the track information of the session has been changed. 220b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang * 221d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2221f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * @param tracks A list which includes track information. 223b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang */ 22410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTracksChanged(Session session, List<TvTrackInfo> tracks) { 225b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 226b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 227b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang /** 22810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * This is called when a track for a given type is selected. 2299b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * 2306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 23110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the selected track. The type can be 23210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or 23310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_SUBTITLE}. 23410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param trackId The ID of the selected track. When {@code null} the currently selected 23510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * track for a given type should be unselected. 236d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo */ 23710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTrackSelected(Session session, int type, String trackId) { 238d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 239d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 240d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo /** 2416320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * This is invoked when the video size has been changed. It is also called when the first 2426320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * time video size information becomes available after the session is tuned to a specific 2436320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * channel. 2446320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * 2456320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2466320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param width The width of the video. 2476320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param height The height of the video. 2486320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 2496320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo public void onVideoSizeChanged(Session session, int width, int height) { 2506320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 2516320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 2526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 253d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * This is called when the video is available, so the TV input starts the playback. 254d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * 255d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 2569b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 2579b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoAvailable(Session session) { 2589b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 2599b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 2609b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 2619b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * This is called when the video is not available, so the TV input stops the playback. 2629b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * 2639b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback 2649b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * @param reason The reason why the TV input stopped the playback: 2659b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <ul> 2669b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN} 2676e62a1508cb7a5efcdde2ae9e51672fea4296dcaJae Seo * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING} 2689b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL} 2699b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING} 2709b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * </ul> 2719b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 2729b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoUnavailable(Session session, int reason) { 2739b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 2749b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 2759b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 276bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * This is called when the current program content turns out to be allowed to watch since 277bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * its content rating is not blocked by parental controls. 278bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * 279bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback 280bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo */ 281bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void onContentAllowed(Session session) { 282bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 283bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 284bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo /** 285bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * This is called when the current program content turns out to be not allowed to watch 286bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * since its content rating is blocked by parental controls. 2876057102dbb746593a7d59cf377c969b62e38c664Jae Seo * 2886057102dbb746593a7d59cf377c969b62e38c664Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback 2896057102dbb746593a7d59cf377c969b62e38c664Jae Seo * @param rating The content ration of the blocked program. 2906057102dbb746593a7d59cf377c969b62e38c664Jae Seo */ 2916057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void onContentBlocked(Session session, TvContentRating rating) { 2926057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 2936057102dbb746593a7d59cf377c969b62e38c664Jae Seo 2946057102dbb746593a7d59cf377c969b62e38c664Jae Seo /** 2955b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * This is called when {@link TvInputService.Session#layoutSurface} is called to change the 2965b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * layout of surface. 297ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho * 298ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho * @param session A {@link TvInputManager.Session} associated with this callback 2995b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param left Left position. 3005b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param top Top position. 3015b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param right Right position. 3025b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param bottom Bottom position. 303ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho * @hide 304ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho */ 305ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @SystemApi 306ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void onLayoutSurface(Session session, int left, int top, int right, int bottom) { 307ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 308ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 309ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho /** 310832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * This is called when a custom event has been sent from this session. 311832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * 312832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param session A {@link TvInputManager.Session} associated with this callback 313832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param eventType The type of the event. 314832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param eventArgs Optional arguments of the event. 315832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @hide 316832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho */ 31715bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 318832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void onSessionEvent(Session session, String eventType, Bundle eventArgs) { 319832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 3203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 3213957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3222b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private static final class SessionCallbackRecord { 3232b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SessionCallback mSessionCallback; 3243957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final Handler mHandler; 3252b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private Session mSession; 3263957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo SessionCallbackRecord(SessionCallback sessionCallback, 3283957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Handler handler) { 3292b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback = sessionCallback; 3303957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler = handler; 3313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 3323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionCreated(final Session session) { 3342b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSession = session; 3353957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler.post(new Runnable() { 3363957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 3373957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void run() { 3382b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback.onSessionCreated(session); 3392b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 3402b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim }); 3412b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 3422b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 3436320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionReleased() { 3442b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mHandler.post(new Runnable() { 3452b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim @Override 3462b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void run() { 3472b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback.onSessionReleased(mSession); 3483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 3493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }); 3503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 351832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 3526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postChannelRetuned(final Uri channelUri) { 353832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mHandler.post(new Runnable() { 354832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 355832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void run() { 3561f213914c45c23c653f721690da2ce0718e63139Dongwon Kang mSessionCallback.onChannelRetuned(mSession, channelUri); 357832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 358832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho }); 359832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 360832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 3616320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postTracksChanged(final List<TvTrackInfo> tracks) { 362b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang mHandler.post(new Runnable() { 363b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang @Override 364b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang public void run() { 36510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mSessionCallback.onTracksChanged(mSession, tracks); 366b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 367b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang }); 368b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 369b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 3706320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postTrackSelected(final int type, final String trackId) { 371d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo mHandler.post(new Runnable() { 372d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo @Override 373d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo public void run() { 37410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mSessionCallback.onTrackSelected(mSession, type, trackId); 375d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 376d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo }); 377d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 378d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 3796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoSizeChanged(final int width, final int height) { 3806320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mHandler.post(new Runnable() { 3816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo @Override 3826320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo public void run() { 3836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSessionCallback.onVideoSizeChanged(mSession, width, height); 3846320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 3856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo }); 3866320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 3876320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 3886320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoAvailable() { 3899b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mHandler.post(new Runnable() { 3909b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 3919b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void run() { 3929b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mSessionCallback.onVideoAvailable(mSession); 3939b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 3949b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang }); 3959b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 3969b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 3976320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoUnavailable(final int reason) { 3989b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mHandler.post(new Runnable() { 3999b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 4009b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void run() { 4019b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mSessionCallback.onVideoUnavailable(mSession, reason); 4029b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4039b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang }); 4049b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4059b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 4066320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postContentAllowed() { 407bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo mHandler.post(new Runnable() { 408bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo @Override 409bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void run() { 410bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo mSessionCallback.onContentAllowed(mSession); 411bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 412bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo }); 413bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 414bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 4156320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postContentBlocked(final TvContentRating rating) { 4166057102dbb746593a7d59cf377c969b62e38c664Jae Seo mHandler.post(new Runnable() { 4176057102dbb746593a7d59cf377c969b62e38c664Jae Seo @Override 4186057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void run() { 4196057102dbb746593a7d59cf377c969b62e38c664Jae Seo mSessionCallback.onContentBlocked(mSession, rating); 4206057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 4216057102dbb746593a7d59cf377c969b62e38c664Jae Seo }); 4226057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 4236057102dbb746593a7d59cf377c969b62e38c664Jae Seo 4246320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postLayoutSurface(final int left, final int top, final int right, 425ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho final int bottom) { 426ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho mHandler.post(new Runnable() { 427ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @Override 428ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void run() { 429ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho mSessionCallback.onLayoutSurface(mSession, left, top, right, bottom); 430ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 431ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho }); 432ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 433ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 4346320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionEvent(final String eventType, final Bundle eventArgs) { 435832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mHandler.post(new Runnable() { 436832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 437832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void run() { 438832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mSessionCallback.onSessionEvent(mSession, eventType, eventArgs); 439832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 440832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho }); 441832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 4423957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 4433957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 4443957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 4452778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Callback used to monitor status of the TV input. 4463957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 4472778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public abstract static class TvInputCallback { 4483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 449969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * This is called when the state of a given TV input is changed. 4503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 4518e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 4528e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param state State of the TV input. The value is one of the following: 453969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <ul> 454969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_CONNECTED} 455969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_CONNECTED_STANDBY} 456969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_DISCONNECTED} 457969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </ul> 4583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 459969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public void onInputStateChanged(String inputId, int state) { 4603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 4618e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 4628e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim /** 4638e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * This is called when a TV input is added. 4648e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * 4658e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 4668e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim */ 4678e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputAdded(String inputId) { 4688e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 4698e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 4708e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim /** 4718e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * This is called when a TV input is removed. 4728e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * 4738e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 4748e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim */ 4758e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputRemoved(String inputId) { 4768e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 47719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 47819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee /** 47919ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * This is called when a TV input is updated. The update of TV input happens when it is 48019ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * reinstalled or the media on which the newer version of TV input exists is 48119ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * available/unavailable. 48219ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * 48319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * @param inputId The id of the TV input. 48419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * @hide 48519ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee */ 48619ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @SystemApi 48719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void onInputUpdated(String inputId) { 48819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 4893957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 4903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 4912778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private static final class TvInputCallbackRecord { 4922778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private final TvInputCallback mCallback; 4933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final Handler mHandler; 4943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 4952778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public TvInputCallbackRecord(TvInputCallback callback, Handler handler) { 4962778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback = callback; 4973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler = handler; 4983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 4993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5002778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public TvInputCallback getCallback() { 5012778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo return mCallback; 5028e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5038e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 5048e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void postInputStateChanged(final String inputId, final int state) { 5058e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mHandler.post(new Runnable() { 5068e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 5078e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void run() { 5082778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback.onInputStateChanged(inputId, state); 5098e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5108e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim }); 5118e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5128e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 5138e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void postInputAdded(final String inputId) { 5148e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mHandler.post(new Runnable() { 5158e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 5168e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void run() { 5172778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback.onInputAdded(inputId); 5188e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 5198e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim }); 5203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5213957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5228e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void postInputRemoved(final String inputId) { 5233957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler.post(new Runnable() { 5243957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 5253957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void run() { 5262778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback.onInputRemoved(inputId); 5273957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5283957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }); 5293957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 53019ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 53119ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void postInputUpdated(final String inputId) { 53219ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee mHandler.post(new Runnable() { 53319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @Override 53419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void run() { 535db8f7ab752de641b147015a2b4a134913fbcb594Youngsang Cho mCallback.onInputUpdated(inputId); 53619ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 53719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee }); 53819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 5393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5403957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5413957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 542d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Interface used to receive events from Hardware objects. 543d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 544d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 545d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 546d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract static class HardwareCallback { 547d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract void onReleased(); 548d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract void onStreamConfigChanged(TvStreamConfig[] configs); 549d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 550d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 551d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 5523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @hide 5533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 5543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public TvInputManager(ITvInputManager service, int userId) { 5553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService = service; 5563957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mUserId = userId; 5573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mClient = new ITvInputClient.Stub() { 5583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 559d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim public void onSessionCreated(String inputId, IBinder token, InputChannel channel, 5606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int seq) { 5612b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 5622b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 5633957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (record == null) { 5643957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Log.e(TAG, "Callback not found for " + token); 5653957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo return; 5663957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5673957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Session session = null; 5683957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (token != null) { 5692b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim session = new Session(token, channel, mService, mUserId, seq, 5702b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap); 5713957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5723957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo record.postSessionCreated(session); 5733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5743957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 5772b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionReleased(int seq) { 5782b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 5792b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 5802b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.delete(seq); 5812b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (record == null) { 5822b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim Log.e(TAG, "Callback not found for seq:" + seq); 5832b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim return; 5842b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 5852b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim record.mSession.releaseInternal(); 5862b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim record.postSessionReleased(); 5872b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 5882b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 5892b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 5902b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim @Override 5911f213914c45c23c653f721690da2ce0718e63139Dongwon Kang public void onChannelRetuned(Uri channelUri, int seq) { 592a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang synchronized (mSessionCallbackRecordMap) { 593a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 594a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang if (record == null) { 595a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 596a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang return; 597a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 5981f213914c45c23c653f721690da2ce0718e63139Dongwon Kang record.postChannelRetuned(channelUri); 599a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 600a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 601a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang 602a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang @Override 60310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTracksChanged(List<TvTrackInfo> tracks, int seq) { 604832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho synchronized (mSessionCallbackRecordMap) { 605832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 606832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho if (record == null) { 607832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho Log.e(TAG, "Callback not found for seq " + seq); 608832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho return; 609832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 6106320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (record.mSession.updateTracks(tracks)) { 6116320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postTracksChanged(tracks); 6126320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo postVideoSizeChangedIfNeededLocked(record); 6136320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 614b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 615b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 616b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 617b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang @Override 61810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTrackSelected(int type, String trackId, int seq) { 619d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo synchronized (mSessionCallbackRecordMap) { 620d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 621d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo if (record == null) { 622d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 623d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo return; 624d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 6256320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (record.mSession.updateTrackSelection(type, trackId)) { 6266320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postTrackSelected(type, trackId); 6276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo postVideoSizeChangedIfNeededLocked(record); 6286320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6296320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6316320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 6326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private void postVideoSizeChangedIfNeededLocked(SessionCallbackRecord record) { 6336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo TvTrackInfo track = record.mSession.getVideoTrackToNotify(); 6346320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track != null) { 6356320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postVideoSizeChanged(track.getVideoWidth(), track.getVideoHeight()); 636d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 637d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 638d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 639d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo @Override 6409b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoAvailable(int seq) { 6419b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang synchronized (mSessionCallbackRecordMap) { 6429b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 6439b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang if (record == null) { 6449b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 6459b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang return; 6469b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6479b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang record.postVideoAvailable(); 6489b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6499b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6509b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 6519b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 6529b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoUnavailable(int reason, int seq) { 6539b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang synchronized (mSessionCallbackRecordMap) { 6549b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 6559b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang if (record == null) { 6569b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 6579b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang return; 6589b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6599b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang record.postVideoUnavailable(reason); 6609b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6619b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6629b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 6639b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 664bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void onContentAllowed(int seq) { 665bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo synchronized (mSessionCallbackRecordMap) { 666bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 667bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo if (record == null) { 668bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 669bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo return; 670bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 671bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo record.postContentAllowed(); 672bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 673bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 674bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 675bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo @Override 6766057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void onContentBlocked(String rating, int seq) { 6776057102dbb746593a7d59cf377c969b62e38c664Jae Seo synchronized (mSessionCallbackRecordMap) { 6786057102dbb746593a7d59cf377c969b62e38c664Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 6796057102dbb746593a7d59cf377c969b62e38c664Jae Seo if (record == null) { 6806057102dbb746593a7d59cf377c969b62e38c664Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 6816057102dbb746593a7d59cf377c969b62e38c664Jae Seo return; 6826057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6836057102dbb746593a7d59cf377c969b62e38c664Jae Seo record.postContentBlocked(TvContentRating.unflattenFromString(rating)); 6846057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6856057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6866057102dbb746593a7d59cf377c969b62e38c664Jae Seo 6876057102dbb746593a7d59cf377c969b62e38c664Jae Seo @Override 688ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void onLayoutSurface(int left, int top, int right, int bottom, int seq) { 689ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho synchronized (mSessionCallbackRecordMap) { 690ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 691ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho if (record == null) { 692ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho Log.e(TAG, "Callback not found for seq " + seq); 693ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho return; 694ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 695ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho record.postLayoutSurface(left, top, right, bottom); 696ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 697ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 698ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 699ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @Override 700832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void onSessionEvent(String eventType, Bundle eventArgs, int seq) { 701832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho synchronized (mSessionCallbackRecordMap) { 702832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 703832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho if (record == null) { 704832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho Log.e(TAG, "Callback not found for seq " + seq); 705832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho return; 706832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 707832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho record.postSessionEvent(eventType, eventArgs); 708832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 709832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 710969167dc05a6485a32d160895871cff46fd81884Wonsik Kim }; 7112778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mManagerCallback = new ITvInputManagerCallback.Stub() { 712832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 713969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public void onInputStateChanged(String inputId, int state) { 714969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 715969167dc05a6485a32d160895871cff46fd81884Wonsik Kim mStateMap.put(inputId, state); 7162778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 7178e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputStateChanged(inputId, state); 7188e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7198e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7208e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7218e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 7228e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 7238e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputAdded(String inputId) { 7248e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim synchronized (mLock) { 7258e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mStateMap.put(inputId, INPUT_STATE_CONNECTED); 7262778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 7278e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputAdded(inputId); 7288e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7298e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7308e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7318e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 7328e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 7338e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputRemoved(String inputId) { 7348e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim synchronized (mLock) { 7358e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mStateMap.remove(inputId); 7362778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 7378e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputRemoved(inputId); 7383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7403957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 74119ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 74219ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @Override 74319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void onInputUpdated(String inputId) { 74419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee synchronized (mLock) { 745db8f7ab752de641b147015a2b4a134913fbcb594Youngsang Cho for (TvInputCallbackRecord record : mCallbackRecords) { 74619ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee record.postInputUpdated(inputId); 74719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 74819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 74919ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 7503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }; 751969167dc05a6485a32d160895871cff46fd81884Wonsik Kim try { 7529127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo if (mService != null) { 7539127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo mService.registerCallback(mManagerCallback, mUserId); 7549127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo } 755969167dc05a6485a32d160895871cff46fd81884Wonsik Kim } catch (RemoteException e) { 756969167dc05a6485a32d160895871cff46fd81884Wonsik Kim Log.e(TAG, "mService.registerCallback failed: " + e); 757969167dc05a6485a32d160895871cff46fd81884Wonsik Kim } 7583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 7603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 7613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Returns the complete list of TV inputs on the system. 7623957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 7633957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @return List of {@link TvInputInfo} for each TV input that describes its meta information. 7643957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 7653957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public List<TvInputInfo> getTvInputList() { 7663957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 7673957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo return mService.getTvInputList(mUserId); 7683957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 7693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 7703957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7713957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7723957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 7733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 774b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * Returns the {@link TvInputInfo} for a given TV input. 775b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * 776b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * @param inputId The ID of the TV input. 777b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * @return the {@link TvInputInfo} for a given TV input. {@code null} if not found. 778b375805f3b1672e68d1511565af4700e5fa8491dJae Seo */ 779b375805f3b1672e68d1511565af4700e5fa8491dJae Seo public TvInputInfo getTvInputInfo(String inputId) { 780783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (inputId == null) { 781783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("inputId cannot be null"); 782783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 783b375805f3b1672e68d1511565af4700e5fa8491dJae Seo try { 784b375805f3b1672e68d1511565af4700e5fa8491dJae Seo return mService.getTvInputInfo(inputId, mUserId); 785b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } catch (RemoteException e) { 786b375805f3b1672e68d1511565af4700e5fa8491dJae Seo throw new RuntimeException(e); 787b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } 788b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } 789b375805f3b1672e68d1511565af4700e5fa8491dJae Seo 790b375805f3b1672e68d1511565af4700e5fa8491dJae Seo /** 7916320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns the state of a given TV input. It returns one of the following: 792969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <ul> 793969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_CONNECTED} 794969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_CONNECTED_STANDBY} 795969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_DISCONNECTED} 796969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </ul> 7973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 7988e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 799969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * @throws IllegalArgumentException if the argument is {@code null} or if there is no 800969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * {@link TvInputInfo} corresponding to {@code inputId}. 8013957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 802969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public int getInputState(String inputId) { 803d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim if (inputId == null) { 804783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("inputId cannot be null"); 8053957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 806969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 807969167dc05a6485a32d160895871cff46fd81884Wonsik Kim Integer state = mStateMap.get(inputId); 808969167dc05a6485a32d160895871cff46fd81884Wonsik Kim if (state == null) { 809969167dc05a6485a32d160895871cff46fd81884Wonsik Kim throw new IllegalArgumentException("Unrecognized input ID: " + inputId); 8103957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 811969167dc05a6485a32d160895871cff46fd81884Wonsik Kim return state.intValue(); 8123957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8133957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8143957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8153957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 8162778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Registers a {@link TvInputCallback}. 8173957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 8182778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * @param callback A callback used to monitor status of the TV inputs. 8198e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the status change will be delivered to. 8203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if any of the arguments is {@code null}. 8213957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 8222778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public void registerCallback(TvInputCallback callback, Handler handler) { 8232778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo if (callback == null) { 8248e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim throw new IllegalArgumentException("callback cannot be null"); 8253957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8263957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (handler == null) { 8273957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("handler cannot be null"); 8283957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 829969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 8302778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallbackRecords.add(new TvInputCallbackRecord(callback, handler)); 8313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8333957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8343957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 8352778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Unregisters the existing {@link TvInputCallback}. 8363957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 8372778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * @param callback The existing callback to remove. 8383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if any of the arguments is {@code null}. 8393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 8402778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public void unregisterCallback(final TvInputCallback callback) { 8412778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo if (callback == null) { 8428e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim throw new IllegalArgumentException("callback cannot be null"); 8433957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 844969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 8452778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (Iterator<TvInputCallbackRecord> it = mCallbackRecords.iterator(); 846969167dc05a6485a32d160895871cff46fd81884Wonsik Kim it.hasNext(); ) { 8472778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo TvInputCallbackRecord record = it.next(); 8482778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo if (record.getCallback() == callback) { 8493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo it.remove(); 850969167dc05a6485a32d160895871cff46fd81884Wonsik Kim break; 8513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8563957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 857783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Returns the user's parental controls enabled state. 858783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 859783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return {@code true} if the user enabled the parental controls, {@code false} otherwise. 860783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 861783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public boolean isParentalControlsEnabled() { 862783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 863783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return mService.isParentalControlsEnabled(mUserId); 864783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 865783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 866783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 867783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 868783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 869783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 870783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Sets the user's parental controls enabled state. 871783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 872783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param enabled The user's parental controls enabled state. {@code true} if the user enabled 873783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * the parental controls, {@code false} otherwise. 874783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isParentalControlsEnabled 875783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 876783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 877783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 878783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public void setParentalControlsEnabled(boolean enabled) { 879783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 880783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.setParentalControlsEnabled(enabled, mUserId); 881783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 882783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 883783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 884783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 885783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 886783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 887783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Checks whether a given TV content rating is blocked by the user. 888783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 889783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The TV content rating to check. 890783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return {@code true} if the given TV content rating is blocked, {@code false} otherwise. 891783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 892783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public boolean isRatingBlocked(TvContentRating rating) { 893783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (rating == null) { 894783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("rating cannot be null"); 895783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 896783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 897783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return mService.isRatingBlocked(rating.flattenToString(), mUserId); 898783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 899783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 900783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 901783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 902783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 903783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 904783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Returns the list of blocked content ratings. 905783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 906783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return the list of content ratings blocked by the user. 907783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 908783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 909783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 910783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public List<TvContentRating> getBlockedRatings() { 911783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 912783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo List<TvContentRating> ratings = new ArrayList<TvContentRating>(); 913783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo for (String rating : mService.getBlockedRatings(mUserId)) { 914783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo ratings.add(TvContentRating.unflattenFromString(rating)); 915783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 916783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return ratings; 917783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 918783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 919783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 920783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 921783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 922783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 923783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Adds a user blocked content rating. 924783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 925783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The content rating to block. 926783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isRatingBlocked 927783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #removeBlockedRating 928783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 929783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 930783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 931783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public void addBlockedRating(TvContentRating rating) { 932783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (rating == null) { 933783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("rating cannot be null"); 934783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 935783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 936783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.addBlockedRating(rating.flattenToString(), mUserId); 937783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 938783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 939783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 940783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 941783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 942783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 943783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Removes a user blocked content rating. 944783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 945783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The content rating to unblock. 946783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isRatingBlocked 947783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #addBlockedRating 948783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 949783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 950783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 951783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public void removeBlockedRating(TvContentRating rating) { 952783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo if (rating == null) { 953783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new IllegalArgumentException("rating cannot be null"); 954783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 955783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 956783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.removeBlockedRating(rating.flattenToString(), mUserId); 957783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 958783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo throw new RuntimeException(e); 959783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 960783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 961783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 962783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 9639c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Returns the list of all TV content rating systems defined. 9645c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim * @hide 9655c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim */ 9665c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim @SystemApi 9679c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public List<TvContentRatingSystemInfo> getTvContentRatingSystemList() { 9685c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim try { 9699c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo return mService.getTvContentRatingSystemList(mUserId); 9705c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } catch (RemoteException e) { 9715c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim throw new RuntimeException(e); 9725c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } 9735c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } 9745c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim 9755c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim /** 976674e96216d6a60f0d87d3a6a0d62f358a101532bYoungsang Cho * Creates a {@link Session} for a given TV input. 9773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * <p> 9783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * The number of sessions that can be created at the same time is limited by the capability of 9793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * the given TV input. 9803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * </p> 9813957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 9828e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param inputId The id of the TV input. 9838e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param callback A callback used to receive the created session. 9848e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the session creation will be delivered to. 9853957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if any of the arguments is {@code null}. 986b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 9873957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 98815bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 9892b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void createSession(String inputId, final SessionCallback callback, 9903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Handler handler) { 991d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim if (inputId == null) { 992d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim throw new IllegalArgumentException("id cannot be null"); 9933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 9943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (callback == null) { 9953957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("callback cannot be null"); 9963957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 9973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (handler == null) { 9983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("handler cannot be null"); 9993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10002b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = new SessionCallbackRecord(callback, handler); 10012b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 10023957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo int seq = mNextSeq++; 10032b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.put(seq, record); 10043957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 1005d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim mService.createSession(mClient, inputId, seq, mUserId); 10063957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 10073957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 10083957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10093957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10103957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 10113957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1012b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo /** 1013c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * Returns the TvStreamConfig list of the given TV input. 1014c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * 101590e733385d466acd87730676c83c080a17ff495fWonsik Kim * If you are using {@link Hardware} object from {@link 101690e733385d466acd87730676c83c080a17ff495fWonsik Kim * #acquireTvInputHardware}, you should get the list of available streams 101790e733385d466acd87730676c83c080a17ff495fWonsik Kim * from {@link HardwareCallback#onStreamConfigChanged} method, not from 101890e733385d466acd87730676c83c080a17ff495fWonsik Kim * here. This method is designed to be used with {@link #captureFrame} in 101990e733385d466acd87730676c83c080a17ff495fWonsik Kim * capture scenarios specifically and not suitable for any other use. 102090e733385d466acd87730676c83c080a17ff495fWonsik Kim * 1021c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param inputId the id of the TV input. 1022c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @return List of {@link TvStreamConfig} which is available for capturing 1023c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * of the given TV input. 1024c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @hide 1025c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo */ 1026c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo @SystemApi 1027c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId) { 1028c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo try { 1029c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo return mService.getAvailableTvStreamConfigList(inputId, mUserId); 1030c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } catch (RemoteException e) { 1031c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo throw new RuntimeException(e); 1032c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1033c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1034c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo 1035c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo /** 1036c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * Take a snapshot of the given TV input into the provided Surface. 1037c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * 1038c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param inputId the id of the TV input. 1039c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param surface the {@link Surface} to which the snapshot is captured. 1040c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param config the {@link TvStreamConfig} which is used for capturing. 1041c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @return true when the {@link Surface} is ready to be captured. 1042c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @hide 1043c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo */ 1044c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo @SystemApi 1045c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo public boolean captureFrame(String inputId, Surface surface, TvStreamConfig config) { 1046c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo try { 1047c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo return mService.captureFrame(inputId, surface, config, mUserId); 1048c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } catch (RemoteException e) { 1049c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo throw new RuntimeException(e); 1050df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } 1051df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } 1052df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo 1053df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo /** 1054df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * Returns true if there is only a single TV input session. 1055df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * 1056df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * @hide 1057df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo */ 1058df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo @SystemApi 1059df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo public boolean isSingleSessionActive() { 1060df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo try { 1061df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo return mService.isSingleSessionActive(mUserId); 1062df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } catch (RemoteException e) { 1063df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo throw new RuntimeException(e); 1064c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1065c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1066c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo 1067c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo /** 1068d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Returns a list of TvInputHardwareInfo objects representing available hardware. 1069d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1070d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1071d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1072d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1073d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public List<TvInputHardwareInfo> getHardwareList() { 1074d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1075d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mService.getHardwareList(); 1076d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1077d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1078d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1079d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1080d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1081d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1082d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Returns acquired TvInputManager.Hardware object for given deviceId. 1083d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1084d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * If there are other Hardware object acquired for the same deviceId, calling this method will 1085d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * preempt the previously acquired object and report {@link HardwareCallback#onReleased} to the 1086d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * old object. 1087d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1088d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1089d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1090d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1091d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public Hardware acquireTvInputHardware(int deviceId, final HardwareCallback callback, 1092d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim TvInputInfo info) { 1093d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1094d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return new Hardware( 1095d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mService.acquireTvInputHardware(deviceId, new ITvInputHardwareCallback.Stub() { 1096d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @Override 1097d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void onReleased() { 1098d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim callback.onReleased(); 1099d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1100d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1101d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @Override 1102d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void onStreamConfigChanged(TvStreamConfig[] configs) { 1103d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim callback.onStreamConfigChanged(configs); 1104d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1105d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim }, info, mUserId)); 1106d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1107d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1108d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1109d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1110d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1111d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1112d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Releases previously acquired hardware object. 1113d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1114d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1115d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1116d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1117d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void releaseTvInputHardware(int deviceId, Hardware hardware) { 1118d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1119d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mService.releaseTvInputHardware(deviceId, hardware.getInterface(), mUserId); 1120d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1121d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1122d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1123d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1124d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1125d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1126b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * The Session provides the per-session functionality of TV inputs. 1127b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 1128b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo */ 112915bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 11303957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public static final class Session { 11316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_IN_PROGRESS = -1; 11326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_NOT_HANDLED = 0; 11336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_HANDLED = 1; 11346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private static final long INPUT_SESSION_NOT_RESPONDING_TIMEOUT = 2500; 11366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11373957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputManager mService; 11383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final int mUserId; 11392b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final int mSeq; 11406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // For scheduling input event handling on the main thread. This also serves as a lock to 11426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // protect pending input events and the input channel. 11436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final InputEventHandler mHandler = new InputEventHandler(Looper.getMainLooper()); 11446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final Pool<PendingEvent> mPendingEventPool = new SimplePool<PendingEvent>(20); 11466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final SparseArray<PendingEvent> mPendingEvents = new SparseArray<PendingEvent>(20); 11472b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap; 11486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11499a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho private IBinder mToken; 11506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private TvInputEventSender mSender; 11516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private InputChannel mChannel; 11526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 11536320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private final Object mTrackLock = new Object(); 11546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 115510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private final List<TvTrackInfo> mAudioTracks = new ArrayList<TvTrackInfo>(); 11566320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 115710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private final List<TvTrackInfo> mVideoTracks = new ArrayList<TvTrackInfo>(); 11586320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 115910d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<TvTrackInfo>(); 11606320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 116110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedAudioTrackId; 11626320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 116310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedVideoTrackId; 11646320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 116510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedSubtitleTrackId; 11666320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 11676320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private int mVideoWidth; 11686320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mTrackLock") 11696320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private int mVideoHeight; 11703957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 11712b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId, 11722b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) { 11733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mToken = token; 11746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mChannel = channel; 11753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService = service; 11763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mUserId = userId; 11772b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSeq = seq; 11782b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap = sessionCallbackRecordMap; 11793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 11813957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 11823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Releases this session. 11833957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 11843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void release() { 11859a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1186dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1187dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 11889a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 11893957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 11903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.releaseSession(mToken, mUserId); 11913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 11923957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 11933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11946a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 11952b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim releaseInternal(); 11963957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 11983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 119915c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * Sets this as the main session. The main session is a session whose corresponding TV 120015c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * input determines the HDMI-CEC active source device. 120115c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * 120215c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * @see TvView#setMain 12034c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee */ 120415c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee void setMain() { 12054c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee if (mToken == null) { 12064c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee Log.w(TAG, "The session has been already released"); 12074c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee return; 12084c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 12094c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee try { 12104c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee mService.setMainSession(mToken, mUserId); 12114c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } catch (RemoteException e) { 12124c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee throw new RuntimeException(e); 12134c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 12144c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 12154c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee 12164c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee /** 12173957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Sets the {@link android.view.Surface} for this session. 12183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 12193957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param surface A {@link android.view.Surface} used to render video. 12203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1221f1c025cbcd98f2366d384c5aac114c330090a645Wonsik Kim public void setSurface(Surface surface) { 12229a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1223dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1224dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 12259a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 12263957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo // surface can be null. 12273957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 12283957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.setSurface(mToken, surface, mUserId); 12293957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 12303957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 12313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12333957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12343957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1235e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * Notifies of any structural changes (format or size) of the {@link Surface} 1236e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * passed by {@link #setSurface}. 1237e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * 1238e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @param format The new PixelFormat of the {@link Surface}. 1239e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @param width The new width of the {@link Surface}. 1240e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @param height The new height of the {@link Surface}. 1241e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * @hide 1242e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho */ 124315bbf3b220fdd22df62f2bfa04452f4cdf11d2bbJae Seo @SystemApi 1244e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho public void dispatchSurfaceChanged(int format, int width, int height) { 1245e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho if (mToken == null) { 1246e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho Log.w(TAG, "The session has been already released"); 1247e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho return; 1248e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1249e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho try { 1250e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho mService.dispatchSurfaceChanged(mToken, format, width, height, mUserId); 1251e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } catch (RemoteException e) { 1252e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho throw new RuntimeException(e); 1253e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1254e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1255e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho 1256e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho /** 1257782f7345471072b630e58c7abd3579b0015273b1Jae Seo * Sets the relative stream volume of this session to handle a change of audio focus. 12583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 12593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param volume A volume value between 0.0f to 1.0f. 12603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if the volume value is out of range. 12613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1262782f7345471072b630e58c7abd3579b0015273b1Jae Seo public void setStreamVolume(float volume) { 12639a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1264dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1265dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 12669a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 12673957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 12683957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (volume < 0.0f || volume > 1.0f) { 12693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("volume should be between 0.0f and 1.0f"); 12703957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12713957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.setVolume(mToken, volume, mUserId); 12723957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 12733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 12743957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 12783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Tunes to a given channel. 12793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 12803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param channelUri The URI of a channel. 12813957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if the argument is {@code null}. 12823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 12833957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void tune(Uri channelUri) { 12841a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim tune(channelUri, null); 12851a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim } 12861a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim 12871a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim /** 12881a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * Tunes to a given channel. 12891a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * 12901a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @param channelUri The URI of a channel. 12911a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @param params A set of extra parameters which might be handled with this tune event. 12921a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @throws IllegalArgumentException if {@code channelUri} is {@code null}. 12931a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @hide 12941a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim */ 12951a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim @SystemApi 12961a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim public void tune(Uri channelUri, Bundle params) { 12973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (channelUri == null) { 12983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("channelUri cannot be null"); 12993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 13009a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1301dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1302dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 13039a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 13046320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 13056320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.clear(); 13066320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.clear(); 13076320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.clear(); 13086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedAudioTrackId = null; 13096320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedVideoTrackId = null; 13106320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedSubtitleTrackId = null; 13116320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoWidth = 0; 13126320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoHeight = 0; 13136320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13143957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 13151a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim mService.tune(mToken, channelUri, params, mUserId); 13163957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 13173957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new RuntimeException(e); 13183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 13193957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 13209a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 13219a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 13222c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * Enables or disables the caption for this session. 13232c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * 13242c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * @param enabled {@code true} to enable, {@code false} to disable. 13252c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo */ 13262c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo public void setCaptionEnabled(boolean enabled) { 13272c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo if (mToken == null) { 13282c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo Log.w(TAG, "The session has been already released"); 13292c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo return; 13302c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 13312c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo try { 13322c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo mService.setCaptionEnabled(mToken, enabled, mUserId); 13332c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } catch (RemoteException e) { 13342c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo throw new RuntimeException(e); 13352c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 13362c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 13372c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo 13382c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo /** 13391f81b1040f40a3233981f34268b11e5c9ad9f34cDongwon Kang * Selects a track. 13401f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * 134110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the track to select. The type can be 134210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or 134310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_SUBTITLE}. 134410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param trackId The ID of the track to select. When {@code null}, the currently selected 134510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * track of the given type will be unselected. 13465b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @see #getTracks 13471f213914c45c23c653f721690da2ce0718e63139Dongwon Kang */ 134810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void selectTrack(int type, String trackId) { 13496320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 13506320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 13516320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mAudioTracks, trackId)) { 13526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid audio trackId: " + trackId); 13536320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 13546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13556320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 13566320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mVideoTracks, trackId)) { 13576320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid video trackId: " + trackId); 13586320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 13596320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13606320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 13616320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mSubtitleTracks, trackId)) { 13626320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid subtitle trackId: " + trackId); 13636320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 13646320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 13656320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else { 13666320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo throw new IllegalArgumentException("invalid type: " + type); 136710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo } 13681f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 13691f213914c45c23c653f721690da2ce0718e63139Dongwon Kang if (mToken == null) { 13701f213914c45c23c653f721690da2ce0718e63139Dongwon Kang Log.w(TAG, "The session has been already released"); 13711f213914c45c23c653f721690da2ce0718e63139Dongwon Kang return; 13721f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 13731f213914c45c23c653f721690da2ce0718e63139Dongwon Kang try { 137410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mService.selectTrack(mToken, type, trackId, mUserId); 13751f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } catch (RemoteException e) { 13761f213914c45c23c653f721690da2ce0718e63139Dongwon Kang throw new RuntimeException(e); 13771f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 13781f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 13791f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 1380984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee private boolean containsTrack(List<TvTrackInfo> tracks, String trackId) { 1381984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee for (TvTrackInfo track : tracks) { 1382984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee if (track.getId().equals(trackId)) { 1383984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee return true; 1384984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1385984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1386984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee return false; 1387984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1388984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee 13891f213914c45c23c653f721690da2ce0718e63139Dongwon Kang /** 139010d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * Returns the list of tracks for a given type. Returns {@code null} if the information is 139110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * not available. 13921f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * 139310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO}, 139410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}. 139510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @return the list of tracks for the given type. 13961f213914c45c23c653f721690da2ce0718e63139Dongwon Kang */ 139710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public List<TvTrackInfo> getTracks(int type) { 13986320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 13996320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 14006320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mAudioTracks == null) { 14016320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 14026320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14036320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return new ArrayList<TvTrackInfo>(mAudioTracks); 14046320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 14056320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mVideoTracks == null) { 14066320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 14076320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return new ArrayList<TvTrackInfo>(mVideoTracks); 14096320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 14106320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mSubtitleTracks == null) { 14116320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 14126320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14136320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return new ArrayList<TvTrackInfo>(mSubtitleTracks); 141410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo } 14151f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 141610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo throw new IllegalArgumentException("invalid type: " + type); 14171f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 14181f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 1419d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo /** 142010d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * Returns the selected track for a given type. Returns {@code null} if the information is 142110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * not available or any of the tracks for the given type is not selected. 142210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * 142310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @return the ID of the selected track. 142410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @see #selectTrack 1425d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo */ 142610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public String getSelectedTrack(int type) { 14276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14286320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 14296320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedAudioTrackId; 14306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 14316320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedVideoTrackId; 14326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 14336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedSubtitleTrackId; 14346320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 1435d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 143610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo throw new IllegalArgumentException("invalid type: " + type); 14371f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 14381f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 14391f213914c45c23c653f721690da2ce0718e63139Dongwon Kang /** 14406320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Responds to onTracksChanged() and updates the internal track information. Returns true if 14416320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * there is an update. 14426320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 14436320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo boolean updateTracks(List<TvTrackInfo> tracks) { 14446320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14456320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.clear(); 14466320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.clear(); 14476320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.clear(); 14486320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo for (TvTrackInfo track : tracks) { 14496320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track.getType() == TvTrackInfo.TYPE_AUDIO) { 14506320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.add(track); 14516320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) { 14526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.add(track); 14536320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) { 14546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.add(track); 14556320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14566320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14576320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return !mAudioTracks.isEmpty() || !mVideoTracks.isEmpty() 14586320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo || !mSubtitleTracks.isEmpty(); 14596320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14606320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14616320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 14626320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 14636320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Responds to onTrackSelected() and updates the internal track selection information. 14646320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns true if there is an update. 14656320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 14666320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo boolean updateTrackSelection(int type, String trackId) { 14676320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14686320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO && trackId != mSelectedAudioTrackId) { 14696320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedAudioTrackId = trackId; 14706320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 14716320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO && trackId != mSelectedVideoTrackId) { 14726320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedVideoTrackId = trackId; 14736320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 14746320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE 14756320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo && trackId != mSelectedSubtitleTrackId) { 14766320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedSubtitleTrackId = trackId; 14776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 14786320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14806320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return false; 14816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 14826320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 14836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 14846320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns the new/updated video track that contains new video size information. Returns 14856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * null if there is no video track to notify. Subsequent calls of this method results in a 14866320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * non-null video track returned only by the first call and null returned by following 14876320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * calls. The caller should immediately notify of the video size change upon receiving the 14886320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * track. 14896320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 14906320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo TvTrackInfo getVideoTrackToNotify() { 14916320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo synchronized (mTrackLock) { 14926320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (!mVideoTracks.isEmpty() && mSelectedVideoTrackId != null) { 14936320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo for (TvTrackInfo track : mVideoTracks) { 14946320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track.getId().equals(mSelectedVideoTrackId)) { 14956320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo int videoWidth = track.getVideoWidth(); 14966320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo int videoHeight = track.getVideoHeight(); 14976320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mVideoWidth != videoWidth || mVideoHeight != videoHeight) { 14986320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoWidth = videoWidth; 14996320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoHeight = videoHeight; 15006320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return track; 15016320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15026320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15036320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15046320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15056320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15066320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 15076320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 15086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 15096320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 15101f81b1040f40a3233981f34268b11e5c9ad9f34cDongwon Kang * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle) 1511a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * TvInputService.Session.appPrivateCommand()} on the current TvView. 1512a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * 1513a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @param action Name of the command to be performed. This <em>must</em> be a scoped name, 1514a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * i.e. prefixed with a package name you own, so that different developers will 1515a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * not create conflicting commands. 1516a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @param data Any data to include with the command. 1517a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @hide 1518a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo */ 1519a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo @SystemApi 1520a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo public void sendAppPrivateCommand(String action, Bundle data) { 1521a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo if (mToken == null) { 1522a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo Log.w(TAG, "The session has been already released"); 1523a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo return; 1524a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 1525a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo try { 1526a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo mService.sendAppPrivateCommand(mToken, action, data, mUserId); 1527a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } catch (RemoteException e) { 1528a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo throw new RuntimeException(e); 1529a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 1530a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 1531a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo 1532a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo /** 15339a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Creates an overlay view. Once the overlay view is created, {@link #relayoutOverlayView} 15349a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * should be called whenever the layout of its containing view is changed. 15359a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * {@link #removeOverlayView()} should be called to remove the overlay view. 15369a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Since a session can have only one overlay view, this method should be called only once 15379a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * or it can be called again after calling {@link #removeOverlayView()}. 15389a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * 15399a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param view A view playing TV. 15409a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param frame A position of the overlay view. 15419a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @throws IllegalArgumentException if any of the arguments is {@code null}. 1542dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim * @throws IllegalStateException if {@code view} is not attached to a window. 15439a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 15449a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho void createOverlayView(View view, Rect frame) { 15459a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (view == null) { 15469a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalArgumentException("view cannot be null"); 15479a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15489a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (frame == null) { 15499a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalArgumentException("frame cannot be null"); 15509a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15519a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (view.getWindowToken() == null) { 15529a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalStateException("view must be attached to a window"); 15539a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15549a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1555dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1556dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 15579a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15589a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 15599a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.createOverlayView(mToken, view.getWindowToken(), frame, mUserId); 15609a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 15619a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new RuntimeException(e); 15629a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15639a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15649a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 15659a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 15669a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Relayouts the current overlay view. 15679a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * 15689a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param frame A new position of the overlay view. 15699a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @throws IllegalArgumentException if the arguments is {@code null}. 15709a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 15719a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho void relayoutOverlayView(Rect frame) { 15729a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (frame == null) { 15739a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalArgumentException("frame cannot be null"); 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.relayoutOverlayView(mToken, frame, mUserId); 15819a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 15829a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new RuntimeException(e); 15839a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15849a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15859a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 15869a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 15879a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Removes the current overlay view. 15889a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 15899a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho void removeOverlayView() { 15909a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1591dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1592dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 15939a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15949a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 15959a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.removeOverlayView(mToken, mUserId); 15969a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 15979a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new RuntimeException(e); 15989a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 15999a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 16006a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16016a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 16029bf671f8ee72b156f16fcf05a3d1c6e093ecba67Sungsoo Lim * Requests to unblock content blocked by parental controls. 1603903d6b72cd572665309633e925485464d08bb25aJaewan Kim */ 16049bf671f8ee72b156f16fcf05a3d1c6e093ecba67Sungsoo Lim void requestUnblockContent(TvContentRating unblockedRating) { 1605903d6b72cd572665309633e925485464d08bb25aJaewan Kim if (mToken == null) { 1606903d6b72cd572665309633e925485464d08bb25aJaewan Kim Log.w(TAG, "The session has been already released"); 1607903d6b72cd572665309633e925485464d08bb25aJaewan Kim return; 1608903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 1609a42be3c95021c5fb7e4ac0a8fbfc542f841f44ddJaewan Kim if (unblockedRating == null) { 1610a42be3c95021c5fb7e4ac0a8fbfc542f841f44ddJaewan Kim throw new IllegalArgumentException("unblockedRating cannot be null"); 1611a42be3c95021c5fb7e4ac0a8fbfc542f841f44ddJaewan Kim } 1612903d6b72cd572665309633e925485464d08bb25aJaewan Kim try { 16139bf671f8ee72b156f16fcf05a3d1c6e093ecba67Sungsoo Lim mService.requestUnblockContent(mToken, unblockedRating.flattenToString(), mUserId); 1614903d6b72cd572665309633e925485464d08bb25aJaewan Kim } catch (RemoteException e) { 1615903d6b72cd572665309633e925485464d08bb25aJaewan Kim throw new RuntimeException(e); 1616903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 1617903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 1618903d6b72cd572665309633e925485464d08bb25aJaewan Kim 1619903d6b72cd572665309633e925485464d08bb25aJaewan Kim /** 16206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Dispatches an input event to this session. 16216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 16228e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param event An {@link InputEvent} to dispatch. 16236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param token A token used to identify the input event later in the callback. 16246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param callback A callback used to receive the dispatch result. 16258e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the dispatch result will be delivered to. 16266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns 16276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns 16286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will 16296a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * be invoked later. 16306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @throws IllegalArgumentException if any of the necessary arguments is {@code null}. 16316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @hide 16326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 16336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public int dispatchInputEvent(InputEvent event, Object token, 16346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo FinishedInputEventCallback callback, Handler handler) { 16356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (event == null) { 16366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo throw new IllegalArgumentException("event cannot be null"); 16376a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (callback != null && handler == null) { 16396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo throw new IllegalArgumentException("handler cannot be null"); 16406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 16426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mChannel == null) { 16436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_NOT_HANDLED; 16446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo PendingEvent p = obtainPendingEventLocked(event, token, callback, handler); 16466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (Looper.myLooper() == Looper.getMainLooper()) { 16476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Already running on the main thread so we can send the event immediately. 16486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return sendInputEventOnMainLooperLocked(p); 16496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Post the event to the main thread. 16526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_SEND_INPUT_EVENT, p); 16536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 16546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.sendMessage(msg); 16556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_IN_PROGRESS; 16566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16586a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 16606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Callback that is invoked when an input event that was dispatched to this session has been 16616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * finished. 16626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 16636a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @hide 16646a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 16656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public interface FinishedInputEventCallback { 16666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 16676a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Called when the dispatched input event is finished. 16686a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 16698e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param token A token passed to {@link #dispatchInputEvent}. 16706a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param handled {@code true} if the dispatched input event was handled properly. 16716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@code false} otherwise. 16726a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 16736a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void onFinishedInputEvent(Object token, boolean handled); 16746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16756a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16766a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Must be called on the main looper 16776a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void sendInputEventAndReportResultOnMainLooper(PendingEvent p) { 16786a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 16796a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int result = sendInputEventOnMainLooperLocked(p); 16806a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (result == DISPATCH_IN_PROGRESS) { 16816a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 16826a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16836a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16846a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16856a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo invokeFinishedInputEventCallback(p, false); 16866a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16876a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16886a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private int sendInputEventOnMainLooperLocked(PendingEvent p) { 16896a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mChannel != null) { 16906a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mSender == null) { 16916a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mSender = new TvInputEventSender(mChannel, mHandler.getLooper()); 16926a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 16936a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 16946a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final InputEvent event = p.mEvent; 16956a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final int seq = event.getSequenceNumber(); 16966a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mSender.sendInputEvent(seq, event)) { 16976a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEvents.put(seq, p); 16986a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p); 16996a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 17006a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.sendMessageDelayed(msg, INPUT_SESSION_NOT_RESPONDING_TIMEOUT); 17016a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_IN_PROGRESS; 17026a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17036a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17046a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Log.w(TAG, "Unable to send input event to session: " + mToken + " dropping:" 17056a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo + event); 17066a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17076a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_NOT_HANDLED; 17086a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17096a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17106a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo void finishedInputEvent(int seq, boolean handled, boolean timeout) { 17116a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final PendingEvent p; 17126a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 17136a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int index = mPendingEvents.indexOfKey(seq); 17146a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (index < 0) { 17156a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; // spurious, event already finished or timed out 17166a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17176a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17186a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p = mPendingEvents.valueAt(index); 17196a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEvents.removeAt(index); 17206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (timeout) { 17226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Log.w(TAG, "Timeout waiting for seesion to handle input event after " 17236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo + INPUT_SESSION_NOT_RESPONDING_TIMEOUT + " ms: " + mToken); 17246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } else { 17256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.removeMessages(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p); 17266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17296a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo invokeFinishedInputEventCallback(p, handled); 17306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Assumes the event has already been removed from the queue. 17336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) { 17346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mHandled = handled; 17355b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo if (p.mEventHandler.getLooper().isCurrentThread()) { 17366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Already running on the callback handler thread so we can send the callback 17376a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // immediately. 17386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.run(); 17396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } else { 17406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Post the event to the callback handler thread. 17416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // In this case, the callback will be responsible for recycling the event. 17425b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo Message msg = Message.obtain(p.mEventHandler, p); 17436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 17446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.sendToTarget(); 17456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void flushPendingEventsLocked() { 17496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.removeMessages(InputEventHandler.MSG_FLUSH_INPUT_EVENT); 17506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final int count = mPendingEvents.size(); 17526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo for (int i = 0; i < count; i++) { 17536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int seq = mPendingEvents.keyAt(i); 17546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_FLUSH_INPUT_EVENT, seq, 0); 17556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 17566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.sendToTarget(); 17576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17586a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private PendingEvent obtainPendingEventLocked(InputEvent event, Object token, 17616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo FinishedInputEventCallback callback, Handler handler) { 17626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo PendingEvent p = mPendingEventPool.acquire(); 17636a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (p == null) { 17646a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p = new PendingEvent(); 17656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mEvent = event; 17675b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo p.mEventToken = token; 17686a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mCallback = callback; 17695b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo p.mEventHandler = handler; 17706a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return p; 17716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17726a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17736a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void recyclePendingEventLocked(PendingEvent p) { 17746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.recycle(); 17756a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEventPool.release(p); 17766a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 17776a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 1778bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang IBinder getToken() { 1779bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang return mToken; 1780bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang } 1781bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang 17822b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private void releaseInternal() { 17832b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mToken = null; 17842b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mHandler) { 17852b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (mChannel != null) { 17862b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (mSender != null) { 17872b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim flushPendingEventsLocked(); 17882b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSender.dispose(); 17892b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSender = null; 17902b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 17912b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mChannel.dispose(); 17922b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mChannel = null; 17932b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 17942b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 17952b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 17962b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.remove(mSeq); 17972b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 17982b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 17992b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 18006a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class InputEventHandler extends Handler { 18016a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_SEND_INPUT_EVENT = 1; 18026a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_TIMEOUT_INPUT_EVENT = 2; 18036a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_FLUSH_INPUT_EVENT = 3; 18046a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18056a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo InputEventHandler(Looper looper) { 18066a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo super(looper, null, true); 18076a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18086a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18096a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 18106a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void handleMessage(Message msg) { 18116a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo switch (msg.what) { 18126a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_SEND_INPUT_EVENT: { 18136a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo sendInputEventAndReportResultOnMainLooper((PendingEvent) msg.obj); 18146a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 18156a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18166a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_TIMEOUT_INPUT_EVENT: { 18176a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(msg.arg1, false, true); 18186a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 18196a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_FLUSH_INPUT_EVENT: { 18216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(msg.arg1, false, false); 18226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 18236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class TvInputEventSender extends InputEventSender { 18296a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public TvInputEventSender(InputChannel inputChannel, Looper looper) { 18306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo super(inputChannel, looper); 18316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 18346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void onInputEventFinished(int seq, boolean handled) { 18356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(seq, handled, false); 18366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18376a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class PendingEvent implements Runnable { 18406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public InputEvent mEvent; 18415b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo public Object mEventToken; 18426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public FinishedInputEventCallback mCallback; 18435b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo public Handler mEventHandler; 18446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public boolean mHandled; 18456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void recycle() { 18476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mEvent = null; 18485b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mEventToken = null; 18496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mCallback = null; 18505b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mEventHandler = null; 18516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandled = false; 18526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 18556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void run() { 18565b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mCallback.onFinishedInputEvent(mEventToken, mHandled); 18576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 18585b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo synchronized (mEventHandler) { 18596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo recyclePendingEventLocked(this); 18606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 18633957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 1864d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1865d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1866d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * The Hardware provides the per-hardware functionality of TV hardware. 1867d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1868d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * TV hardware is physical hardware attached to the Android device; for example, HDMI ports, 1869d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Component/Composite ports, etc. Specifically, logical devices such as HDMI CEC logical 1870d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * devices don't fall into this category. 1871d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1872d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1873d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1874d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 1875d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public final static class Hardware { 1876d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private final ITvInputHardware mInterface; 1877d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1878d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private Hardware(ITvInputHardware hardwareInterface) { 1879d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface = hardwareInterface; 1880d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1881d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1882d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private ITvInputHardware getInterface() { 1883d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface; 1884d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1885d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1886d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public boolean setSurface(Surface surface, TvStreamConfig config) { 1887d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1888d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface.setSurface(surface, config); 1889d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1890d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1891d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1892d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1893d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1894d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void setStreamVolume(float volume) { 1895d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1896d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface.setStreamVolume(volume); 1897d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1898d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1899d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1900d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1901d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1902d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public boolean dispatchKeyEventToHdmi(KeyEvent event) { 1903d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1904d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface.dispatchKeyEventToHdmi(event); 1905d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1906d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1907d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1908d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1909d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1910d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void overrideAudioSink(int audioType, String audioAddress, int samplingRate, 1911d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim int channelMask, int format) { 1912d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1913d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface.overrideAudioSink(audioType, audioAddress, samplingRate, channelMask, 1914d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim format); 1915d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1916d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 1917d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1918d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1919d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 19203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo} 1921