• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 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.common.util;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.media.tv.TvInputInfo;
22 import android.os.Build;
23 import android.util.ArraySet;
24 import android.util.Log;
25 import com.android.tv.common.BuildConfig;
26 import com.android.tv.common.CommonConstants;
27 import com.android.tv.common.actions.InputSetupActionUtils;
28 import com.android.tv.common.experiments.Experiments;
29 import java.io.File;
30 import java.text.SimpleDateFormat;
31 import java.util.Date;
32 import java.util.Locale;
33 import java.util.Set;
34 
35 /** Util class for common use in TV app and inputs. */
36 @SuppressWarnings("AndroidApiChecker") // TODO(b/32513850) remove when error prone is updated
37 public final class CommonUtils {
38     private static final String TAG = "CommonUtils";
39     private static final ThreadLocal<SimpleDateFormat> ISO_8601 =
40             new ThreadLocal() {
41                 private final SimpleDateFormat value =
42                         new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);
43 
44                 @Override
45                 protected SimpleDateFormat initialValue() {
46                     return value;
47                 }
48             };
49     // Hardcoded list for known bundled inputs not written by OEM/SOCs.
50     // Bundled (system) inputs not in the list will get the high priority
51     // so they and their channels come first in the UI.
52     private static final Set<String> BUNDLED_PACKAGE_SET = new ArraySet<>();
53 
54     static {
55         BUNDLED_PACKAGE_SET.add("com.android.tv");
56     }
57 
58     private static Boolean sRunningInTest;
59 
CommonUtils()60     private CommonUtils() {}
61 
62     /**
63      * Returns an intent to start the setup activity for the TV input using {@link
64      * InputSetupActionUtils#INTENT_ACTION_INPUT_SETUP}.
65      */
createSetupIntent(Intent originalSetupIntent, String inputId)66     public static Intent createSetupIntent(Intent originalSetupIntent, String inputId) {
67         if (originalSetupIntent == null) {
68             return null;
69         }
70         Intent setupIntent = new Intent(originalSetupIntent);
71         if (!InputSetupActionUtils.hasInputSetupAction(originalSetupIntent)) {
72             Intent intentContainer = new Intent(InputSetupActionUtils.INTENT_ACTION_INPUT_SETUP);
73             intentContainer.putExtra(InputSetupActionUtils.EXTRA_SETUP_INTENT, originalSetupIntent);
74             intentContainer.putExtra(InputSetupActionUtils.EXTRA_INPUT_ID, inputId);
75             setupIntent = intentContainer;
76         }
77         return setupIntent;
78     }
79 
80     /**
81      * Returns an intent to start the setup activity for this TV input using {@link
82      * InputSetupActionUtils#INTENT_ACTION_INPUT_SETUP}.
83      */
createSetupIntent(TvInputInfo input)84     public static Intent createSetupIntent(TvInputInfo input) {
85         return createSetupIntent(input.createSetupIntent(), input.getId());
86     }
87 
88     /**
89      * Checks if this application is running in tests.
90      *
91      * <p>{@link android.app.ActivityManager#isRunningInTestHarness} doesn't return {@code true} for
92      * the usual devices even the application is running in tests. We need to figure it out by
93      * checking whether the class in tv-tests-common module can be loaded or not.
94      */
isRunningInTest()95     public static synchronized boolean isRunningInTest() {
96         if (sRunningInTest == null) {
97             try {
98                 Class.forName("com.android.tv.testing.utils.Utils");
99                 Log.i(
100                         TAG,
101                         "Assumed to be running in a test because"
102                                 + " com.android.tv.testing.utils.Utils is found");
103                 sRunningInTest = true;
104             } catch (ClassNotFoundException e) {
105                 sRunningInTest = false;
106             }
107         }
108         return sRunningInTest;
109     }
110 
111     /** Checks whether a given package is in our bundled package set. */
isInBundledPackageSet(String packageName)112     public static boolean isInBundledPackageSet(String packageName) {
113         return BUNDLED_PACKAGE_SET.contains(packageName);
114     }
115 
116     /** Checks whether a given input is a bundled input. */
isBundledInput(String inputId)117     public static boolean isBundledInput(String inputId) {
118         for (String prefix : BUNDLED_PACKAGE_SET) {
119             if (inputId.startsWith(prefix + "/")) {
120                 return true;
121             }
122         }
123         return false;
124     }
125 
126     /** Returns true if the application is packaged with Live TV. */
isPackagedWithLiveChannels(Context context)127     public static boolean isPackagedWithLiveChannels(Context context) {
128         return (CommonConstants.BASE_PACKAGE.equals(context.getPackageName()));
129     }
130 
131     /** Returns true if the current user is a developer. */
isDeveloper()132     public static boolean isDeveloper() {
133         return BuildConfig.ENG || Experiments.ENABLE_DEVELOPER_FEATURES.get();
134     }
135 
136     /** Converts time in milliseconds to a ISO 8061 string. */
toIsoDateTimeString(long timeMillis)137     public static String toIsoDateTimeString(long timeMillis) {
138         return ISO_8601.get().format(new Date(timeMillis));
139     }
140 
141     /**
142      * Deletes a file or a directory.
143      *
144      * @return <code>true</code> if and only if the file or directory is successfully deleted;
145      *     <code>false</code> otherwise
146      */
deleteDirOrFile(File fileOrDirectory)147     public static boolean deleteDirOrFile(File fileOrDirectory) {
148         if (fileOrDirectory.isDirectory()) {
149             File[] files = fileOrDirectory.listFiles();
150             if (files != null) {
151                 for (File child : files) {
152                     deleteDirOrFile(child);
153                 }
154             }
155         }
156         // If earlier deletes failed this will also
157         return fileOrDirectory.delete();
158     }
159 
isRoboTest()160     public static boolean isRoboTest() {
161         return "robolectric".equals(Build.FINGERPRINT);
162     }
163 }
164