• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.tv;
18 
19 import android.content.Context;
20 import android.content.pm.PackageManager;
21 import android.os.Build;
22 import android.support.annotation.VisibleForTesting;
23 import android.text.TextUtils;
24 import android.util.Log;
25 
26 import com.android.tv.common.feature.Feature;
27 import com.android.tv.common.feature.GServiceFeature;
28 import com.android.tv.common.feature.PropertyFeature;
29 import com.android.tv.config.RemoteConfig;
30 import com.android.tv.experiments.Experiments;
31 import com.android.tv.util.LocationUtils;
32 import com.android.tv.util.PermissionUtils;
33 import com.android.tv.util.Utils;
34 
35 import java.util.Locale;
36 
37 import static com.android.tv.common.feature.EngOnlyFeature.ENG_ONLY_FEATURE;
38 import static com.android.tv.common.feature.FeatureUtils.AND;
39 import static com.android.tv.common.feature.FeatureUtils.OFF;
40 import static com.android.tv.common.feature.FeatureUtils.ON;
41 import static com.android.tv.common.feature.FeatureUtils.OR;
42 
43 /**
44  * List of {@link Feature} for the Live TV App.
45  *
46  * <p>Remove the {@code Feature} once it is launched.
47  */
48 public final class Features {
49     private static final String TAG = "Features";
50     private static final boolean DEBUG = false;
51 
52     /**
53      * UI for opting in to analytics.
54      *
55      * <p>Do not turn this on until the splash screen asking existing users to opt-in is launched.
56      * See <a href="http://b/20228119">b/20228119</a>
57      */
58     public static final Feature ANALYTICS_OPT_IN = ENG_ONLY_FEATURE;
59 
60     /**
61      * Analytics that include sensitive information such as channel or program identifiers.
62      *
63      * <p>See <a href="http://b/22062676">b/22062676</a>
64      */
65     public static final Feature ANALYTICS_V2 = AND(ON, ANALYTICS_OPT_IN);
66 
67     public static final Feature EPG_SEARCH =
68             new PropertyFeature("feature_tv_use_epg_search", false);
69 
70     public static final Feature TUNER =
71             new Feature() {
72                 @Override
73                 public boolean isEnabled(Context context) {
74 
75                     if (Utils.isDeveloper()) {
76                         // we enable tuner for developers to test tuner in any platform.
77                         return true;
78                     }
79 
80                     // This is special handling just for USB Tuner.
81                     // It does not require any N API's but relies on a improvements in N for AC3 support
82                     return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;
83                 }
84             };
85 
86     /**
87      * Use network tuner if it is available and there is no other tuner types.
88      */
89     public static final Feature NETWORK_TUNER =
90             new Feature() {
91                 @Override
92                 public boolean isEnabled(Context context) {
93                     if (!TUNER.isEnabled(context)) {
94                         return false;
95                     }
96                     if (Utils.isDeveloper()) {
97                         // Network tuner will be enabled for developers.
98                         return true;
99                     }
100                     return Locale.US.getCountry().equalsIgnoreCase(
101                             LocationUtils.getCurrentCountry(context));
102                 }
103             };
104 
105     private static final String GSERVICE_KEY_UNHIDE = "live_channels_unhide";
106     /**
107      * A flag which indicates that LC app is unhidden even when there is no input.
108      */
109     public static final Feature UNHIDE =
110             OR(new GServiceFeature(GSERVICE_KEY_UNHIDE, false), new Feature() {
111                 @Override
112                 public boolean isEnabled(Context context) {
113                     // If LC app runs as non-system app, we unhide the app.
114                     return !PermissionUtils.hasAccessAllEpg(context);
115                 }
116             });
117 
118     public static final Feature PICTURE_IN_PICTURE =
119             new Feature() {
120                 private Boolean mEnabled;
121 
122                 @Override
123                 public boolean isEnabled(Context context) {
124                     if (mEnabled == null) {
125                         mEnabled =
126                                 Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
127                                         && context.getPackageManager()
128                                                 .hasSystemFeature(
129                                                         PackageManager.FEATURE_PICTURE_IN_PICTURE);
130                     }
131                     return mEnabled;
132                 }
133             };
134 
135     /** Use AC3 software decode. */
136     public static final Feature AC3_SOFTWARE_DECODE =
137             new Feature() {
138                 private final String[] SUPPORTED_REGIONS = {};
139 
140                 private Boolean mEnabled;
141 
142                 @Override
143                 public boolean isEnabled(Context context) {
144                     if (mEnabled == null) {
145                         if (mEnabled == null) {
146                             // We will not cache the result of fallback solution.
147                             String country = LocationUtils.getCurrentCountry(context);
148                             for (int i = 0; i < SUPPORTED_REGIONS.length; ++i) {
149                                 if (SUPPORTED_REGIONS[i].equalsIgnoreCase(country)) {
150                                     return true;
151                                 }
152                             }
153                             if (DEBUG) Log.d(TAG, "AC3 flag false after country check");
154                             return false;
155                         }
156                     }
157                     if (DEBUG) Log.d(TAG, "AC3 flag " + mEnabled);
158                     return mEnabled;
159                 }
160             };
161 
162     /** Show postal code fragment before channel scan. */
163     public static final Feature ENABLE_CLOUD_EPG_REGION =
164             new Feature() {
165                 private final String[] SUPPORTED_REGIONS = {
166                 };
167 
168 
169                 @Override
170                 public boolean isEnabled(Context context) {
171                     if (!Experiments.CLOUD_EPG.get()) {
172                         if (DEBUG) Log.d(TAG, "Experiments.CLOUD_EPG is false");
173                         return false;
174                     }
175                     String country = LocationUtils.getCurrentCountry(context);
176                     for (int i = 0; i < SUPPORTED_REGIONS.length; i++) {
177                         if (SUPPORTED_REGIONS[i].equalsIgnoreCase(country)) {
178                             return true;
179                         }
180                     }
181                     if (DEBUG) Log.d(TAG, "EPG flag false after country check");
182                     return false;
183                 }
184             };
185 
186     /** Enable a conflict dialog between currently watched channel and upcoming recording. */
187     public static final Feature SHOW_UPCOMING_CONFLICT_DIALOG = OFF;
188 
189     /**
190      * Use input blacklist to disable partner's tuner input.
191      */
192     public static final Feature USE_PARTNER_INPUT_BLACKLIST = ON;
193 
194     /**
195      * Enable Dvb parsers and listeners.
196      */
197     public static final Feature ENABLE_FILE_DVB = OFF;
198 
199     @VisibleForTesting
200     public static final Feature TEST_FEATURE = new PropertyFeature("test_feature", false);
201 
Features()202     private Features() {
203     }
204 }
205