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 19a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seoimport android.annotation.IntDef; 20c8b7356434f665c494504661a943323c0bbe702eJae Seoimport android.annotation.NonNull; 214bf607b00c14c031e991ac9dc0ad49b9249c9162Dongwon Kangimport android.annotation.Nullable; 2289813b8162d84c5736d375e6a3018edcae4c97b9Dongwon Kangimport android.annotation.RequiresPermission; 23a759b111a1c9cb00284038f8a1554bf29709b952Jae Seoimport android.annotation.SystemApi; 24d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.annotation.SystemService; 25d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkeyimport android.content.Context; 26558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chenimport android.content.Intent; 279a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Choimport android.graphics.Rect; 284b34cc77630112d00e9a87498d05f5f8803a9ff6Jae Seoimport android.media.PlaybackParams; 293957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.net.Uri; 30832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Choimport android.os.Bundle; 313957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.os.Handler; 323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.os.IBinder; 336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.os.Looper; 346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.os.Message; 3558739e758428f3b880f8e67161f57c59aa06d496Jaesung Chungimport android.os.ParcelFileDescriptor; 363957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.os.RemoteException; 37777718220cdacb82e984c7ea8915e36ea203e5a2Jae Seoimport android.text.TextUtils; 38969167dc05a6485a32d160895871cff46fd81884Wonsik Kimimport android.util.ArrayMap; 393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.util.Log; 406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.util.Pools.Pool; 416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.util.Pools.SimplePool; 423957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.util.SparseArray; 436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.view.InputChannel; 446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.view.InputEvent; 456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seoimport android.view.InputEventSender; 46d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kimimport android.view.KeyEvent; 473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport android.view.Surface; 489a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Choimport android.view.View; 493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 50de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seoimport com.android.internal.util.Preconditions; 51de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo 52a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seoimport java.lang.annotation.Retention; 53a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seoimport java.lang.annotation.RetentionPolicy; 543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.ArrayList; 553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.Iterator; 56969167dc05a6485a32d160895871cff46fd81884Wonsik Kimimport java.util.LinkedList; 573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.List; 583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seoimport java.util.Map; 593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo/** 613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Central system API to the overall TV input framework (TIF) architecture, which arbitrates 62d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey * interaction between applications and the selected TV inputs. 635557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * 645557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * <p>There are three primary parties involved in the TV input framework (TIF) architecture: 655557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * 665557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * <ul> 675557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * <li>The <strong>TV input manager</strong> as expressed by this class is the central point of the 685557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * system that manages interaction between all other parts. It is expressed as the client-side API 695557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * here which exists in each application context and communicates with a global system service that 705557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * manages the interaction across all processes. 715557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * <li>A <strong>TV input</strong> implemented by {@link TvInputService} represents an input source 725557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * of TV, which can be a pass-through input such as HDMI, or a tuner input which provides broadcast 735557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * TV programs. The system binds to the TV input per application’s request. 745557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * on implementing TV inputs. 755557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * <li><strong>Applications</strong> talk to the TV input manager to list TV inputs and check their 765557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * status. Once an application find the input to use, it uses {@link TvView} or 775557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * {@link TvRecordingClient} for further interaction such as watching and recording broadcast TV 785557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * programs. 795557bef5e47fb7a70cd2be03384863ad9f9c5a14Dongwon Kang * </ul> 803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 81d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey@SystemService(Context.TV_INPUT_SERVICE) 823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seopublic final class TvInputManager { 833957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private static final String TAG = "TvInputManager"; 843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8558739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung static final int DVB_DEVICE_START = 0; 8658739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung static final int DVB_DEVICE_END = 2; 8758739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung 8858739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung /** 8958739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * A demux device of DVB API for controlling the filters of DVB hardware/software. 9058739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @hide 9158739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung */ 9258739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung public static final int DVB_DEVICE_DEMUX = DVB_DEVICE_START; 9358739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung /** 9458739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * A DVR device of DVB API for reading transport streams. 9558739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @hide 9658739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung */ 9758739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung public static final int DVB_DEVICE_DVR = 1; 9858739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung /** 9958739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * A frontend device of DVB API for controlling the tuner and DVB demodulator hardware. 10058739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @hide 10158739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung */ 10258739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung public static final int DVB_DEVICE_FRONTEND = DVB_DEVICE_END; 10358739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung 104cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo /** @hide */ 105cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo @Retention(RetentionPolicy.SOURCE) 106cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo @IntDef({VIDEO_UNAVAILABLE_REASON_UNKNOWN, VIDEO_UNAVAILABLE_REASON_TUNING, 107cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL, VIDEO_UNAVAILABLE_REASON_BUFFERING, 108cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY}) 109cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo public @interface VideoUnavailableReason {} 110cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo 1116057102dbb746593a7d59cf377c969b62e38c664Jae Seo static final int VIDEO_UNAVAILABLE_REASON_START = 0; 112ff1f29e1b112e68d16908b1a89225315089f8e50Dongwon Kang static final int VIDEO_UNAVAILABLE_REASON_END = 4; 1136057102dbb746593a7d59cf377c969b62e38c664Jae Seo 1149b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 115e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and 116e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable due to 117e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * an unspecified error. 1189b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 1196057102dbb746593a7d59cf377c969b62e38c664Jae Seo public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = VIDEO_UNAVAILABLE_REASON_START; 1209b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 121e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and 122e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because 123e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * the corresponding TV input is in the middle of tuning to a new channel. 1249b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 1256e62a1508cb7a5efcdde2ae9e51672fea4296dcaJae Seo public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1; 1269b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 127e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and 128e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable due to 129e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * weak TV signal. 1309b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 1319b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2; 1329b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 133e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and 134e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because 135e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * the corresponding TV input has stopped playback temporarily to buffer more data. 1369b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 137ff1f29e1b112e68d16908b1a89225315089f8e50Dongwon Kang public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3; 138ff1f29e1b112e68d16908b1a89225315089f8e50Dongwon Kang /** 139e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and 140e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because 141e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * the current TV program is audio-only. 142ff1f29e1b112e68d16908b1a89225315089f8e50Dongwon Kang */ 143ff1f29e1b112e68d16908b1a89225315089f8e50Dongwon Kang public static final int VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = VIDEO_UNAVAILABLE_REASON_END; 1449b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 1453b9be6700fd631e25559693820d03389f8de3893Jae Seo /** @hide */ 1463b9be6700fd631e25559693820d03389f8de3893Jae Seo @Retention(RetentionPolicy.SOURCE) 147cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo @IntDef({TIME_SHIFT_STATUS_UNKNOWN, TIME_SHIFT_STATUS_UNSUPPORTED, 148cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo TIME_SHIFT_STATUS_UNAVAILABLE, TIME_SHIFT_STATUS_AVAILABLE}) 149cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo public @interface TimeShiftStatus {} 1503b9be6700fd631e25559693820d03389f8de3893Jae Seo 1516f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 152e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and 153e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Unknown status. Also 154e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * the status prior to calling {@code notifyTimeShiftStatusChanged}. 1556f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 15682fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo public static final int TIME_SHIFT_STATUS_UNKNOWN = 0; 1576f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 1586f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 159e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and 160e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: The current TV input 161e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * does not support time shifting. 1626f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 163465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1; 1646f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 1656f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 166e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and 167e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Time shifting is 168e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * currently unavailable but might work again later. 1696f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 170465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2; 171465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo 172465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo /** 173e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and 174e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Time shifting is 175e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * currently available. In this status, the application assumes it can pause/resume playback, 176e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * seek to a specified time position and set playback rate and audio mode. 177465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo */ 17882fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo public static final int TIME_SHIFT_STATUS_AVAILABLE = 3; 1796f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 180e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo /** 181e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Value returned by {@link TvInputService.Session#onTimeShiftGetCurrentPosition()} and 182e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvInputService.Session#onTimeShiftGetStartPosition()} when time shifting has not 183e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * yet started. 184e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo */ 1856f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public static final long TIME_SHIFT_INVALID_TIME = Long.MIN_VALUE; 1866f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 187cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo /** @hide */ 188cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo @Retention(RetentionPolicy.SOURCE) 189cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo @IntDef({RECORDING_ERROR_UNKNOWN, RECORDING_ERROR_INSUFFICIENT_SPACE, 190cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo RECORDING_ERROR_RESOURCE_BUSY}) 191cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo public @interface RecordingError {} 192cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo 193150923ac6adf3f618e9e1ac9d4d600a9c66bd812Dongwon Kang static final int RECORDING_ERROR_START = 0; 194150923ac6adf3f618e9e1ac9d4d600a9c66bd812Dongwon Kang static final int RECORDING_ERROR_END = 2; 195150923ac6adf3f618e9e1ac9d4d600a9c66bd812Dongwon Kang 196969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 197e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Error for {@link TvInputService.RecordingSession#notifyError(int)} and 198e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvRecordingClient.RecordingCallback#onError(int)}: The requested operation cannot be 199ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * completed due to a problem that does not fit under any other error codes, or the error code 200ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * for the problem is defined on the higher version than application's 201ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * <code>android:targetSdkVersion</code>. 202a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 203150923ac6adf3f618e9e1ac9d4d600a9c66bd812Dongwon Kang public static final int RECORDING_ERROR_UNKNOWN = RECORDING_ERROR_START; 204a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 205a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 206e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Error for {@link TvInputService.RecordingSession#notifyError(int)} and 207e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvRecordingClient.RecordingCallback#onError(int)}: Recording cannot proceed due to 208e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * insufficient storage space. 209a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 21025c9c5edab42d6c9e9e0469ab04fb7ff87704d1cJae Seo public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 1; 211e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo 212e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo /** 213e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * Error for {@link TvInputService.RecordingSession#notifyError(int)} and 214e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvRecordingClient.RecordingCallback#onError(int)}: Recording cannot proceed because 215e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * a required recording resource was not able to be allocated. 216e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo */ 217150923ac6adf3f618e9e1ac9d4d600a9c66bd812Dongwon Kang public static final int RECORDING_ERROR_RESOURCE_BUSY = RECORDING_ERROR_END; 218a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 219a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** @hide */ 220a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Retention(RetentionPolicy.SOURCE) 221cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo @IntDef({INPUT_STATE_CONNECTED, INPUT_STATE_CONNECTED_STANDBY, INPUT_STATE_DISCONNECTED}) 222cdfbc488c675a9800dfc8f15aec24b65a7558d29Jae Seo public @interface InputState {} 223a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 224a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 225e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * State for {@link #getInputState(String)} and 226e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is connected. 22782fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 2282375a2e4157cc0c887959976036c60443bfcf908Dongwon Kang * <p>This state indicates that a source device is connected to the input port and is in the 22971d5c76f19e8714102073bf774c025d5ccdebc11Shubang * normal operation mode. It is mostly relevant to hardware inputs such as HDMI input. 23071d5c76f19e8714102073bf774c025d5ccdebc11Shubang * Non-hardware inputs are considered connected all the time. 231969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 232969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_CONNECTED = 0; 233e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo 234969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 235e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * State for {@link #getInputState(String)} and 236e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is connected but 237e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * in standby mode. 23882fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 2392375a2e4157cc0c887959976036c60443bfcf908Dongwon Kang * <p>This state indicates that a source device is connected to the input port but is in standby 24071d5c76f19e8714102073bf774c025d5ccdebc11Shubang * or low power mode. It is mostly relevant to hardware inputs such as HDMI input and Component 24171d5c76f19e8714102073bf774c025d5ccdebc11Shubang * inputs. 242969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 243969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_CONNECTED_STANDBY = 1; 244e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo 245969167dc05a6485a32d160895871cff46fd81884Wonsik Kim /** 246e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * State for {@link #getInputState(String)} and 247e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is disconnected. 24882fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 24982fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * <p>This state indicates that a source device is disconnected from the input port. It is 25082fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * mostly relevant to hardware inputs such as HDMI input. 25182fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 252969167dc05a6485a32d160895871cff46fd81884Wonsik Kim */ 253969167dc05a6485a32d160895871cff46fd81884Wonsik Kim public static final int INPUT_STATE_DISCONNECTED = 2; 254969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 255783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 256783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Broadcast intent action when the user blocked content ratings change. For use with the 257783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * {@link #isRatingBlocked}. 258783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 259783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public static final String ACTION_BLOCKED_RATINGS_CHANGED = 2602778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.BLOCKED_RATINGS_CHANGED"; 261783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 262783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 263783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Broadcast intent action when the parental controls enabled state changes. For use with the 264783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * {@link #isParentalControlsEnabled}. 265783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 266783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public static final String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = 2672778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED"; 2689c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo 2699c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo /** 2709c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Broadcast intent action used to query available content rating systems. 2710610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * 2720610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * <p>The TV input manager service locates available content rating systems by querying 2730610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * broadcast receivers that are registered for this action. An application can offer additional 2740610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * content rating systems to the user by declaring a suitable broadcast receiver in its 2750610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * manifest. 2760610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * 2770610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * <p>Here is an example broadcast receiver declaration that an application might include in its 2789c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * AndroidManifest.xml to advertise custom content rating systems. The meta-data specifies a 2799c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * resource that contains a description of each content rating system that is provided by the 2809c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * application. 2810610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * 2829c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <p><pre class="prettyprint"> 2839c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * {@literal 2849c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <receiver android:name=".TvInputReceiver"> 2859c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <intent-filter> 2869c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <action android:name= 2874e389e557efb7806b73d2059d46e2809c1a9f83dSungsoo Lim * "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS" /> 2889c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * </intent-filter> 2899c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <meta-data 2904e389e557efb7806b73d2059d46e2809c1a9f83dSungsoo Lim * android:name="android.media.tv.metadata.CONTENT_RATING_SYSTEMS" 2919c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * android:resource="@xml/tv_content_rating_systems" /> 2920610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * </receiver>}</pre> 2930610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * 2940610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * <p>In the above example, the <code>@xml/tv_content_rating_systems</code> resource refers to an 2959c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * XML resource whose root element is <code><rating-system-definitions></code> that 2969c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * contains zero or more <code><rating-system-definition></code> elements. Each <code> 2979c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * <rating-system-definition></code> element specifies the ratings, sub-ratings and rating 2989c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * orders of a particular content rating system. 2999c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * 3009c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * @see TvContentRating 3019c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo */ 3029c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public static final String ACTION_QUERY_CONTENT_RATING_SYSTEMS = 3032778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS"; 3049c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo 3059c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo /** 3069c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Content rating systems metadata associated with {@link #ACTION_QUERY_CONTENT_RATING_SYSTEMS}. 3070610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * 3080610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * <p>Specifies the resource ID of an XML resource that describes the content rating systems 3090610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * that are provided by the application. 3109c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo */ 3119c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public static final String META_DATA_CONTENT_RATING_SYSTEMS = 3122778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo "android.media.tv.metadata.CONTENT_RATING_SYSTEMS"; 313783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 314a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo /** 315a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo * Activity action to set up channel sources i.e. TV inputs of type 316a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo * {@link TvInputInfo#TYPE_TUNER}. When invoked, the system will display an appropriate UI for 317a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo * the user to initiate the individual setup flow provided by 318a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo * {@link android.R.attr#setupActivity} of each TV input service. 319a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo */ 320a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo public static final String ACTION_SETUP_INPUTS = "android.media.tv.action.SETUP_INPUTS"; 321a6d34ee8b4cbcda514274272188414f5ef107450Jae Seo 322e0712b2661e5ec14fdd0ddf91dc42367d3598dc0Chulwoo Lee /** 323e0712b2661e5ec14fdd0ddf91dc42367d3598dc0Chulwoo Lee * Activity action to display the recording schedules. When invoked, the system will display an 324e0712b2661e5ec14fdd0ddf91dc42367d3598dc0Chulwoo Lee * appropriate UI to browse the schedules. 325e0712b2661e5ec14fdd0ddf91dc42367d3598dc0Chulwoo Lee */ 326e0712b2661e5ec14fdd0ddf91dc42367d3598dc0Chulwoo Lee public static final String ACTION_VIEW_RECORDING_SCHEDULES = 327e0712b2661e5ec14fdd0ddf91dc42367d3598dc0Chulwoo Lee "android.media.tv.action.VIEW_RECORDING_SCHEDULES"; 328e0712b2661e5ec14fdd0ddf91dc42367d3598dc0Chulwoo Lee 3293957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputManager mService; 3303957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 331969167dc05a6485a32d160895871cff46fd81884Wonsik Kim private final Object mLock = new Object(); 332969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 3336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mLock") 334093d994965bef197fb676731fc50f6f6f630b8feJae Seo private final List<TvInputCallbackRecord> mCallbackRecords = new LinkedList<>(); 335969167dc05a6485a32d160895871cff46fd81884Wonsik Kim 336969167dc05a6485a32d160895871cff46fd81884Wonsik Kim // A mapping from TV input ID to the state of corresponding input. 3376320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo // @GuardedBy("mLock") 338093d994965bef197fb676731fc50f6f6f630b8feJae Seo private final Map<String, Integer> mStateMap = new ArrayMap<>(); 3393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3402b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim // A mapping from the sequence number of a session to its SessionCallbackRecord. 3412b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap = 342093d994965bef197fb676731fc50f6f6f630b8feJae Seo new SparseArray<>(); 3433957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3443957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo // A sequence number for the next session to be created. Should be protected by a lock 3452b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim // {@code mSessionCallbackRecordMap}. 3463957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private int mNextSeq; 3473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputClient mClient; 3493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final int mUserId; 3513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 3523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 3533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Interface used to receive the created session. 354b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 3553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 3562b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public abstract static class SessionCallback { 3573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 3583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * This is called after {@link TvInputManager#createSession} has been processed. 3593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 3603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param session A {@link TvInputManager.Session} instance created. This can be 3613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * {@code null} if the creation request failed. 3623957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 3634bf607b00c14c031e991ac9dc0ad49b9249c9162Dongwon Kang public void onSessionCreated(@Nullable Session session) { 3642b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 3652b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 3662b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim /** 3672b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * This is called when {@link TvInputManager.Session} is released. 3682b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * This typically happens when the process hosting the session has crashed or been killed. 3692b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * 3702b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim * @param session A {@link TvInputManager.Session} instance released. 3712b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim */ 3722b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionReleased(Session session) { 3732b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 374832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 375832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho /** 3761f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * This is called when the channel of this session is changed by the underlying TV input 3776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * without any {@link TvInputManager.Session#tune(Uri)} request. 378a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang * 379d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 3801f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * @param channelUri The URI of a channel. 381a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang */ 3821f213914c45c23c653f721690da2ce0718e63139Dongwon Kang public void onChannelRetuned(Session session, Uri channelUri) { 383832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 384832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 385832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho /** 3861f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * This is called when the track information of the session has been changed. 387b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang * 388d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 3891f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * @param tracks A list which includes track information. 390b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang */ 39110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTracksChanged(Session session, List<TvTrackInfo> tracks) { 392b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 393b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 394b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang /** 39510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * This is called when a track for a given type is selected. 3969b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * 3976320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 39810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the selected track. The type can be 39910d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or 40010d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_SUBTITLE}. 40110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param trackId The ID of the selected track. When {@code null} the currently selected 40210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * track for a given type should be unselected. 403d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo */ 4044bf607b00c14c031e991ac9dc0ad49b9249c9162Dongwon Kang public void onTrackSelected(Session session, int type, @Nullable String trackId) { 405d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 406d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 407d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo /** 4086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * This is invoked when the video size has been changed. It is also called when the first 4096320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * time video size information becomes available after the session is tuned to a specific 4106320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * channel. 4116320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * 4126320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 4136320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param width The width of the video. 4146320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * @param height The height of the video. 4156320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 4166320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo public void onVideoSizeChanged(Session session, int width, int height) { 4176320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 4186320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 4196320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 420d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * This is called when the video is available, so the TV input starts the playback. 421d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * 422d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo * @param session A {@link TvInputManager.Session} associated with this callback. 4239b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 4249b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoAvailable(Session session) { 4259b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4269b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 4279b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 4289b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * This is called when the video is not available, so the TV input stops the playback. 4299b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * 4306f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback. 4319b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * @param reason The reason why the TV input stopped the playback: 4329b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <ul> 4339b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN} 4346e62a1508cb7a5efcdde2ae9e51672fea4296dcaJae Seo * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING} 4359b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL} 4369b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING} 437ff1f29e1b112e68d16908b1a89225315089f8e50Dongwon Kang * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY} 4389b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang * </ul> 4399b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang */ 4409b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoUnavailable(Session session, int reason) { 4419b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 4429b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 4439b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang /** 444bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * This is called when the current program content turns out to be allowed to watch since 445bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * its content rating is not blocked by parental controls. 446bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * 4476f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback. 448bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo */ 449bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void onContentAllowed(Session session) { 450bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 451bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 452bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo /** 453bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * This is called when the current program content turns out to be not allowed to watch 454bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo * since its content rating is blocked by parental controls. 4556057102dbb746593a7d59cf377c969b62e38c664Jae Seo * 4566f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback. 4576057102dbb746593a7d59cf377c969b62e38c664Jae Seo * @param rating The content ration of the blocked program. 4586057102dbb746593a7d59cf377c969b62e38c664Jae Seo */ 4596057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void onContentBlocked(Session session, TvContentRating rating) { 4606057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 4616057102dbb746593a7d59cf377c969b62e38c664Jae Seo 4626057102dbb746593a7d59cf377c969b62e38c664Jae Seo /** 4635b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * This is called when {@link TvInputService.Session#layoutSurface} is called to change the 4645b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * layout of surface. 465ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho * 4666f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback. 4675b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param left Left position. 4685b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param top Top position. 4695b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param right Right position. 4705b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @param bottom Bottom position. 471ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho */ 472ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void onLayoutSurface(Session session, int left, int top, int right, int bottom) { 473ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 474ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 475ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho /** 476832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * This is called when a custom event has been sent from this session. 477832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * 478832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param session A {@link TvInputManager.Session} associated with this callback 479832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param eventType The type of the event. 480832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho * @param eventArgs Optional arguments of the event. 481832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho */ 482832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void onSessionEvent(Session session, String eventType, Bundle eventArgs) { 483832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 4846f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 4856f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 486465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * This is called when the time shift status is changed. 4876f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * 4886f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback. 489465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * @param status The current time shift status. Should be one of the followings. 4906f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * <ul> 491465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNSUPPORTED} 4926f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNAVAILABLE} 493465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * <li>{@link TvInputManager#TIME_SHIFT_STATUS_AVAILABLE} 4946f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * </ul> 4956f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 4966f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void onTimeShiftStatusChanged(Session session, int status) { 4976f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 4986f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 4996f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 5004e3ded556100f674ccba0d0e40adcbd0d30f9b23Jae Seo * This is called when the start position for time shifting has changed. 5016f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * 5026f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback. 5034e3ded556100f674ccba0d0e40adcbd0d30f9b23Jae Seo * @param timeMs The start position for time shifting, in milliseconds since the epoch. 5046f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 5056f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void onTimeShiftStartPositionChanged(Session session, long timeMs) { 5066f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 5076f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 5086f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 5094e3ded556100f674ccba0d0e40adcbd0d30f9b23Jae Seo * This is called when the current position for time shifting is changed. 5106f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * 5116f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * @param session A {@link TvInputManager.Session} associated with this callback. 5124e3ded556100f674ccba0d0e40adcbd0d30f9b23Jae Seo * @param timeMs The current position for time shifting, in milliseconds since the epoch. 5136f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 5146f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void onTimeShiftCurrentPositionChanged(Session session, long timeMs) { 5156f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 516a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 517e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo // For the recording session only 518a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 519e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * This is called when the recording session has been tuned to the given channel and is 520e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * ready to start recording. 521b55c7517ba4b2c2959a0bc4d37536e7e3c8283c9Dongwon Kang * 522b55c7517ba4b2c2959a0bc4d37536e7e3c8283c9Dongwon Kang * @param channelUri The URI of a channel. 523a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 524b55c7517ba4b2c2959a0bc4d37536e7e3c8283c9Dongwon Kang void onTuned(Session session, Uri channelUri) { 525a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 526a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 527e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo // For the recording session only 528a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 529e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * This is called when the current recording session has stopped recording and created a 530e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * new data entry in the {@link TvContract.RecordedPrograms} table that describes the newly 531e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * recorded program. 532a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * 533e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * @param recordedProgramUri The URI for the newly recorded program. 534a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo **/ 535a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo void onRecordingStopped(Session session, Uri recordedProgramUri) { 536a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 537a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 538e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo // For the recording session only 539a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 540e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * This is called when an issue has occurred. It may be called at any time after the current 541e3c11e842937f50f54c9d82363f33338dc9e261bJae Seo * recording session is created until it is released. 542a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * 543a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param error The error code. 544a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 545a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo void onError(Session session, @TvInputManager.RecordingError int error) { 546a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 5473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5492b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private static final class SessionCallbackRecord { 5502b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SessionCallback mSessionCallback; 5513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final Handler mHandler; 5522b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private Session mSession; 5533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo SessionCallbackRecord(SessionCallback sessionCallback, 5553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Handler handler) { 5562b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback = sessionCallback; 5573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler = handler; 5583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 5606320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionCreated(final Session session) { 5612b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSession = session; 5623957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler.post(new Runnable() { 5633957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 5643957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void run() { 5652b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback.onSessionCreated(session); 5662b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 5672b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim }); 5682b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 5692b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 5706320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionReleased() { 5712b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mHandler.post(new Runnable() { 5722b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim @Override 5732b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void run() { 5742b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallback.onSessionReleased(mSession); 5753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 5763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }); 5773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 578832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 5796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postChannelRetuned(final Uri channelUri) { 580832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mHandler.post(new Runnable() { 581832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 582832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void run() { 5831f213914c45c23c653f721690da2ce0718e63139Dongwon Kang mSessionCallback.onChannelRetuned(mSession, channelUri); 584832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 585832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho }); 586832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 587832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho 5886320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postTracksChanged(final List<TvTrackInfo> tracks) { 589b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang mHandler.post(new Runnable() { 590b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang @Override 591b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang public void run() { 59210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mSessionCallback.onTracksChanged(mSession, tracks); 593b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 594b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang }); 595b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 596b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 5976320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postTrackSelected(final int type, final String trackId) { 598d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo mHandler.post(new Runnable() { 599d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo @Override 600d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo public void run() { 60110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mSessionCallback.onTrackSelected(mSession, type, trackId); 602d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 603d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo }); 604d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 605d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 6066320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoSizeChanged(final int width, final int height) { 6076320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mHandler.post(new Runnable() { 6086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo @Override 6096320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo public void run() { 6106320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSessionCallback.onVideoSizeChanged(mSession, width, height); 6116320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6126320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo }); 6136320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 6146320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 6156320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoAvailable() { 6169b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mHandler.post(new Runnable() { 6179b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 6189b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void run() { 6199b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mSessionCallback.onVideoAvailable(mSession); 6209b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6219b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang }); 6229b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6239b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 6246320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postVideoUnavailable(final int reason) { 6259b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mHandler.post(new Runnable() { 6269b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 6279b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void run() { 6289b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang mSessionCallback.onVideoUnavailable(mSession, reason); 6299b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6309b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang }); 6319b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 6329b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 6336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postContentAllowed() { 634bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo mHandler.post(new Runnable() { 635bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo @Override 636bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void run() { 637bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo mSessionCallback.onContentAllowed(mSession); 638bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 639bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo }); 640bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 641bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 6426320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postContentBlocked(final TvContentRating rating) { 6436057102dbb746593a7d59cf377c969b62e38c664Jae Seo mHandler.post(new Runnable() { 6446057102dbb746593a7d59cf377c969b62e38c664Jae Seo @Override 6456057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void run() { 6466057102dbb746593a7d59cf377c969b62e38c664Jae Seo mSessionCallback.onContentBlocked(mSession, rating); 6476057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6486057102dbb746593a7d59cf377c969b62e38c664Jae Seo }); 6496057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 6506057102dbb746593a7d59cf377c969b62e38c664Jae Seo 6516320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postLayoutSurface(final int left, final int top, final int right, 652ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho final int bottom) { 653ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho mHandler.post(new Runnable() { 654ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @Override 655ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void run() { 656ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho mSessionCallback.onLayoutSurface(mSession, left, top, right, bottom); 657ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 658ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho }); 659ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 660ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 6616320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo void postSessionEvent(final String eventType, final Bundle eventArgs) { 662832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mHandler.post(new Runnable() { 663832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 664832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void run() { 665832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho mSessionCallback.onSessionEvent(mSession, eventType, eventArgs); 666832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 667832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho }); 668832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 6696f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 6706f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang void postTimeShiftStatusChanged(final int status) { 6716f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mHandler.post(new Runnable() { 6726f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang @Override 6736f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void run() { 6746f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mSessionCallback.onTimeShiftStatusChanged(mSession, status); 6756f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 6766f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang }); 6776f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 6786f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 6796f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang void postTimeShiftStartPositionChanged(final long timeMs) { 6806f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mHandler.post(new Runnable() { 6816f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang @Override 6826f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void run() { 6836f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mSessionCallback.onTimeShiftStartPositionChanged(mSession, timeMs); 6846f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 6856f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang }); 6866f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 6876f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 6886f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang void postTimeShiftCurrentPositionChanged(final long timeMs) { 6896f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mHandler.post(new Runnable() { 6906f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang @Override 6916f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void run() { 6926f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mSessionCallback.onTimeShiftCurrentPositionChanged(mSession, timeMs); 6936f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 6946f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang }); 6956f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 696a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 697a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo // For the recording session only 698b55c7517ba4b2c2959a0bc4d37536e7e3c8283c9Dongwon Kang void postTuned(final Uri channelUri) { 699a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mHandler.post(new Runnable() { 700a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 701a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void run() { 702b55c7517ba4b2c2959a0bc4d37536e7e3c8283c9Dongwon Kang mSessionCallback.onTuned(mSession, channelUri); 703a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 704a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo }); 705a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 706a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 707a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo // For the recording session only 708a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo void postRecordingStopped(final Uri recordedProgramUri) { 709a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mHandler.post(new Runnable() { 710a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 711a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void run() { 712a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mSessionCallback.onRecordingStopped(mSession, recordedProgramUri); 713a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 714a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo }); 715a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 716a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 717a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo // For the recording session only 718a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo void postError(final int error) { 719a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mHandler.post(new Runnable() { 720a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 721a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void run() { 722a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mSessionCallback.onError(mSession, error); 723a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 724a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo }); 725a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 7263957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7273957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 7283957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 72982fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * Callback used to monitor status of the TV inputs. 7303957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 7312778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public abstract static class TvInputCallback { 7323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 733969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * This is called when the state of a given TV input is changed. 7343957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 735a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 7368e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param state State of the TV input. The value is one of the following: 737969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <ul> 738969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_CONNECTED} 739969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_CONNECTED_STANDBY} 740969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link TvInputManager#INPUT_STATE_DISCONNECTED} 741969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </ul> 7423957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 7433b9be6700fd631e25559693820d03389f8de3893Jae Seo public void onInputStateChanged(String inputId, @InputState int state) { 7443957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7458e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 7468e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim /** 74782fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * This is called when a TV input is added to the system. 74882fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 74982fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * <p>Normally it happens when the user installs a new TV input package that implements 75082fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * {@link TvInputService} interface. 7518e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * 752a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 7538e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim */ 7548e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputAdded(String inputId) { 7558e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 7568e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 7578e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim /** 75882fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * This is called when a TV input is removed from the system. 75982fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 76082fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * <p>Normally it happens when the user uninstalls the previously installed TV input 76182fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * package. 7628e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * 763a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 7648e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim */ 7658e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputRemoved(String inputId) { 7668e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 76719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 76819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee /** 76982fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * This is called when a TV input is updated on the system. 77082fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 77182fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * <p>Normally it happens when a previously installed TV input package is re-installed or 77282fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * the media on which a newer version of the package exists becomes available/unavailable. 77319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee * 774a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 77519ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee */ 77619ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void onInputUpdated(String inputId) { 77719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 778a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 779a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 780aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo * This is called when the information about an existing TV input has been updated. 781a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * 782aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo * <p>Because the system automatically creates a <code>TvInputInfo</code> object for each TV 783aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo * input based on the information collected from the <code>AndroidManifest.xml</code>, this 784dee3cfe897b8cc49a3374807bd61647d429f706fJae Seo * method is only called back when such information has changed dynamically. 785aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo * 786aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo * @param inputInfo The <code>TvInputInfo</code> object that contains new information. 787a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 788aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo public void onTvInputInfoUpdated(TvInputInfo inputInfo) { 789a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 7903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 7913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 7922778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private static final class TvInputCallbackRecord { 7932778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo private final TvInputCallback mCallback; 7943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final Handler mHandler; 7953957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 7962778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public TvInputCallbackRecord(TvInputCallback callback, Handler handler) { 7972778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallback = callback; 7983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler = handler; 7993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8003957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8012778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo public TvInputCallback getCallback() { 8022778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo return mCallback; 8038e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 8048e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 805a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void postInputAdded(final String inputId) { 8068e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mHandler.post(new Runnable() { 8078e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 8088e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void run() { 809a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mCallback.onInputAdded(inputId); 8108e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 8118e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim }); 8128e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 8138e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 814a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void postInputRemoved(final String inputId) { 8158e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mHandler.post(new Runnable() { 8168e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 8178e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void run() { 818a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mCallback.onInputRemoved(inputId); 8198e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 8208e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim }); 8213957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8223957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 823a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void postInputUpdated(final String inputId) { 8243957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mHandler.post(new Runnable() { 8253957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 8263957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void run() { 827a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mCallback.onInputUpdated(inputId); 8283957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8293957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }); 8303957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 83119ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 832a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void postInputStateChanged(final String inputId, final int state) { 83319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee mHandler.post(new Runnable() { 83419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @Override 83519ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void run() { 836a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mCallback.onInputStateChanged(inputId, state); 837a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 838a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo }); 839a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 840a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 841aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo public void postTvInputInfoUpdated(final TvInputInfo inputInfo) { 842a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mHandler.post(new Runnable() { 843a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 844a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void run() { 845aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo mCallback.onTvInputInfoUpdated(inputInfo); 84619ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 84719ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee }); 84819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 8493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 852d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Interface used to receive events from Hardware objects. 8530632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * 854d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 855d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 856d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 857d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract static class HardwareCallback { 8580632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang /** 8590632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * This is called when {@link Hardware} is no longer available for the client. 8600632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang */ 861d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract void onReleased(); 8620632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang 8630632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang /** 8640632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * This is called when the underlying {@link TvStreamConfig} has been changed. 8650632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * 866775e3c288e264399f25ea0ca7e19ac037e5c95b5Dongwon Kang * @param configs The new {@link TvStreamConfig}s. 8670632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang */ 868d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public abstract void onStreamConfigChanged(TvStreamConfig[] configs); 869d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 870d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 871d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 8723957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @hide 8733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 8743957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public TvInputManager(ITvInputManager service, int userId) { 8753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService = service; 8763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mUserId = userId; 8773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mClient = new ITvInputClient.Stub() { 8783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 879d6672b51c5e07ec376a61057cfbb6bb7491a76b3Sungsoo Lim public void onSessionCreated(String inputId, IBinder token, InputChannel channel, 8806a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int seq) { 8812b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 8822b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 8833957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (record == null) { 8843957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Log.e(TAG, "Callback not found for " + token); 8853957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo return; 8863957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8873957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo Session session = null; 8883957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (token != null) { 8892b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim session = new Session(token, channel, mService, mUserId, seq, 8902b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap); 8913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8923957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo record.postSessionCreated(session); 8933957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8943957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 8953957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 8963957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo @Override 8972b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim public void onSessionReleased(int seq) { 8982b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 8992b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 9002b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.delete(seq); 9012b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (record == null) { 9022b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim Log.e(TAG, "Callback not found for seq:" + seq); 9032b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim return; 9042b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 9052b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim record.mSession.releaseInternal(); 9062b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim record.postSessionReleased(); 9072b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 9082b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 9092b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 9102b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim @Override 9111f213914c45c23c653f721690da2ce0718e63139Dongwon Kang public void onChannelRetuned(Uri channelUri, int seq) { 912a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang synchronized (mSessionCallbackRecordMap) { 913a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 914a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang if (record == null) { 915a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 916a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang return; 917a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 9181f213914c45c23c653f721690da2ce0718e63139Dongwon Kang record.postChannelRetuned(channelUri); 919a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 920a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang } 921a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang 922a3be12a236aef0d9c4ff1274075f1e7899d29153Dongwon Kang @Override 92310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTracksChanged(List<TvTrackInfo> tracks, int seq) { 924832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho synchronized (mSessionCallbackRecordMap) { 925832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 926832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho if (record == null) { 927832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho Log.e(TAG, "Callback not found for seq " + seq); 928832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho return; 929832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 9306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (record.mSession.updateTracks(tracks)) { 9316320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postTracksChanged(tracks); 9326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo postVideoSizeChangedIfNeededLocked(record); 9336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 934b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 935b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang } 936b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang 937b93ccca6139a7ee2dba5c110e5f8213a2bd231e5Dongwon Kang @Override 93810d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public void onTrackSelected(int type, String trackId, int seq) { 939d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo synchronized (mSessionCallbackRecordMap) { 940d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 941d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo if (record == null) { 942d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 943d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo return; 944d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 9456320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (record.mSession.updateTrackSelection(type, trackId)) { 9466320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postTrackSelected(type, trackId); 9476320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo postVideoSizeChangedIfNeededLocked(record); 9486320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 9496320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 9506320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 9516320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 9526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private void postVideoSizeChangedIfNeededLocked(SessionCallbackRecord record) { 9536320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo TvTrackInfo track = record.mSession.getVideoTrackToNotify(); 9546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track != null) { 9556320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo record.postVideoSizeChanged(track.getVideoWidth(), track.getVideoHeight()); 956d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 957d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 958d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo 959d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo @Override 9609b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoAvailable(int seq) { 9619b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang synchronized (mSessionCallbackRecordMap) { 9629b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 9639b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang if (record == null) { 9649b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 9659b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang return; 9669b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 9679b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang record.postVideoAvailable(); 9689b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 9699b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 9709b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 9719b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 9729b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang public void onVideoUnavailable(int reason, int seq) { 9739b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang synchronized (mSessionCallbackRecordMap) { 9749b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 9759b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang if (record == null) { 9769b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 9779b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang return; 9789b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 9799b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang record.postVideoUnavailable(reason); 9809b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 9819b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang } 9829b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang 9839b08edff236fc68d836eccfaa1a5f028dc390cecDongwon Kang @Override 984bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo public void onContentAllowed(int seq) { 985bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo synchronized (mSessionCallbackRecordMap) { 986bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 987bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo if (record == null) { 988bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 989bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo return; 990bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 991bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo record.postContentAllowed(); 992bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 993bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo } 994bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo 995bbcd206a798c8c2845200daf7a2d4cb7b29056f3Jae Seo @Override 9966057102dbb746593a7d59cf377c969b62e38c664Jae Seo public void onContentBlocked(String rating, int seq) { 9976057102dbb746593a7d59cf377c969b62e38c664Jae Seo synchronized (mSessionCallbackRecordMap) { 9986057102dbb746593a7d59cf377c969b62e38c664Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 9996057102dbb746593a7d59cf377c969b62e38c664Jae Seo if (record == null) { 10006057102dbb746593a7d59cf377c969b62e38c664Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 10016057102dbb746593a7d59cf377c969b62e38c664Jae Seo return; 10026057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 10036057102dbb746593a7d59cf377c969b62e38c664Jae Seo record.postContentBlocked(TvContentRating.unflattenFromString(rating)); 10046057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 10056057102dbb746593a7d59cf377c969b62e38c664Jae Seo } 10066057102dbb746593a7d59cf377c969b62e38c664Jae Seo 10076057102dbb746593a7d59cf377c969b62e38c664Jae Seo @Override 1008ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho public void onLayoutSurface(int left, int top, int right, int bottom, int seq) { 1009ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho synchronized (mSessionCallbackRecordMap) { 1010ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 1011ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho if (record == null) { 1012ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho Log.e(TAG, "Callback not found for seq " + seq); 1013ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho return; 1014ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 1015ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho record.postLayoutSurface(left, top, right, bottom); 1016ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 1017ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho } 1018ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho 1019ff04ae757a5542d2d5633e75b7adacc4fce1ce7eYoungsang Cho @Override 1020832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho public void onSessionEvent(String eventType, Bundle eventArgs, int seq) { 1021832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho synchronized (mSessionCallbackRecordMap) { 1022832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 1023832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho if (record == null) { 1024832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho Log.e(TAG, "Callback not found for seq " + seq); 1025832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho return; 1026832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 1027832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho record.postSessionEvent(eventType, eventArgs); 1028832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 1029832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho } 10306f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 10316f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang @Override 10326f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void onTimeShiftStatusChanged(int status, int seq) { 10336f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mSessionCallbackRecordMap) { 10346f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 10356f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (record == null) { 10366f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 10376f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 10386f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10396f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang record.postTimeShiftStatusChanged(status); 10406f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10416f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10426f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 10436f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang @Override 10446f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void onTimeShiftStartPositionChanged(long timeMs, int seq) { 10456f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mSessionCallbackRecordMap) { 10466f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 10476f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (record == null) { 10486f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 10496f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 10506f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10516f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang record.postTimeShiftStartPositionChanged(timeMs); 10526f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10536f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10546f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 10556f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang @Override 10566f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang public void onTimeShiftCurrentPositionChanged(long timeMs, int seq) { 10576f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mSessionCallbackRecordMap) { 10586f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 10596f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (record == null) { 10606f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.e(TAG, "Callback not found for seq " + seq); 10616f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 10626f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10636f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang record.postTimeShiftCurrentPositionChanged(timeMs); 10646f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 10656f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 1066a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 1067832860fb9f6b3a7188a6af2d5d67806593595800Youngsang Cho @Override 1068b55c7517ba4b2c2959a0bc4d37536e7e3c8283c9Dongwon Kang public void onTuned(int seq, Uri channelUri) { 1069a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo synchronized (mSessionCallbackRecordMap) { 1070a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 1071a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo if (record == null) { 1072a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 1073a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo return; 1074a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1075b55c7517ba4b2c2959a0bc4d37536e7e3c8283c9Dongwon Kang record.postTuned(channelUri); 1076a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1077a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1078a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 1079a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 1080a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void onRecordingStopped(Uri recordedProgramUri, int seq) { 1081a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo synchronized (mSessionCallbackRecordMap) { 1082a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 1083a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo if (record == null) { 1084a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 1085a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo return; 10868e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 1087a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo record.postRecordingStopped(recordedProgramUri); 10888e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 10898e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 10908e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 10918e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 1092a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void onError(int error, int seq) { 1093a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo synchronized (mSessionCallbackRecordMap) { 1094a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq); 1095a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo if (record == null) { 1096a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo Log.e(TAG, "Callback not found for seq " + seq); 1097a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo return; 1098a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1099a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo record.postError(error); 1100a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1101a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1102a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo }; 1103a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo ITvInputManagerCallback managerCallback = new ITvInputManagerCallback.Stub() { 1104a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 11058e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputAdded(String inputId) { 11068e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim synchronized (mLock) { 11078e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mStateMap.put(inputId, INPUT_STATE_CONNECTED); 11082778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 11098e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputAdded(inputId); 11108e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 11118e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 11128e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim } 11138e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim 11148e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim @Override 11158e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim public void onInputRemoved(String inputId) { 11168e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim synchronized (mLock) { 11178e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim mStateMap.remove(inputId); 11182778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 11198e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim record.postInputRemoved(inputId); 11203957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11213957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11223957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 112319ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee 112419ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee @Override 112519ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee public void onInputUpdated(String inputId) { 112619ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee synchronized (mLock) { 1127db8f7ab752de641b147015a2b4a134913fbcb594Youngsang Cho for (TvInputCallbackRecord record : mCallbackRecords) { 112819ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee record.postInputUpdated(inputId); 112919ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 113019ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 113119ba61affbc0c4a4454abc6cf09f70ea428d1a62Chulwoo Lee } 1132a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 1133a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 1134a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void onInputStateChanged(String inputId, int state) { 1135a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo synchronized (mLock) { 1136a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mStateMap.put(inputId, state); 1137a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 1138a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo record.postInputStateChanged(inputId, state); 1139a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1140a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1141a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1142a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 1143a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @Override 1144aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo public void onTvInputInfoUpdated(TvInputInfo inputInfo) { 1145a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo synchronized (mLock) { 1146a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo for (TvInputCallbackRecord record : mCallbackRecords) { 1147aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo record.postTvInputInfoUpdated(inputInfo); 1148a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1149a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1150a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 11513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo }; 1152969167dc05a6485a32d160895871cff46fd81884Wonsik Kim try { 11539127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo if (mService != null) { 115438b3257b7c0d80d282f1a1f7e1dd9c47e77c1081Jae Seo mService.registerCallback(managerCallback, mUserId); 1155993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang List<TvInputInfo> infos = mService.getTvInputList(mUserId); 1156993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang synchronized (mLock) { 1157993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang for (TvInputInfo info : infos) { 1158993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang String inputId = info.getId(); 115982fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo mStateMap.put(inputId, mService.getTvInputState(inputId, mUserId)); 1160993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang } 1161993f81e2380da210c27e1e957ac1bdca3a99100aDongwon Kang } 11629127e4580c618bc1afae5c2c280f5a271f7a7635Jae Seo } 1163969167dc05a6485a32d160895871cff46fd81884Wonsik Kim } catch (RemoteException e) { 1164c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1165969167dc05a6485a32d160895871cff46fd81884Wonsik Kim } 11663957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11673957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 11683957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 11693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Returns the complete list of TV inputs on the system. 11703957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 11713957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @return List of {@link TvInputInfo} for each TV input that describes its meta information. 11723957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 11733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public List<TvInputInfo> getTvInputList() { 11743957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 11753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo return mService.getTvInputList(mUserId); 11763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 1177c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 11783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 11803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 11813957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1182b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * Returns the {@link TvInputInfo} for a given TV input. 1183b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * 1184b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * @param inputId The ID of the TV input. 1185b375805f3b1672e68d1511565af4700e5fa8491dJae Seo * @return the {@link TvInputInfo} for a given TV input. {@code null} if not found. 1186b375805f3b1672e68d1511565af4700e5fa8491dJae Seo */ 11874bf607b00c14c031e991ac9dc0ad49b9249c9162Dongwon Kang @Nullable 1188c8b7356434f665c494504661a943323c0bbe702eJae Seo public TvInputInfo getTvInputInfo(@NonNull String inputId) { 1189de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(inputId); 1190b375805f3b1672e68d1511565af4700e5fa8491dJae Seo try { 1191b375805f3b1672e68d1511565af4700e5fa8491dJae Seo return mService.getTvInputInfo(inputId, mUserId); 1192b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } catch (RemoteException e) { 1193c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1194b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } 1195b375805f3b1672e68d1511565af4700e5fa8491dJae Seo } 1196b375805f3b1672e68d1511565af4700e5fa8491dJae Seo 1197b375805f3b1672e68d1511565af4700e5fa8491dJae Seo /** 1198ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * Updates the <code>TvInputInfo</code> for an existing TV input. A TV input service 1199ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * implementation may call this method to pass the application and system an up-to-date 1200ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * <code>TvInputInfo</code> object that describes itself. 1201c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo * 1202ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * <p>The system automatically creates a <code>TvInputInfo</code> object for each TV input, 1203ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * based on the information collected from the <code>AndroidManifest.xml</code>, thus it is not 1204ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * necessary to call this method unless such information has changed dynamically. 1205ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * Use {@link TvInputInfo.Builder} to build a new <code>TvInputInfo</code> object. 1206ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * 1207ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * <p>Attempting to change information about a TV input that the calling package does not own 1208ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * does nothing. 1209c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo * 1210aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo * @param inputInfo The <code>TvInputInfo</code> object that contains new information. 1211c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo * @throws IllegalArgumentException if the argument is {@code null}. 1212ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang * @see TvInputCallback#onTvInputInfoUpdated(TvInputInfo) 1213c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo */ 1214ee564881d99eeca24e1ef4b59ca6dab4d30a90d9Dongwon Kang public void updateTvInputInfo(@NonNull TvInputInfo inputInfo) { 1215c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo Preconditions.checkNotNull(inputInfo); 1216c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo try { 1217aa5605ffee270ef8802c5d9dc8df8ce71e377f55Jae Seo mService.updateTvInputInfo(inputInfo, mUserId); 1218c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo } catch (RemoteException e) { 1219c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1220c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo } 1221c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo } 1222c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo 1223c2a89510ddda390d6d53ff24dd20d257fcd2379eJae Seo /** 122482fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * Returns the state of a given TV input. 122582fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * 122682fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * <p>The state is one of the following: 1227969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <ul> 1228969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_CONNECTED} 1229969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_CONNECTED_STANDBY} 1230969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * <li>{@link #INPUT_STATE_DISCONNECTED} 1231969167dc05a6485a32d160895871cff46fd81884Wonsik Kim * </ul> 12323957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 1233a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 123482fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo * @throws IllegalArgumentException if the argument is {@code null}. 12353957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 12363b9be6700fd631e25559693820d03389f8de3893Jae Seo @InputState 1237c8b7356434f665c494504661a943323c0bbe702eJae Seo public int getInputState(@NonNull String inputId) { 1238de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(inputId); 1239969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 1240969167dc05a6485a32d160895871cff46fd81884Wonsik Kim Integer state = mStateMap.get(inputId); 1241969167dc05a6485a32d160895871cff46fd81884Wonsik Kim if (state == null) { 124282fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo Log.w(TAG, "Unrecognized input ID: " + inputId); 124382fce64530d19a4da1c02d424fb2515feafe6a70Jae Seo return INPUT_STATE_DISCONNECTED; 12443957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 1245093d994965bef197fb676731fc50f6f6f630b8feJae Seo return state; 12463957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 12502778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Registers a {@link TvInputCallback}. 12513957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 12522778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * @param callback A callback used to monitor status of the TV inputs. 12538e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the status change will be delivered to. 12543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1255c8b7356434f665c494504661a943323c0bbe702eJae Seo public void registerCallback(@NonNull TvInputCallback callback, @NonNull Handler handler) { 1256de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(callback); 1257de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(handler); 1258969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 12592778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo mCallbackRecords.add(new TvInputCallbackRecord(callback, handler)); 12603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12623957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12633957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 12642778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * Unregisters the existing {@link TvInputCallback}. 12653957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 12662778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo * @param callback The existing callback to remove. 12673957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1268c8b7356434f665c494504661a943323c0bbe702eJae Seo public void unregisterCallback(@NonNull final TvInputCallback callback) { 1269de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(callback); 1270969167dc05a6485a32d160895871cff46fd81884Wonsik Kim synchronized (mLock) { 12712778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo for (Iterator<TvInputCallbackRecord> it = mCallbackRecords.iterator(); 1272969167dc05a6485a32d160895871cff46fd81884Wonsik Kim it.hasNext(); ) { 12732778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo TvInputCallbackRecord record = it.next(); 12742778f5a7bd7c45861b6f2fc5639509e327495a4aJae Seo if (record.getCallback() == callback) { 12753957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo it.remove(); 1276969167dc05a6485a32d160895871cff46fd81884Wonsik Kim break; 12773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12793957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12803957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 12813957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 12823957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1283783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Returns the user's parental controls enabled state. 1284783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 1285783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return {@code true} if the user enabled the parental controls, {@code false} otherwise. 1286783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 1287783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public boolean isParentalControlsEnabled() { 1288783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 1289783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return mService.isParentalControlsEnabled(mUserId); 1290783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 1291c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1292783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1293783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1294783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1295783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 1296783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Sets the user's parental controls enabled state. 1297783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 1298783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param enabled The user's parental controls enabled state. {@code true} if the user enabled 1299783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * the parental controls, {@code false} otherwise. 1300783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isParentalControlsEnabled 1301783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 1302783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 1303783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 130489813b8162d84c5736d375e6a3018edcae4c97b9Dongwon Kang @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS) 1305783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public void setParentalControlsEnabled(boolean enabled) { 1306783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 1307783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.setParentalControlsEnabled(enabled, mUserId); 1308783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 1309c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1310783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1311783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1312783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1313783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 1314783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Checks whether a given TV content rating is blocked by the user. 1315783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 1316936c040ec445afad98ec16fc634ae6573eceefbbJae Seo * @param rating The TV content rating to check. Can be {@link TvContentRating#UNRATED}. 1317783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return {@code true} if the given TV content rating is blocked, {@code false} otherwise. 1318783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 1319c8b7356434f665c494504661a943323c0bbe702eJae Seo public boolean isRatingBlocked(@NonNull TvContentRating rating) { 1320de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(rating); 1321783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 1322783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return mService.isRatingBlocked(rating.flattenToString(), mUserId); 1323783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 1324c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1325783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1326783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1327783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1328783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 1329783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Returns the list of blocked content ratings. 1330783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 1331783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @return the list of content ratings blocked by the user. 1332783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 13339650a435ed909ed4062d64fd2d9b085628d4a455Jeff Sharkey @SystemApi 1334783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo public List<TvContentRating> getBlockedRatings() { 1335783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 1336093d994965bef197fb676731fc50f6f6f630b8feJae Seo List<TvContentRating> ratings = new ArrayList<>(); 1337783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo for (String rating : mService.getBlockedRatings(mUserId)) { 1338783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo ratings.add(TvContentRating.unflattenFromString(rating)); 1339783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1340783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo return ratings; 1341783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 1342c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1343783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1344783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1345783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1346783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 1347783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Adds a user blocked content rating. 1348783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 1349783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The content rating to block. 1350783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isRatingBlocked 1351783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #removeBlockedRating 1352783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 1353783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 1354783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 135589813b8162d84c5736d375e6a3018edcae4c97b9Dongwon Kang @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS) 1356de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo public void addBlockedRating(@NonNull TvContentRating rating) { 1357de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(rating); 1358783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 1359783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.addBlockedRating(rating.flattenToString(), mUserId); 1360783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 1361c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1362783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1363783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1364783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1365783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 1366783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * Removes a user blocked content rating. 1367783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * 1368783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @param rating The content rating to unblock. 1369783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #isRatingBlocked 1370783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @see #addBlockedRating 1371783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo * @hide 1372783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo */ 1373783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo @SystemApi 137489813b8162d84c5736d375e6a3018edcae4c97b9Dongwon Kang @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS) 1375de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo public void removeBlockedRating(@NonNull TvContentRating rating) { 1376de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(rating); 1377783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo try { 1378783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo mService.removeBlockedRating(rating.flattenToString(), mUserId); 1379783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } catch (RemoteException e) { 1380c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1381783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1382783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo } 1383783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo 1384783645e99f909ffc7a2d5d2fca9324cc0e9b7362Jae Seo /** 13859c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo * Returns the list of all TV content rating systems defined. 13865c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim * @hide 13875c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim */ 13885c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim @SystemApi 1389dd3ec0be1196304b66eb8168fa747a92a88c9605Shubang @RequiresPermission(android.Manifest.permission.READ_CONTENT_RATING_SYSTEMS) 13909c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo public List<TvContentRatingSystemInfo> getTvContentRatingSystemList() { 13915c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim try { 13929c165d6e9a2f085fbdc87b9221f2d52d851b2652Jae Seo return mService.getTvContentRatingSystemList(mUserId); 13935c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } catch (RemoteException e) { 1394c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 13955c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } 13965c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim } 13975c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim 13985c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5Sungsoo Lim /** 1399558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * Notifies the TV input of the given preview program that the program's browsable state is 1400558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * disabled. 1401558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * @hide 1402558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen */ 1403558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen @SystemApi 1404558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen @RequiresPermission(android.Manifest.permission.NOTIFY_TV_INPUTS) 1405558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen public void notifyPreviewProgramBrowsableDisabled(String packageName, long programId) { 1406558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen Intent intent = new Intent(); 1407558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.setAction(TvContract.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED); 1408558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.putExtra(TvContract.EXTRA_PREVIEW_PROGRAM_ID, programId); 1409558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.setPackage(packageName); 1410558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen try { 1411558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen mService.sendTvInputNotifyIntent(intent, mUserId); 1412558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } catch (RemoteException e) { 1413558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen throw e.rethrowFromSystemServer(); 1414558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } 1415558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } 1416558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen 1417558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen /** 1418558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * Notifies the TV input of the given watch next program that the program's browsable state is 1419558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * disabled. 1420558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * @hide 1421558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen */ 1422558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen @SystemApi 1423558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen @RequiresPermission(android.Manifest.permission.NOTIFY_TV_INPUTS) 1424558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen public void notifyWatchNextProgramBrowsableDisabled(String packageName, long programId) { 1425558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen Intent intent = new Intent(); 1426558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.setAction(TvContract.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED); 1427558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.putExtra(TvContract.EXTRA_WATCH_NEXT_PROGRAM_ID, programId); 1428558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.setPackage(packageName); 1429558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen try { 1430558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen mService.sendTvInputNotifyIntent(intent, mUserId); 1431558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } catch (RemoteException e) { 1432558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen throw e.rethrowFromSystemServer(); 1433558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } 1434558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } 1435558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen 1436558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen /** 1437558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * Notifies the TV input of the given preview program that the program is added to watch next. 1438558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen * @hide 1439558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen */ 1440558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen @SystemApi 1441558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen @RequiresPermission(android.Manifest.permission.NOTIFY_TV_INPUTS) 1442558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen public void notifyPreviewProgramAddedToWatchNext(String packageName, long previewProgramId, 1443558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen long watchNextProgramId) { 1444558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen Intent intent = new Intent(); 1445558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.setAction(TvContract.ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT); 1446558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.putExtra(TvContract.EXTRA_PREVIEW_PROGRAM_ID, previewProgramId); 1447558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.putExtra(TvContract.EXTRA_WATCH_NEXT_PROGRAM_ID, watchNextProgramId); 1448558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen intent.setPackage(packageName); 1449558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen try { 1450558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen mService.sendTvInputNotifyIntent(intent, mUserId); 1451558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } catch (RemoteException e) { 1452558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen throw e.rethrowFromSystemServer(); 1453558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } 1454558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen } 1455558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen 1456558acf96dbffc0f13b414b1a5c5de191f6ffe27aConrad Chen /** 1457674e96216d6a60f0d87d3a6a0d62f358a101532bYoungsang Cho * Creates a {@link Session} for a given TV input. 14580610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * 14590610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * <p>The number of sessions that can be created at the same time is limited by the capability 14600610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * of the given TV input. 14613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 1462a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 14638e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param callback A callback used to receive the created session. 14648e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param handler A {@link Handler} that the session creation will be delivered to. 1465b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 14663957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1467de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback, 1468de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo @NonNull Handler handler) { 1469a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo createSessionInternal(inputId, false, callback, handler); 1470a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1471a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 1472a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 1473a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * Creates a recording {@link Session} for a given TV input. 1474a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * 1475a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * <p>The number of sessions that can be created at the same time is limited by the capability 1476a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * of the given TV input. 1477a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * 1478a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 1479a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param callback A callback used to receive the created session. 1480a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param handler A {@link Handler} that the session creation will be delivered to. 1481a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @hide 1482a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 1483a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo public void createRecordingSession(@NonNull String inputId, 1484a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo @NonNull final SessionCallback callback, @NonNull Handler handler) { 1485a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo createSessionInternal(inputId, true, callback, handler); 1486a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 1487a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 1488a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo private void createSessionInternal(String inputId, boolean isRecordingSession, 1489a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo SessionCallback callback, Handler handler) { 1490de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(inputId); 1491de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(callback); 1492de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(handler); 14932b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim SessionCallbackRecord record = new SessionCallbackRecord(callback, handler); 14942b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 14953957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo int seq = mNextSeq++; 14962b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.put(seq, record); 14973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 1498a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mService.createSession(mClient, inputId, isRecordingSession, seq, mUserId); 14993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 1500c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 15013957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 15023957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 15033957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 15043957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 1505b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo /** 1506c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * Returns the TvStreamConfig list of the given TV input. 1507c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * 150890e733385d466acd87730676c83c080a17ff495fWonsik Kim * If you are using {@link Hardware} object from {@link 150990e733385d466acd87730676c83c080a17ff495fWonsik Kim * #acquireTvInputHardware}, you should get the list of available streams 151090e733385d466acd87730676c83c080a17ff495fWonsik Kim * from {@link HardwareCallback#onStreamConfigChanged} method, not from 151190e733385d466acd87730676c83c080a17ff495fWonsik Kim * here. This method is designed to be used with {@link #captureFrame} in 151290e733385d466acd87730676c83c080a17ff495fWonsik Kim * capture scenarios specifically and not suitable for any other use. 151390e733385d466acd87730676c83c080a17ff495fWonsik Kim * 1514a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 1515c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @return List of {@link TvStreamConfig} which is available for capturing 1516c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * of the given TV input. 1517c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @hide 1518c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo */ 1519c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo @SystemApi 1520d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT) 1521c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId) { 1522c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo try { 1523c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo return mService.getAvailableTvStreamConfigList(inputId, mUserId); 1524c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } catch (RemoteException e) { 1525c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1526c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1527c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1528c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo 1529c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo /** 1530c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * Take a snapshot of the given TV input into the provided Surface. 1531c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * 1532a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @param inputId The ID of the TV input. 1533c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param surface the {@link Surface} to which the snapshot is captured. 1534c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @param config the {@link TvStreamConfig} which is used for capturing. 1535c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @return true when the {@link Surface} is ready to be captured. 1536c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo * @hide 1537c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo */ 1538c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo @SystemApi 1539d86b8fea43ebb6e5c31691b44d8ceb0d8d3c9072Jeff Sharkey @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT) 1540c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo public boolean captureFrame(String inputId, Surface surface, TvStreamConfig config) { 1541c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo try { 1542c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo return mService.captureFrame(inputId, surface, config, mUserId); 1543c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } catch (RemoteException e) { 1544c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1545df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } 1546df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } 1547df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo 1548df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo /** 1549df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * Returns true if there is only a single TV input session. 1550df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * 1551df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo * @hide 1552df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo */ 1553df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo @SystemApi 1554dd3ec0be1196304b66eb8168fa747a92a88c9605Shubang @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT) 1555df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo public boolean isSingleSessionActive() { 1556df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo try { 1557df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo return mService.isSingleSessionActive(mUserId); 1558df9f0a321e0cb2958c9d170395a0367a106fa0e6Terry Heo } catch (RemoteException e) { 1559c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1560c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1561c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo } 1562c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo 1563c086a3df3b28996cd10ebe42c5f59035d054aa0dTerry Heo /** 1564d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Returns a list of TvInputHardwareInfo objects representing available hardware. 1565d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 1566d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1567d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1568d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 156989813b8162d84c5736d375e6a3018edcae4c97b9Dongwon Kang @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) 1570d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public List<TvInputHardwareInfo> getHardwareList() { 1571d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1572d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mService.getHardwareList(); 1573d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1574c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1575d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1576d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1577d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1578d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 15790632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * Acquires {@link Hardware} object for the given device ID. 1580d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 15810632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * <p>A subsequent call to this method on the same {@code deviceId} will release the currently 15820632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * acquired Hardware. 1583d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 15840632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param deviceId The device ID to acquire Hardware for. 15850632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param callback A callback to receive updates on Hardware. 15860632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param info The TV input which will use the acquired Hardware. 15870632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @return Hardware on success, {@code null} otherwise. 15880632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * 1589c204c223a77237e13d084d58590acb16b025c676Jeff Sharkey * @hide 15900632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @removed 1591d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1592c204c223a77237e13d084d58590acb16b025c676Jeff Sharkey @SystemApi 159389813b8162d84c5736d375e6a3018edcae4c97b9Dongwon Kang @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) 1594d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public Hardware acquireTvInputHardware(int deviceId, final HardwareCallback callback, 1595d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim TvInputInfo info) { 15960632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang return acquireTvInputHardware(deviceId, info, callback); 15970632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang } 15980632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang 15990632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang /** 16000632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * Acquires {@link Hardware} object for the given device ID. 16010632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * 16020632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * <p>A subsequent call to this method on the same {@code deviceId} will release the currently 16030632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * acquired Hardware. 16040632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * 16050632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param deviceId The device ID to acquire Hardware for. 16060632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param callback A callback to receive updates on Hardware. 16070632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param info The TV input which will use the acquired Hardware. 16080632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @return Hardware on success, {@code null} otherwise. 16090632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * 16100632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @hide 16110632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang */ 16120632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang @SystemApi 16130632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) 16140632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang public Hardware acquireTvInputHardware(int deviceId, TvInputInfo info, 16150632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang final HardwareCallback callback) { 1616d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1617d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return new Hardware( 1618d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mService.acquireTvInputHardware(deviceId, new ITvInputHardwareCallback.Stub() { 1619d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @Override 1620d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void onReleased() { 1621d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim callback.onReleased(); 1622d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1623d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1624d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @Override 1625d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void onStreamConfigChanged(TvStreamConfig[] configs) { 1626d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim callback.onStreamConfigChanged(configs); 1627d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1628d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim }, info, mUserId)); 1629d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1630c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1631d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1632d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1633d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1634d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 1635d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Releases previously acquired hardware object. 1636d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 16370632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param deviceId The device ID this Hardware was acquired for 16380632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * @param hardware Hardware to release. 16390632d8ae71418bea092f9f2c7e62118213e7cc78Dongwon Kang * 1640d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 1641d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 1642d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 164389813b8162d84c5736d375e6a3018edcae4c97b9Dongwon Kang @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE) 1644d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void releaseTvInputHardware(int deviceId, Hardware hardware) { 1645d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 1646d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mService.releaseTvInputHardware(deviceId, hardware.getInterface(), mUserId); 1647d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 1648c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1649d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1650d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 1651d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 1652d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 165358739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * Returns the list of currently available DVB devices on the system. 165458739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * 165558739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @return the list of {@link DvbDeviceInfo} objects representing available DVB devices. 165658739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @hide 165758739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung */ 165858739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung public List<DvbDeviceInfo> getDvbDeviceList() { 165958739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung try { 166058739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung return mService.getDvbDeviceList(); 166158739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung } catch (RemoteException e) { 1662c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 166358739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung } 166458739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung } 166558739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung 166658739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung /** 166758739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * Returns a {@link ParcelFileDescriptor} of a specified DVB device for a given 166858739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * {@link DvbDeviceInfo} 166958739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * 167058739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @param info A {@link DvbDeviceInfo} to open a DVB device. 1671ed6586a569ddf2cf67014bbf51f8126dff116ca8Jae Seo * @param device A DVB device. The DVB device can be {@link #DVB_DEVICE_DEMUX}, 1672ed6586a569ddf2cf67014bbf51f8126dff116ca8Jae Seo * {@link #DVB_DEVICE_DVR} or {@link #DVB_DEVICE_FRONTEND}. 167358739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @return a {@link ParcelFileDescriptor} of a specified DVB device for a given 1674ed6586a569ddf2cf67014bbf51f8126dff116ca8Jae Seo * {@link DvbDeviceInfo}, or {@code null} if the given {@link DvbDeviceInfo} was invalid 1675ed6586a569ddf2cf67014bbf51f8126dff116ca8Jae Seo * or the specified DVB device was busy with a previous request. 167658739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung * @hide 167758739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung */ 167858739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device) { 167958739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung try { 168058739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung if (DVB_DEVICE_START > device || DVB_DEVICE_END < device) { 168158739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung throw new IllegalArgumentException("Invalid DVB device: " + device); 168258739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung } 168358739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung return mService.openDvbDevice(info, device); 168458739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung } catch (RemoteException e) { 1685c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 168658739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung } 168758739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung } 168858739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung 168958739e758428f3b880f8e67161f57c59aa06d496Jaesung Chung /** 16902e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang * Requests to make a channel browsable. 16912e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang * 16922e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang * <p>Once called, the system will review the request and make the channel browsable based on 16932e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang * its policy. The first request from a package is guaranteed to be approved. 16942e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang * 16952e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang * @param channelUri The URI for the channel to be browsable. 16962e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang * @hide 16972e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang */ 16982e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang public void requestChannelBrowsable(Uri channelUri) { 16992e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang try { 17002e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang mService.requestChannelBrowsable(channelUri, mUserId); 17012e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang } catch (RemoteException e) { 17022e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang throw e.rethrowFromSystemServer(); 17032e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang } 17042e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang } 17052e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang 17062e7f5ce709f9ee45c4fb219d768fbec057185375Dongwon Kang /** 1707b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * The Session provides the per-session functionality of TV inputs. 1708b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo * @hide 1709b8a64416e5e7cf39fd899fa600a940b0ef3c15fdJae Seo */ 17103957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public static final class Session { 17116a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_IN_PROGRESS = -1; 17126a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_NOT_HANDLED = 0; 17136a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo static final int DISPATCH_HANDLED = 1; 17146a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17156a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private static final long INPUT_SESSION_NOT_RESPONDING_TIMEOUT = 2500; 17166a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17173957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final ITvInputManager mService; 17183957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo private final int mUserId; 17192b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final int mSeq; 17206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // For scheduling input event handling on the main thread. This also serves as a lock to 17226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // protect pending input events and the input channel. 17236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final InputEventHandler mHandler = new InputEventHandler(Looper.getMainLooper()); 17246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 1725093d994965bef197fb676731fc50f6f6f630b8feJae Seo private final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20); 1726093d994965bef197fb676731fc50f6f6f630b8feJae Seo private final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20); 17272b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap; 17286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17299a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho private IBinder mToken; 17306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private TvInputEventSender mSender; 17316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private InputChannel mChannel; 17326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 17336f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang private final Object mMetadataLock = new Object(); 17346f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 1735093d994965bef197fb676731fc50f6f6f630b8feJae Seo private final List<TvTrackInfo> mAudioTracks = new ArrayList<>(); 17366f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 1737093d994965bef197fb676731fc50f6f6f630b8feJae Seo private final List<TvTrackInfo> mVideoTracks = new ArrayList<>(); 17386f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 1739093d994965bef197fb676731fc50f6f6f630b8feJae Seo private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<>(); 17406f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 174110d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedAudioTrackId; 17426f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 174310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedVideoTrackId; 17446f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 174510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo private String mSelectedSubtitleTrackId; 17466f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 17476320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private int mVideoWidth; 17486f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang // @GuardedBy("mMetadataLock") 17496320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo private int mVideoHeight; 17503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 17512b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId, 17522b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) { 17533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mToken = token; 17546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mChannel = channel; 17553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService = service; 17563957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mUserId = userId; 17572b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSeq = seq; 17582b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap = sessionCallbackRecordMap; 17593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 17603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 17613957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 17623957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Releases this session. 17633957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 17643957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void release() { 17659a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1766dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1767dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 17689a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 17693957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 17703957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.releaseSession(mToken, mUserId); 17713957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 1772c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 17733957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 17746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 17752b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim releaseInternal(); 17763957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 17773957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 17783957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 177915c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * Sets this as the main session. The main session is a session whose corresponding TV 178015c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * input determines the HDMI-CEC active source device. 178115c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * 178215c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee * @see TvView#setMain 17834c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee */ 178415c56aac985bc8d75f38fb4ecb92dda12d2ca06cJi-Hwan Lee void setMain() { 17854c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee if (mToken == null) { 17864c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee Log.w(TAG, "The session has been already released"); 17874c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee return; 17884c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 17894c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee try { 17904c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee mService.setMainSession(mToken, mUserId); 17914c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } catch (RemoteException e) { 1792c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 17934c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 17944c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee } 17954c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee 17964c52697dbed682a19dacc78b0c08931ea8dbc6b5Ji-Hwan Lee /** 17973957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Sets the {@link android.view.Surface} for this session. 17983957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 17993957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param surface A {@link android.view.Surface} used to render video. 18003957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1801f1c025cbcd98f2366d384c5aac114c330090a645Wonsik Kim public void setSurface(Surface surface) { 18029a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1803dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1804dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 18059a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 18063957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo // surface can be null. 18073957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 18083957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.setSurface(mToken, surface, mUserId); 18093957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 1810c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 18113957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 18123957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 18133957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 18143957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 1815606c8a396558e9714159db4969340af170677172Jae Seo * Notifies of any structural changes (format or size) of the surface passed in 1816606c8a396558e9714159db4969340af170677172Jae Seo * {@link #setSurface}. 1817e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho * 1818606c8a396558e9714159db4969340af170677172Jae Seo * @param format The new PixelFormat of the surface. 1819606c8a396558e9714159db4969340af170677172Jae Seo * @param width The new width of the surface. 1820606c8a396558e9714159db4969340af170677172Jae Seo * @param height The new height of the surface. 1821e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho */ 1822e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho public void dispatchSurfaceChanged(int format, int width, int height) { 1823e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho if (mToken == null) { 1824e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho Log.w(TAG, "The session has been already released"); 1825e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho return; 1826e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1827e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho try { 1828e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho mService.dispatchSurfaceChanged(mToken, format, width, height, mUserId); 1829e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } catch (RemoteException e) { 1830c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 1831e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1832e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho } 1833e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho 1834e821d711db1799dc51661a3ed6188f3cd942bae7Youngsang Cho /** 1835782f7345471072b630e58c7abd3579b0015273b1Jae Seo * Sets the relative stream volume of this session to handle a change of audio focus. 18363957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 18373957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param volume A volume value between 0.0f to 1.0f. 18383957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @throws IllegalArgumentException if the volume value is out of range. 18393957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 1840782f7345471072b630e58c7abd3579b0015273b1Jae Seo public void setStreamVolume(float volume) { 18419a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1842dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1843dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 18449a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 18453957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 18463957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo if (volume < 0.0f || volume > 1.0f) { 18473957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo throw new IllegalArgumentException("volume should be between 0.0f and 1.0f"); 18483957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 18493957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo mService.setVolume(mToken, volume, mUserId); 18503957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 1851c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 18523957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 18533957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 18543957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo 18553957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo /** 18563957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * Tunes to a given channel. 18573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * 18583957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo * @param channelUri The URI of a channel. 18593957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo */ 18603957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo public void tune(Uri channelUri) { 18611a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim tune(channelUri, null); 18621a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim } 18631a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim 18641a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim /** 18651a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * Tunes to a given channel. 18661a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * 18671a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @param channelUri The URI of a channel. 18681a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim * @param params A set of extra parameters which might be handled with this tune event. 18691a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim */ 1870de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo public void tune(@NonNull Uri channelUri, Bundle params) { 1871de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(channelUri); 18729a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 1873dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 1874dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 18759a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 18766f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mMetadataLock) { 18776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.clear(); 18786320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.clear(); 18796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.clear(); 18806320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedAudioTrackId = null; 18816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedVideoTrackId = null; 18826320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedSubtitleTrackId = null; 18836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoWidth = 0; 18846320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoHeight = 0; 18856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 18863957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo try { 18871a6b25eabcc1fb66e6e8d76f91fd413e18b793a9Sungsoo Lim mService.tune(mToken, channelUri, params, mUserId); 18883957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } catch (RemoteException e) { 1889c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 18903957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 18913957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 18929a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 18939a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 18942c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * Enables or disables the caption for this session. 18952c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * 18962c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo * @param enabled {@code true} to enable, {@code false} to disable. 18972c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo */ 18982c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo public void setCaptionEnabled(boolean enabled) { 18992c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo if (mToken == null) { 19002c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo Log.w(TAG, "The session has been already released"); 19012c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo return; 19022c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 19032c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo try { 19042c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo mService.setCaptionEnabled(mToken, enabled, mUserId); 19052c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } catch (RemoteException e) { 1906c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 19072c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 19082c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo } 19092c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo 19102c1c31c7ae9bd972b974a5cc2d8b0942746af612Jae Seo /** 19111f81b1040f40a3233981f34268b11e5c9ad9f34cDongwon Kang * Selects a track. 19121f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * 191310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the track to select. The type can be 191410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or 191510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_SUBTITLE}. 191610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param trackId The ID of the track to select. When {@code null}, the currently selected 191710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * track of the given type will be unselected. 19185b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo * @see #getTracks 19191f213914c45c23c653f721690da2ce0718e63139Dongwon Kang */ 19204bf607b00c14c031e991ac9dc0ad49b9249c9162Dongwon Kang public void selectTrack(int type, @Nullable String trackId) { 19216f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mMetadataLock) { 19226320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 19236320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mAudioTracks, trackId)) { 19246320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid audio trackId: " + trackId); 19256320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 19266320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 19276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 19286320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mVideoTracks, trackId)) { 19296320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid video trackId: " + trackId); 19306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 19316320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 19326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 19336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (trackId != null && !containsTrack(mSubtitleTracks, trackId)) { 19346320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo Log.w(TAG, "Invalid subtitle trackId: " + trackId); 19356320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return; 19366320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 19376320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else { 19386320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo throw new IllegalArgumentException("invalid type: " + type); 193910d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo } 19401f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 19411f213914c45c23c653f721690da2ce0718e63139Dongwon Kang if (mToken == null) { 19421f213914c45c23c653f721690da2ce0718e63139Dongwon Kang Log.w(TAG, "The session has been already released"); 19431f213914c45c23c653f721690da2ce0718e63139Dongwon Kang return; 19441f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 19451f213914c45c23c653f721690da2ce0718e63139Dongwon Kang try { 194610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo mService.selectTrack(mToken, type, trackId, mUserId); 19471f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } catch (RemoteException e) { 1948c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 19491f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 19501f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 19511f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 1952984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee private boolean containsTrack(List<TvTrackInfo> tracks, String trackId) { 1953984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee for (TvTrackInfo track : tracks) { 1954984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee if (track.getId().equals(trackId)) { 1955984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee return true; 1956984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1957984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1958984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee return false; 1959984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee } 1960984d99b584b4d24c160a8725e1624c68ac70f122Chulwoo Lee 19611f213914c45c23c653f721690da2ce0718e63139Dongwon Kang /** 196210d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * Returns the list of tracks for a given type. Returns {@code null} if the information is 196310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * not available. 19641f213914c45c23c653f721690da2ce0718e63139Dongwon Kang * 196510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO}, 196610d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}. 196710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @return the list of tracks for the given type. 19681f213914c45c23c653f721690da2ce0718e63139Dongwon Kang */ 19694bf607b00c14c031e991ac9dc0ad49b9249c9162Dongwon Kang @Nullable 197010d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public List<TvTrackInfo> getTracks(int type) { 19716f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mMetadataLock) { 19726320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 19736320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mAudioTracks == null) { 19746320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 19756320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 1976093d994965bef197fb676731fc50f6f6f630b8feJae Seo return new ArrayList<>(mAudioTracks); 19776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 19786320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mVideoTracks == null) { 19796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 19806320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 1981093d994965bef197fb676731fc50f6f6f630b8feJae Seo return new ArrayList<>(mVideoTracks); 19826320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 19836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mSubtitleTracks == null) { 19846320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 19856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 1986093d994965bef197fb676731fc50f6f6f630b8feJae Seo return new ArrayList<>(mSubtitleTracks); 198710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo } 19881f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 198910d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo throw new IllegalArgumentException("invalid type: " + type); 19901f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 19911f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 1992d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo /** 199310d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * Returns the selected track for a given type. Returns {@code null} if the information is 199410d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * not available or any of the tracks for the given type is not selected. 199510d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * 1996a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * @return The ID of the selected track. 199710d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo * @see #selectTrack 1998d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo */ 19994bf607b00c14c031e991ac9dc0ad49b9249c9162Dongwon Kang @Nullable 200010d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo public String getSelectedTrack(int type) { 20016f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mMetadataLock) { 20026320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (type == TvTrackInfo.TYPE_AUDIO) { 20036320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedAudioTrackId; 20046320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO) { 20056320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedVideoTrackId; 20066320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE) { 20076320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return mSelectedSubtitleTrackId; 20086320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 2009d5ce9759524740cfb02638fd1d7b44315957b422Jae Seo } 201010d285ac06b3d3060c7d90d3dc196d4ac8367467Jae Seo throw new IllegalArgumentException("invalid type: " + type); 20111f213914c45c23c653f721690da2ce0718e63139Dongwon Kang } 20121f213914c45c23c653f721690da2ce0718e63139Dongwon Kang 20131f213914c45c23c653f721690da2ce0718e63139Dongwon Kang /** 20146320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Responds to onTracksChanged() and updates the internal track information. Returns true if 20156320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * there is an update. 20166320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 20176320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo boolean updateTracks(List<TvTrackInfo> tracks) { 20186f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mMetadataLock) { 20196320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.clear(); 20206320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.clear(); 20216320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.clear(); 20226320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo for (TvTrackInfo track : tracks) { 20236320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track.getType() == TvTrackInfo.TYPE_AUDIO) { 20246320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mAudioTracks.add(track); 20256320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) { 20266320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoTracks.add(track); 20276320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) { 20286320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSubtitleTracks.add(track); 20296320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20306320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20316320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return !mAudioTracks.isEmpty() || !mVideoTracks.isEmpty() 20326320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo || !mSubtitleTracks.isEmpty(); 20336320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20346320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20356320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 20366320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 20376320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Responds to onTrackSelected() and updates the internal track selection information. 20386320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns true if there is an update. 20396320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 20406320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo boolean updateTrackSelection(int type, String trackId) { 20416f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mMetadataLock) { 2042777718220cdacb82e984c7ea8915e36ea203e5a2Jae Seo if (type == TvTrackInfo.TYPE_AUDIO 2043777718220cdacb82e984c7ea8915e36ea203e5a2Jae Seo && !TextUtils.equals(trackId, mSelectedAudioTrackId)) { 20446320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedAudioTrackId = trackId; 20456320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 2046777718220cdacb82e984c7ea8915e36ea203e5a2Jae Seo } else if (type == TvTrackInfo.TYPE_VIDEO 2047777718220cdacb82e984c7ea8915e36ea203e5a2Jae Seo && !TextUtils.equals(trackId, mSelectedVideoTrackId)) { 20486320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedVideoTrackId = trackId; 20496320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 20506320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } else if (type == TvTrackInfo.TYPE_SUBTITLE 2051777718220cdacb82e984c7ea8915e36ea203e5a2Jae Seo && !TextUtils.equals(trackId, mSelectedSubtitleTrackId)) { 20526320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mSelectedSubtitleTrackId = trackId; 20536320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return true; 20546320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20556320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20566320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return false; 20576320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20586320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 20596320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 20606320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * Returns the new/updated video track that contains new video size information. Returns 20616320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * null if there is no video track to notify. Subsequent calls of this method results in a 20626320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * non-null video track returned only by the first call and null returned by following 20636320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * calls. The caller should immediately notify of the video size change upon receiving the 20646320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo * track. 20656320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo */ 20666320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo TvTrackInfo getVideoTrackToNotify() { 20676f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang synchronized (mMetadataLock) { 20686320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (!mVideoTracks.isEmpty() && mSelectedVideoTrackId != null) { 20696320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo for (TvTrackInfo track : mVideoTracks) { 20706320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (track.getId().equals(mSelectedVideoTrackId)) { 20716320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo int videoWidth = track.getVideoWidth(); 20726320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo int videoHeight = track.getVideoHeight(); 20736320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo if (mVideoWidth != videoWidth || mVideoHeight != videoHeight) { 20746320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoWidth = videoWidth; 20756320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo mVideoHeight = videoHeight; 20766320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return track; 20776320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20786320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20796320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20806320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20816320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20826320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo return null; 20836320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo } 20846320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo 20856320fc490fe73b089cdccfc617e4b09f31f5d203Jae Seo /** 2086a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo * Plays a given recorded TV program. 2087a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 2088a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo void timeShiftPlay(Uri recordedProgramUri) { 2089a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo if (mToken == null) { 2090a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo Log.w(TAG, "The session has been already released"); 2091a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo return; 2092a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2093a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo try { 2094a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mService.timeShiftPlay(mToken, recordedProgramUri, mUserId); 2095a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } catch (RemoteException e) { 2096c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 2097a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2098a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2099a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 2100a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 21016f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * Pauses the playback. Call {@link #timeShiftResume()} to restart the playback. 21026f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 21036f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang void timeShiftPause() { 21046f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (mToken == null) { 21056f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.w(TAG, "The session has been already released"); 21066f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 21076f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21086f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang try { 21096f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mService.timeShiftPause(mToken, mUserId); 21106f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } catch (RemoteException e) { 2111c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 21126f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21136f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21146f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 21156f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 21166f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * Resumes the playback. No-op if it is already playing the channel. 21176f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 21186f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang void timeShiftResume() { 21196f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (mToken == null) { 21206f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.w(TAG, "The session has been already released"); 21216f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 21226f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21236f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang try { 21246f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mService.timeShiftResume(mToken, mUserId); 21256f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } catch (RemoteException e) { 2126c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 21276f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21286f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21296f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 21306f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 2131465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * Seeks to a specified time position. 21320610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * 21330610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * <p>Normally, the position is given within range between the start and the current time, 2134465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * inclusively. 21356f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * 2136465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * @param timeMs The time position to seek to, in milliseconds since the epoch. 2137465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * @see TvView.TimeShiftPositionCallback#onTimeShiftStartPositionChanged 21386f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 21396f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang void timeShiftSeekTo(long timeMs) { 21406f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (mToken == null) { 21416f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.w(TAG, "The session has been already released"); 21426f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 21436f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21446f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang try { 21456f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang mService.timeShiftSeekTo(mToken, timeMs, mUserId); 21466f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } catch (RemoteException e) { 2147c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 21486f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21496f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21506f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 21516f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 21524b34cc77630112d00e9a87498d05f5f8803a9ff6Jae Seo * Sets playback rate using {@link android.media.PlaybackParams}. 21536f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang * 21544b34cc77630112d00e9a87498d05f5f8803a9ff6Jae Seo * @param params The playback params. 21556f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 21564b34cc77630112d00e9a87498d05f5f8803a9ff6Jae Seo void timeShiftSetPlaybackParams(PlaybackParams params) { 21576f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (mToken == null) { 21586f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.w(TAG, "The session has been already released"); 21596f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 21606f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21616f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang try { 21624b34cc77630112d00e9a87498d05f5f8803a9ff6Jae Seo mService.timeShiftSetPlaybackParams(mToken, params, mUserId); 21636f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } catch (RemoteException e) { 2164c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 21656f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21666f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21676f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 21686f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 2169465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * Enable/disable position tracking. 2170465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * 2171465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo * @param enable {@code true} to enable tracking, {@code false} otherwise. 21726f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang */ 2173465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo void timeShiftEnablePositionTracking(boolean enable) { 21746f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang if (mToken == null) { 21756f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang Log.w(TAG, "The session has been already released"); 21766f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang return; 21776f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 21786f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang try { 2179465f0d6aa36f2f1db88603aa487bcba9f5af068dJae Seo mService.timeShiftEnablePositionTracking(mToken, enable, mUserId); 21806f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } catch (RemoteException e) { 2181c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 2182a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2183a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2184a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 2185a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 21864eee6a73e476cd2d82a69f3a535628901047f140Jae Seo * Starts TV program recording in the current recording session. 21874eee6a73e476cd2d82a69f3a535628901047f140Jae Seo * 21880cb5244e52590214ddc16dd5fc1030b5baf04726Dongwon Kang * @param programUri The URI for the TV program to record as a hint, built by 21894eee6a73e476cd2d82a69f3a535628901047f140Jae Seo * {@link TvContract#buildProgramUri(long)}. Can be {@code null}. 2190a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 21910cb5244e52590214ddc16dd5fc1030b5baf04726Dongwon Kang void startRecording(@Nullable Uri programUri) { 2192a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo if (mToken == null) { 2193a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo Log.w(TAG, "The session has been already released"); 2194a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo return; 2195a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2196a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo try { 21970cb5244e52590214ddc16dd5fc1030b5baf04726Dongwon Kang mService.startRecording(mToken, programUri, mUserId); 2198a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } catch (RemoteException e) { 2199c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 2200a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2201a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2202a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo 2203a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo /** 22044eee6a73e476cd2d82a69f3a535628901047f140Jae Seo * Stops TV program recording in the current recording session. 2205a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo */ 2206a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo void stopRecording() { 2207a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo if (mToken == null) { 2208a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo Log.w(TAG, "The session has been already released"); 2209a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo return; 2210a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } 2211a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo try { 2212a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo mService.stopRecording(mToken, mUserId); 2213a826d0172aae5e91d633ffe606059a2355fbf7e5Jae Seo } catch (RemoteException e) { 2214c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 22156f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 22166f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang } 22176f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang 22186f0240cf63fe62b0af2c7d5112f9881d1e167bfcDongwon Kang /** 22191f81b1040f40a3233981f34268b11e5c9ad9f34cDongwon Kang * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle) 2220a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * TvInputService.Session.appPrivateCommand()} on the current TvView. 2221a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * 2222a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @param action Name of the command to be performed. This <em>must</em> be a scoped name, 2223a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * i.e. prefixed with a package name you own, so that different developers will 2224a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * not create conflicting commands. 2225a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo * @param data Any data to include with the command. 2226a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo */ 2227a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo public void sendAppPrivateCommand(String action, Bundle data) { 2228a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo if (mToken == null) { 2229a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo Log.w(TAG, "The session has been already released"); 2230a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo return; 2231a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 2232a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo try { 2233a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo mService.sendAppPrivateCommand(mToken, action, data, mUserId); 2234a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } catch (RemoteException e) { 2235c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 2236a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 2237a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo } 2238a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo 2239a759b111a1c9cb00284038f8a1554bf29709b952Jae Seo /** 22409a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Creates an overlay view. Once the overlay view is created, {@link #relayoutOverlayView} 22419a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * should be called whenever the layout of its containing view is changed. 22429a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * {@link #removeOverlayView()} should be called to remove the overlay view. 22439a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Since a session can have only one overlay view, this method should be called only once 22449a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * or it can be called again after calling {@link #removeOverlayView()}. 22459a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * 22469a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param view A view playing TV. 22479a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param frame A position of the overlay view. 2248dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim * @throws IllegalStateException if {@code view} is not attached to a window. 22499a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 2250de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo void createOverlayView(@NonNull View view, @NonNull Rect frame) { 2251de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(view); 2252de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(frame); 22539a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (view.getWindowToken() == null) { 22549a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho throw new IllegalStateException("view must be attached to a window"); 22559a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22569a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 2257dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 2258dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 22599a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22609a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 22619a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.createOverlayView(mToken, view.getWindowToken(), frame, mUserId); 22629a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 2263c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 22649a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22659a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22669a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 22679a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 22689a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Relayouts the current overlay view. 22699a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * 22709a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * @param frame A new position of the overlay view. 22719a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 2272de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo void relayoutOverlayView(@NonNull Rect frame) { 2273de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(frame); 22749a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 2275dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 2276dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 22779a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22789a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 22799a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.relayoutOverlayView(mToken, frame, mUserId); 22809a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 2281c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 22829a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22839a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22849a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho 22859a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho /** 22869a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho * Removes the current overlay view. 22879a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho */ 22889a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho void removeOverlayView() { 22899a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho if (mToken == null) { 2290dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim Log.w(TAG, "The session has been already released"); 2291dc952584e37fca96ad0e02e13b2438038fef6befSungsoo Lim return; 22929a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22939a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho try { 22949a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho mService.removeOverlayView(mToken, mUserId); 22959a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } catch (RemoteException e) { 2296c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 22979a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22989a22f0f0a631849d9c622c642d3ab0395f77584bYoungsang Cho } 22996a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23006a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 23019bf671f8ee72b156f16fcf05a3d1c6e093ecba67Sungsoo Lim * Requests to unblock content blocked by parental controls. 2302903d6b72cd572665309633e925485464d08bb25aJaewan Kim */ 2303a90338396c90f19b062b696cdb1ffcb8600755b2Jae Seo void unblockContent(@NonNull TvContentRating unblockedRating) { 2304de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(unblockedRating); 2305903d6b72cd572665309633e925485464d08bb25aJaewan Kim if (mToken == null) { 2306903d6b72cd572665309633e925485464d08bb25aJaewan Kim Log.w(TAG, "The session has been already released"); 2307903d6b72cd572665309633e925485464d08bb25aJaewan Kim return; 2308903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 2309903d6b72cd572665309633e925485464d08bb25aJaewan Kim try { 2310a90338396c90f19b062b696cdb1ffcb8600755b2Jae Seo mService.unblockContent(mToken, unblockedRating.flattenToString(), mUserId); 2311903d6b72cd572665309633e925485464d08bb25aJaewan Kim } catch (RemoteException e) { 2312c53962d4ede82a03b62f0c8bb86bd0da090a15ebJeff Sharkey throw e.rethrowFromSystemServer(); 2313903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 2314903d6b72cd572665309633e925485464d08bb25aJaewan Kim } 2315903d6b72cd572665309633e925485464d08bb25aJaewan Kim 2316903d6b72cd572665309633e925485464d08bb25aJaewan Kim /** 23176a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Dispatches an input event to this session. 23186a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 2319de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo * @param event An {@link InputEvent} to dispatch. Cannot be {@code null}. 23206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param token A token used to identify the input event later in the callback. 2321de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo * @param callback A callback used to receive the dispatch result. Cannot be {@code null}. 2322de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo * @param handler A {@link Handler} that the dispatch result will be delivered to. Cannot be 2323de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo * {@code null}. 23246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns 23256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns 23266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will 23276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * be invoked later. 23286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @hide 23296a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 2330de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo public int dispatchInputEvent(@NonNull InputEvent event, Object token, 2331de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo @NonNull FinishedInputEventCallback callback, @NonNull Handler handler) { 2332de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(event); 2333de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(callback); 2334de08be8f79ea40f3dffae9edff4227704a5c0a3aJae Seo Preconditions.checkNotNull(handler); 23356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 23366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mChannel == null) { 23376a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_NOT_HANDLED; 23386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo PendingEvent p = obtainPendingEventLocked(event, token, callback, handler); 23406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (Looper.myLooper() == Looper.getMainLooper()) { 23416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Already running on the main thread so we can send the event immediately. 23426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return sendInputEventOnMainLooperLocked(p); 23436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Post the event to the main thread. 23466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_SEND_INPUT_EVENT, p); 23476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 23486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.sendMessage(msg); 23496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_IN_PROGRESS; 23506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 23546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Callback that is invoked when an input event that was dispatched to this session has been 23556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * finished. 23566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 23576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @hide 23586a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 23596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public interface FinishedInputEventCallback { 23606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo /** 23616a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * Called when the dispatched input event is finished. 23626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * 23638e6b51b0fb810ac990c863cc0579e2b2700ab7d6Jaewan Kim * @param token A token passed to {@link #dispatchInputEvent}. 23646a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * @param handled {@code true} if the dispatched input event was handled properly. 23656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo * {@code false} otherwise. 23666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo */ 23676e4cbfd2e5ffb739269e5e4affc2b6894bc4090eJae Seo void onFinishedInputEvent(Object token, boolean handled); 23686a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23696a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23706a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Must be called on the main looper 23716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void sendInputEventAndReportResultOnMainLooper(PendingEvent p) { 23726a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 23736a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int result = sendInputEventOnMainLooperLocked(p); 23746a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (result == DISPATCH_IN_PROGRESS) { 23756a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 23766a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23776a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23786a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23796a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo invokeFinishedInputEventCallback(p, false); 23806a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23816a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23826a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private int sendInputEventOnMainLooperLocked(PendingEvent p) { 23836a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mChannel != null) { 23846a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mSender == null) { 23856a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mSender = new TvInputEventSender(mChannel, mHandler.getLooper()); 23866a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23876a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23886a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final InputEvent event = p.mEvent; 23896a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final int seq = event.getSequenceNumber(); 23906a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (mSender.sendInputEvent(seq, event)) { 23916a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEvents.put(seq, p); 23926a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p); 23936a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 23946a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.sendMessageDelayed(msg, INPUT_SESSION_NOT_RESPONDING_TIMEOUT); 23956a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_IN_PROGRESS; 23966a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 23976a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 23986a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Log.w(TAG, "Unable to send input event to session: " + mToken + " dropping:" 23996a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo + event); 24006a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24016a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return DISPATCH_NOT_HANDLED; 24026a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24036a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24046a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo void finishedInputEvent(int seq, boolean handled, boolean timeout) { 24056a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final PendingEvent p; 24066a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo synchronized (mHandler) { 24076a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int index = mPendingEvents.indexOfKey(seq); 24086a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (index < 0) { 24096a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; // spurious, event already finished or timed out 24106a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24116a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24126a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p = mPendingEvents.valueAt(index); 24136a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEvents.removeAt(index); 24146a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24156a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (timeout) { 241640c5c7dcdc9f39100833e86884d86fb7643ffa4bJae Seo Log.w(TAG, "Timeout waiting for session to handle input event after " 24176a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo + INPUT_SESSION_NOT_RESPONDING_TIMEOUT + " ms: " + mToken); 24186a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } else { 24196a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.removeMessages(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p); 24206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo invokeFinishedInputEventCallback(p, handled); 24246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Assumes the event has already been removed from the queue. 24276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) { 24286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mHandled = handled; 24295b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo if (p.mEventHandler.getLooper().isCurrentThread()) { 24306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Already running on the callback handler thread so we can send the callback 24316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // immediately. 24326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.run(); 24336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } else { 24346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // Post the event to the callback handler thread. 24356a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo // In this case, the callback will be responsible for recycling the event. 24365b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo Message msg = Message.obtain(p.mEventHandler, p); 24376a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 24386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.sendToTarget(); 24396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24426a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void flushPendingEventsLocked() { 24436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandler.removeMessages(InputEventHandler.MSG_FLUSH_INPUT_EVENT); 24446a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo final int count = mPendingEvents.size(); 24466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo for (int i = 0; i < count; i++) { 24476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo int seq = mPendingEvents.keyAt(i); 24486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo Message msg = mHandler.obtainMessage(InputEventHandler.MSG_FLUSH_INPUT_EVENT, seq, 0); 24496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.setAsynchronous(true); 24506a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo msg.sendToTarget(); 24516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24526a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private PendingEvent obtainPendingEventLocked(InputEvent event, Object token, 24556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo FinishedInputEventCallback callback, Handler handler) { 24566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo PendingEvent p = mPendingEventPool.acquire(); 24576a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo if (p == null) { 24586a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p = new PendingEvent(); 24596a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24606a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mEvent = event; 24615b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo p.mEventToken = token; 24626a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.mCallback = callback; 24635b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo p.mEventHandler = handler; 24646a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return p; 24656a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24666a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24676a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private void recyclePendingEventLocked(PendingEvent p) { 24686a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo p.recycle(); 24696a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mPendingEventPool.release(p); 24706a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 24716a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 2472bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang IBinder getToken() { 2473bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang return mToken; 2474bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang } 2475bd2fa2c02d916a9b6c62f8fd8701d779c00bd68dDongwon Kang 24762b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim private void releaseInternal() { 24772b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mToken = null; 24782b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mHandler) { 24792b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (mChannel != null) { 24802b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim if (mSender != null) { 24812b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim flushPendingEventsLocked(); 24822b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSender.dispose(); 24832b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSender = null; 24842b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 24852b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mChannel.dispose(); 24862b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mChannel = null; 24872b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 24882b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 24892b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim synchronized (mSessionCallbackRecordMap) { 24902b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim mSessionCallbackRecordMap.remove(mSeq); 24912b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 24922b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim } 24932b35a72a69f6fc39d21f7de9e21044d64db1380dSungsoo Lim 24946a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class InputEventHandler extends Handler { 24956a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_SEND_INPUT_EVENT = 1; 24966a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_TIMEOUT_INPUT_EVENT = 2; 24976a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public static final int MSG_FLUSH_INPUT_EVENT = 3; 24986a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 24996a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo InputEventHandler(Looper looper) { 25006a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo super(looper, null, true); 25016a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25026a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 25036a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 25046a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void handleMessage(Message msg) { 25056a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo switch (msg.what) { 25066a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_SEND_INPUT_EVENT: { 25076a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo sendInputEventAndReportResultOnMainLooper((PendingEvent) msg.obj); 25086a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 25096a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25106a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_TIMEOUT_INPUT_EVENT: { 25116a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(msg.arg1, false, true); 25126a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 25136a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25146a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo case MSG_FLUSH_INPUT_EVENT: { 25156a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(msg.arg1, false, false); 25166a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo return; 25176a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25186a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25196a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25206a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25216a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 25226a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class TvInputEventSender extends InputEventSender { 25236a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public TvInputEventSender(InputChannel inputChannel, Looper looper) { 25246a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo super(inputChannel, looper); 25256a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25266a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 25276a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 25286a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void onInputEventFinished(int seq, boolean handled) { 25296a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo finishedInputEvent(seq, handled, false); 25306a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25316a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25326a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 25336a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo private final class PendingEvent implements Runnable { 25346a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public InputEvent mEvent; 25355b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo public Object mEventToken; 25366a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public FinishedInputEventCallback mCallback; 25375b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo public Handler mEventHandler; 25386a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public boolean mHandled; 25396a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 25406a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void recycle() { 25416a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mEvent = null; 25425b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mEventToken = null; 25436a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mCallback = null; 25445b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mEventHandler = null; 25456a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo mHandled = false; 25466a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25476a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 25486a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo @Override 25496a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo public void run() { 25505b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo mCallback.onFinishedInputEvent(mEventToken, mHandled); 25516a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo 25525b1caaf7d8408bf0ce78d8d7a36f4649dda17797Jae Seo synchronized (mEventHandler) { 25536a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo recyclePendingEventLocked(this); 25546a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25556a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25566a6059a29edf31e65541b3d8927a46f5846fb0a2Jae Seo } 25573957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo } 2558d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 2559d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim /** 2560d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * The Hardware provides the per-hardware functionality of TV hardware. 2561d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 25620610e12733875a267f59d87a2a68aebbf486066eDongwon Kang * <p>TV hardware is physical hardware attached to the Android device; for example, HDMI ports, 2563d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * Component/Composite ports, etc. Specifically, logical devices such as HDMI CEC logical 2564d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * devices don't fall into this category. 2565d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * 2566d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim * @hide 2567d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim */ 2568d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim @SystemApi 2569d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public final static class Hardware { 2570d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private final ITvInputHardware mInterface; 2571d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 2572d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private Hardware(ITvInputHardware hardwareInterface) { 2573d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface = hardwareInterface; 2574d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2575d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 2576d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim private ITvInputHardware getInterface() { 2577d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface; 2578d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2579d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 2580d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public boolean setSurface(Surface surface, TvStreamConfig config) { 2581d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 2582d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim return mInterface.setSurface(surface, config); 2583d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 2584d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 2585d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2586d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2587d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 2588d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void setStreamVolume(float volume) { 2589d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 2590d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface.setStreamVolume(volume); 2591d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 2592d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 2593d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2594d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2595d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 259615985cbafafea12e23cffb5a7eaa85e4682bd5a6Shubang /** @removed */ 25979650a435ed909ed4062d64fd2d9b085628d4a455Jeff Sharkey @SystemApi 2598d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public boolean dispatchKeyEventToHdmi(KeyEvent event) { 259915985cbafafea12e23cffb5a7eaa85e4682bd5a6Shubang return false; 2600d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2601d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim 2602d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim public void overrideAudioSink(int audioType, String audioAddress, int samplingRate, 2603d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim int channelMask, int format) { 2604d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim try { 2605d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim mInterface.overrideAudioSink(audioType, audioAddress, samplingRate, channelMask, 2606d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim format); 2607d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } catch (RemoteException e) { 2608d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim throw new RuntimeException(e); 2609d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2610d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 2611d71c691bc56ef4c5c3cf6b4cabcc450d6b1820c0Wonsik Kim } 26123957091ba8f08c02b5e781098cb955a5f697a1ffJae Seo} 2613