aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/util')
-rw-r--r--src/com/android/tv/util/AccountHelper.java (renamed from src/com/android/tv/util/account/AccountHelperImpl.java)29
-rw-r--r--src/com/android/tv/util/AsyncDbTask.java4
-rw-r--r--src/com/android/tv/util/BitmapUtils.java1
-rw-r--r--src/com/android/tv/util/Clock.java64
-rw-r--r--src/com/android/tv/util/Debug.java50
-rw-r--r--src/com/android/tv/util/DurationTimer.java80
-rw-r--r--src/com/android/tv/util/ImageLoader.java1
-rw-r--r--src/com/android/tv/util/LocationUtils.java137
-rw-r--r--src/com/android/tv/util/NamedThreadFactory.java45
-rw-r--r--src/com/android/tv/util/NetworkTrafficTags.java63
-rw-r--r--src/com/android/tv/util/OnboardingUtils.java8
-rw-r--r--src/com/android/tv/util/PermissionUtils.java53
-rw-r--r--src/com/android/tv/util/RecurringRunner.java2
-rw-r--r--src/com/android/tv/util/SetupUtils.java53
-rw-r--r--src/com/android/tv/util/SqlParams.java74
-rw-r--r--src/com/android/tv/util/StringUtils.java34
-rw-r--r--src/com/android/tv/util/SystemProperties.java53
-rw-r--r--src/com/android/tv/util/TvInputManagerHelper.java104
-rw-r--r--src/com/android/tv/util/Utils.java69
-rw-r--r--src/com/android/tv/util/ViewCache.java15
-rw-r--r--src/com/android/tv/util/account/AccountHelper.java38
21 files changed, 697 insertions, 280 deletions
diff --git a/src/com/android/tv/util/account/AccountHelperImpl.java b/src/com/android/tv/util/AccountHelper.java
index 58fbd27e..a3e6ad58 100644
--- a/src/com/android/tv/util/account/AccountHelperImpl.java
+++ b/src/com/android/tv/util/AccountHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.tv.util.account;
+package com.android.tv.util;
import android.accounts.Account;
import android.content.Context;
@@ -23,23 +23,24 @@ import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
/** Helper methods for getting and selecting a user account. */
-public class AccountHelperImpl implements com.android.tv.util.account.AccountHelper {
+public class AccountHelper {
+ private static final String TAG = "AccountHelper";
+ private static final boolean DEBUG = false;
private static final String SELECTED_ACCOUNT = "android.tv.livechannels.selected_account";
- protected final Context mContext;
+ private final Context mContext;
private final SharedPreferences mDefaultPreferences;
@Nullable private Account mSelectedAccount;
- public AccountHelperImpl(Context context) {
+ public AccountHelper(Context context) {
mContext = context.getApplicationContext();
mDefaultPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
}
/** Returns the currently selected account or {@code null} if none is selected. */
- @Override
@Nullable
- public final Account getSelectedAccount() {
+ public Account getSelectedAccount() {
String accountId = mDefaultPreferences.getString(SELECTED_ACCOUNT, null);
if (accountId == null) {
return null;
@@ -56,12 +57,8 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
return mSelectedAccount;
}
- /**
- * Returns all eligible accounts.
- *
- * <p>Override this method to return the accounts needed.
- */
- protected Account[] getEligibleAccounts() {
+ /** Returns all eligible accounts . */
+ private Account[] getEligibleAccounts() {
return new Account[0];
}
@@ -70,9 +67,8 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
*
* @return selected account or {@code null} if none is selected.
*/
- @Override
@Nullable
- public final Account selectFirstAccount() {
+ public Account selectFirstAccount() {
Account account = getFirstEligibleAccount();
if (account != null) {
selectAccount(account);
@@ -85,9 +81,8 @@ public class AccountHelperImpl implements com.android.tv.util.account.AccountHel
*
* @return first account or {@code null} if none is eligible.
*/
- @Override
@Nullable
- public final Account getFirstEligibleAccount() {
+ public Account getFirstEligibleAccount() {
Account[] accounts = getEligibleAccounts();
return accounts.length == 0 ? null : accounts[0];
}
diff --git a/src/com/android/tv/util/AsyncDbTask.java b/src/com/android/tv/util/AsyncDbTask.java
index b575df53..376fcc70 100644
--- a/src/com/android/tv/util/AsyncDbTask.java
+++ b/src/com/android/tv/util/AsyncDbTask.java
@@ -28,7 +28,6 @@ import android.support.annotation.WorkerThread;
import android.util.Log;
import android.util.Range;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.data.Channel;
import com.android.tv.data.Program;
import com.android.tv.dvr.data.RecordedProgram;
@@ -48,7 +47,6 @@ import java.util.concurrent.RejectedExecutionException;
* @param <Progress> the type of the progress units published during the background computation.
* @param <Result> the type of the result of the background computation.
*/
-@SuppressWarnings("TryWithResources") // TODO(b/62143348): remove when error prone check fixed
public abstract class AsyncDbTask<Params, Progress, Result>
extends AsyncTask<Params, Progress, Result> {
private static final String TAG = "AsyncDbTask";
@@ -151,7 +149,7 @@ public abstract class AsyncDbTask<Params, Progress, Result>
return null;
}
} catch (Exception e) {
- SoftPreconditions.warn(TAG, null, e, "Error querying " + this);
+ SoftPreconditions.warn(TAG, null, "Error querying " + this, e);
return null;
}
}
diff --git a/src/com/android/tv/util/BitmapUtils.java b/src/com/android/tv/util/BitmapUtils.java
index 4c67d934..6902a6fe 100644
--- a/src/com/android/tv/util/BitmapUtils.java
+++ b/src/com/android/tv/util/BitmapUtils.java
@@ -29,7 +29,6 @@ import android.net.Uri;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
-import com.android.tv.common.util.NetworkTrafficTags;
import java.io.BufferedInputStream;
import java.io.Closeable;
import java.io.IOException;
diff --git a/src/com/android/tv/util/Clock.java b/src/com/android/tv/util/Clock.java
new file mode 100644
index 00000000..0004a669
--- /dev/null
+++ b/src/com/android/tv/util/Clock.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.tv.util;
+
+import android.os.SystemClock;
+
+/**
+ * An interface through which system clocks can be read. The {@link #SYSTEM} implementation must be
+ * used for all non-test cases.
+ */
+public interface Clock {
+ /**
+ * Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC. See {@link
+ * System#currentTimeMillis()}.
+ */
+ long currentTimeMillis();
+
+ /**
+ * Returns milliseconds since boot, including time spent in sleep.
+ *
+ * @see SystemClock#elapsedRealtime()
+ */
+ long elapsedRealtime();
+
+ /**
+ * Waits a given number of milliseconds (of uptimeMillis) before returning.
+ *
+ * @param ms to sleep before returning, in milliseconds of uptime.
+ * @see SystemClock#sleep(long)
+ */
+ void sleep(long ms);
+
+ /** The default implementation of Clock. */
+ Clock SYSTEM =
+ new Clock() {
+ @Override
+ public long currentTimeMillis() {
+ return System.currentTimeMillis();
+ }
+
+ @Override
+ public long elapsedRealtime() {
+ return SystemClock.elapsedRealtime();
+ }
+
+ @Override
+ public void sleep(long ms) {
+ SystemClock.sleep(ms);
+ }
+ };
+}
diff --git a/src/com/android/tv/util/Debug.java b/src/com/android/tv/util/Debug.java
new file mode 100644
index 00000000..422a61e3
--- /dev/null
+++ b/src/com/android/tv/util/Debug.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+/** A class only for help developers. */
+public class Debug {
+ /**
+ * A threshold of start up time, when the start up time of Live TV is more than it, a warning
+ * will show to the developer.
+ */
+ public static final long TIME_START_UP_DURATION_THRESHOLD = TimeUnit.SECONDS.toMillis(6);
+ /** Tag for measuring start up time of Live TV. */
+ public static final String TAG_START_UP_TIMER = "start_up_timer";
+
+ /** A global map for duration timers. */
+ private static final Map<String, DurationTimer> sTimerMap = new HashMap<>();
+
+ /** Returns the global duration timer by tag. */
+ public static DurationTimer getTimer(String tag) {
+ if (sTimerMap.get(tag) != null) {
+ return sTimerMap.get(tag);
+ }
+ DurationTimer timer = new DurationTimer(tag, true);
+ sTimerMap.put(tag, timer);
+ return timer;
+ }
+
+ /** Removes the global duration timer by tag. */
+ public static DurationTimer removeTimer(String tag) {
+ return sTimerMap.remove(tag);
+ }
+}
diff --git a/src/com/android/tv/util/DurationTimer.java b/src/com/android/tv/util/DurationTimer.java
new file mode 100644
index 00000000..6aabf37b
--- /dev/null
+++ b/src/com/android/tv/util/DurationTimer.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.util;
+
+import android.os.SystemClock;
+import android.util.Log;
+import com.android.tv.common.BuildConfig;
+
+/** Times a duration. */
+public final class DurationTimer {
+ private static final String TAG = "DurationTimer";
+ public static final long TIME_NOT_SET = -1;
+
+ private long mStartTimeMs = TIME_NOT_SET;
+ private String mTag = TAG;
+ private boolean mLogEngOnly;
+
+ public DurationTimer() {}
+
+ public DurationTimer(String tag, boolean logEngOnly) {
+ mTag = tag;
+ mLogEngOnly = logEngOnly;
+ }
+
+ /** Returns true if the timer is running. */
+ public boolean isRunning() {
+ return mStartTimeMs != TIME_NOT_SET;
+ }
+
+ /** Start the timer. */
+ public void start() {
+ mStartTimeMs = SystemClock.elapsedRealtime();
+ }
+
+ /** Returns true if timer is started. */
+ public boolean isStarted() {
+ return mStartTimeMs != TIME_NOT_SET;
+ }
+
+ /**
+ * Returns the current duration in milliseconds or {@link #TIME_NOT_SET} if the timer is not
+ * running.
+ */
+ public long getDuration() {
+ return isRunning() ? SystemClock.elapsedRealtime() - mStartTimeMs : TIME_NOT_SET;
+ }
+
+ /**
+ * Stops the timer and resets its value to {@link #TIME_NOT_SET}.
+ *
+ * @return the current duration in milliseconds or {@link #TIME_NOT_SET} if the timer is not
+ * running.
+ */
+ public long reset() {
+ long duration = getDuration();
+ mStartTimeMs = TIME_NOT_SET;
+ return duration;
+ }
+
+ /** Adds information and duration time to the log. */
+ public void log(String message) {
+ if (isRunning() && (!mLogEngOnly || BuildConfig.ENG)) {
+ Log.i(mTag, message + " : " + getDuration() + "ms");
+ }
+ }
+}
diff --git a/src/com/android/tv/util/ImageLoader.java b/src/com/android/tv/util/ImageLoader.java
index 32ac89f0..9b4d2a70 100644
--- a/src/com/android/tv/util/ImageLoader.java
+++ b/src/com/android/tv/util/ImageLoader.java
@@ -31,7 +31,6 @@ import android.support.annotation.WorkerThread;
import android.util.ArraySet;
import android.util.Log;
import com.android.tv.R;
-import com.android.tv.common.concurrent.NamedThreadFactory;
import com.android.tv.util.BitmapUtils.ScaledBitmapInfo;
import java.lang.ref.WeakReference;
import java.util.HashMap;
diff --git a/src/com/android/tv/util/LocationUtils.java b/src/com/android/tv/util/LocationUtils.java
new file mode 100644
index 00000000..a960c616
--- /dev/null
+++ b/src/com/android/tv/util/LocationUtils.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.util;
+
+import android.content.Context;
+import android.location.Address;
+import android.location.Geocoder;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.text.TextUtils;
+import android.util.Log;
+import com.android.tv.tuner.util.PostalCodeUtils;
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+
+/** A utility class to get the current location. */
+public class LocationUtils {
+ private static final String TAG = "LocationUtils";
+ private static final boolean DEBUG = false;
+
+ private static Context sApplicationContext;
+ private static Address sAddress;
+ private static String sCountry;
+ private static IOException sError;
+
+ /** Checks the current location. */
+ public static synchronized Address getCurrentAddress(Context context)
+ throws IOException, SecurityException {
+ if (sAddress != null) {
+ return sAddress;
+ }
+ if (sError != null) {
+ throw sError;
+ }
+ if (sApplicationContext == null) {
+ sApplicationContext = context.getApplicationContext();
+ }
+ LocationUtilsHelper.startLocationUpdates();
+ return null;
+ }
+
+ /** Returns the current country. */
+ @NonNull
+ public static synchronized String getCurrentCountry(Context context) {
+ if (sCountry != null) {
+ return sCountry;
+ }
+ if (TextUtils.isEmpty(sCountry)) {
+ sCountry = context.getResources().getConfiguration().locale.getCountry();
+ }
+ return sCountry;
+ }
+
+ private static void updateAddress(Location location) {
+ if (DEBUG) Log.d(TAG, "Updating address with " + location);
+ if (location == null) {
+ return;
+ }
+ Geocoder geocoder = new Geocoder(sApplicationContext, Locale.getDefault());
+ try {
+ List<Address> addresses =
+ geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
+ if (addresses != null && !addresses.isEmpty()) {
+ sAddress = addresses.get(0);
+ if (DEBUG) Log.d(TAG, "Got " + sAddress);
+ try {
+ PostalCodeUtils.updatePostalCode(sApplicationContext);
+ } catch (Exception e) {
+ // Do nothing
+ }
+ } else {
+ if (DEBUG) Log.d(TAG, "No address returned");
+ }
+ sError = null;
+ } catch (IOException e) {
+ Log.w(TAG, "Error in updating address", e);
+ sError = e;
+ }
+ }
+
+ private LocationUtils() {}
+
+ private static class LocationUtilsHelper {
+ private static final LocationListener LOCATION_LISTENER =
+ new LocationListener() {
+ @Override
+ public void onLocationChanged(Location location) {
+ updateAddress(location);
+ }
+
+ @Override
+ public void onStatusChanged(String provider, int status, Bundle extras) {}
+
+ @Override
+ public void onProviderEnabled(String provider) {}
+
+ @Override
+ public void onProviderDisabled(String provider) {}
+ };
+
+ private static LocationManager sLocationManager;
+
+ public static void startLocationUpdates() {
+ if (sLocationManager == null) {
+ sLocationManager =
+ (LocationManager)
+ sApplicationContext.getSystemService(Context.LOCATION_SERVICE);
+ try {
+ sLocationManager.requestLocationUpdates(
+ LocationManager.NETWORK_PROVIDER, 1000, 10, LOCATION_LISTENER, null);
+ } catch (SecurityException e) {
+ // Enables requesting the location updates again.
+ sLocationManager = null;
+ throw e;
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/tv/util/NamedThreadFactory.java b/src/com/android/tv/util/NamedThreadFactory.java
new file mode 100644
index 00000000..264b8b3f
--- /dev/null
+++ b/src/com/android/tv/util/NamedThreadFactory.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.tv.util;
+
+import android.support.annotation.NonNull;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/** A thread factory that creates threads with a suffix. */
+public class NamedThreadFactory implements ThreadFactory {
+ private final AtomicInteger mCount = new AtomicInteger(0);
+ private final ThreadFactory mDefaultThreadFactory;
+ private final String mPrefix;
+
+ public NamedThreadFactory(final String baseName) {
+ mDefaultThreadFactory = Executors.defaultThreadFactory();
+ mPrefix = baseName + "-";
+ }
+
+ @Override
+ public Thread newThread(@NonNull final Runnable runnable) {
+ final Thread thread = mDefaultThreadFactory.newThread(runnable);
+ thread.setName(mPrefix + mCount.getAndIncrement());
+ return thread;
+ }
+
+ public boolean namedWithPrefix(Thread thread) {
+ return thread.getName().startsWith(mPrefix);
+ }
+}
diff --git a/src/com/android/tv/util/NetworkTrafficTags.java b/src/com/android/tv/util/NetworkTrafficTags.java
new file mode 100644
index 00000000..85ecde5b
--- /dev/null
+++ b/src/com/android/tv/util/NetworkTrafficTags.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.tv.util;
+
+import android.net.TrafficStats;
+import android.support.annotation.NonNull;
+import java.util.concurrent.Executor;
+
+/** Constants for tagging network traffic in the Live channels app. */
+public final class NetworkTrafficTags {
+
+ public static final int DEFAULT_LIVE_CHANNELS = 1;
+ public static final int LOGO_FETCHER = 2;
+ public static final int HDHOMERUN = 3;
+ public static final int EPG_FETCH = 4;
+
+ /**
+ * An executor which simply wraps a provided delegate executor, but calls {@link
+ * TrafficStats#setThreadStatsTag(int)} before executing any task.
+ */
+ public static class TrafficStatsTaggingExecutor implements Executor {
+ private final Executor delegateExecutor;
+ private final int tag;
+
+ public TrafficStatsTaggingExecutor(Executor delegateExecutor, int tag) {
+ this.delegateExecutor = delegateExecutor;
+ this.tag = tag;
+ }
+
+ @Override
+ public void execute(final @NonNull Runnable command) {
+ // TODO(b/62038127): robolectric does not support lamdas in unbundled apps
+ delegateExecutor.execute(
+ new Runnable() {
+ @Override
+ public void run() {
+ TrafficStats.setThreadStatsTag(tag);
+ try {
+ command.run();
+ } finally {
+ TrafficStats.clearThreadStatsTag();
+ }
+ }
+ });
+ }
+ }
+
+ private NetworkTrafficTags() {}
+}
diff --git a/src/com/android/tv/util/OnboardingUtils.java b/src/com/android/tv/util/OnboardingUtils.java
index 63383aab..3b72e091 100644
--- a/src/com/android/tv/util/OnboardingUtils.java
+++ b/src/com/android/tv/util/OnboardingUtils.java
@@ -48,8 +48,8 @@ public final class OnboardingUtils {
}
/**
- * Checks if this is the first run of {@link com.android.tv.MainActivity} with the
- * current onboarding version.
+ * Checks if this is the first run of {@link com.android.tv.MainActivity} with the current
+ * onboarding version.
*/
public static boolean isFirstRunWithCurrentVersion(Context context) {
int versionCode =
@@ -59,8 +59,8 @@ public final class OnboardingUtils {
}
/**
- * Marks that the first run of {@link com.android.tv.MainActivity} with the current
- * onboarding version has been completed.
+ * Marks that the first run of {@link com.android.tv.MainActivity} with the current onboarding
+ * version has been completed.
*/
public static void setFirstRunWithCurrentVersionCompleted(Context context) {
PreferenceManager.getDefaultSharedPreferences(context)
diff --git a/src/com/android/tv/util/PermissionUtils.java b/src/com/android/tv/util/PermissionUtils.java
new file mode 100644
index 00000000..b3e4e3a2
--- /dev/null
+++ b/src/com/android/tv/util/PermissionUtils.java
@@ -0,0 +1,53 @@
+package com.android.tv.util;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+/** Util class to handle permissions. */
+public class PermissionUtils {
+ /** Permission to read the TV listings. */
+ public static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS";
+
+ private static Boolean sHasAccessAllEpgPermission;
+ private static Boolean sHasAccessWatchedHistoryPermission;
+ private static Boolean sHasModifyParentalControlsPermission;
+
+ public static boolean hasAccessAllEpg(Context context) {
+ if (sHasAccessAllEpgPermission == null) {
+ sHasAccessAllEpgPermission =
+ context.checkSelfPermission(
+ "com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA")
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ return sHasAccessAllEpgPermission;
+ }
+
+ public static boolean hasAccessWatchedHistory(Context context) {
+ if (sHasAccessWatchedHistoryPermission == null) {
+ sHasAccessWatchedHistoryPermission =
+ context.checkSelfPermission(
+ "com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS")
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ return sHasAccessWatchedHistoryPermission;
+ }
+
+ public static boolean hasModifyParentalControls(Context context) {
+ if (sHasModifyParentalControlsPermission == null) {
+ sHasModifyParentalControlsPermission =
+ context.checkSelfPermission("android.permission.MODIFY_PARENTAL_CONTROLS")
+ == PackageManager.PERMISSION_GRANTED;
+ }
+ return sHasModifyParentalControlsPermission;
+ }
+
+ public static boolean hasReadTvListings(Context context) {
+ return context.checkSelfPermission(PERMISSION_READ_TV_LISTINGS)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ public static boolean hasInternet(Context context) {
+ return context.checkSelfPermission("android.permission.INTERNET")
+ == PackageManager.PERMISSION_GRANTED;
+ }
+}
diff --git a/src/com/android/tv/util/RecurringRunner.java b/src/com/android/tv/util/RecurringRunner.java
index 764689c2..c1b724a2 100644
--- a/src/com/android/tv/util/RecurringRunner.java
+++ b/src/com/android/tv/util/RecurringRunner.java
@@ -22,8 +22,8 @@ import android.os.AsyncTask;
import android.os.Handler;
import android.support.annotation.WorkerThread;
import android.util.Log;
+import com.android.tv.common.SharedPreferencesUtils;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.util.SharedPreferencesUtils;
import java.util.Date;
/**
diff --git a/src/com/android/tv/util/SetupUtils.java b/src/com/android/tv/util/SetupUtils.java
index ad5d5024..a1ff192b 100644
--- a/src/com/android/tv/util/SetupUtils.java
+++ b/src/com/android/tv/util/SetupUtils.java
@@ -28,15 +28,15 @@ import android.media.tv.TvInputManager;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
-import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
-import com.android.tv.TvSingletons;
-import com.android.tv.common.BaseApplication;
+import com.android.tv.ApplicationSingletons;
+import com.android.tv.TvApplication;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.ChannelDataManager;
+import com.android.tv.tuner.tvinput.TunerTvInputService;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -54,8 +54,9 @@ public class SetupUtils {
// Recognized inputs means that the user already knows the inputs are installed.
private static final String PREF_KEY_RECOGNIZED_INPUTS = "recognized_inputs";
private static final String PREF_KEY_IS_FIRST_TUNE = "is_first_tune";
+ private static SetupUtils sSetupUtils;
- private final Context mContext;
+ private final TvApplication mTvApplication;
private final SharedPreferences mSharedPreferences;
private final Set<String> mKnownInputs;
private final Set<String> mSetUpInputs;
@@ -63,10 +64,9 @@ public class SetupUtils {
private boolean mIsFirstTune;
private final String mTunerInputId;
- @VisibleForTesting
- protected SetupUtils(Context context) {
- mContext = context;
- mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ private SetupUtils(TvApplication tvApplication) {
+ mTvApplication = tvApplication;
+ mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(tvApplication);
mSetUpInputs = new ArraySet<>();
mSetUpInputs.addAll(
mSharedPreferences.getStringSet(PREF_KEY_SET_UP_INPUTS, Collections.emptySet()));
@@ -77,16 +77,18 @@ public class SetupUtils {
mRecognizedInputs.addAll(
mSharedPreferences.getStringSet(PREF_KEY_RECOGNIZED_INPUTS, mKnownInputs));
mIsFirstTune = mSharedPreferences.getBoolean(PREF_KEY_IS_FIRST_TUNE, true);
- mTunerInputId = BaseApplication.getSingletons(context).getEmbeddedTunerInputId();
+ mTunerInputId =
+ TvContract.buildInputId(
+ new ComponentName(tvApplication, TunerTvInputService.class));
}
- /**
- * Creates an instance of {@link SetupUtils}.
- *
- * <p><b>WARNING</b> this should only be called by the top level application.
- */
- public static SetupUtils createForTvSingletons(Context context) {
- return new SetupUtils(context.getApplicationContext());
+ /** Gets an instance of {@link SetupUtils}. */
+ public static SetupUtils getInstance(Context context) {
+ if (sSetupUtils != null) {
+ return sSetupUtils;
+ }
+ sSetupUtils = new SetupUtils((TvApplication) context.getApplicationContext());
+ return sSetupUtils;
}
/** Additional work after the setup of TV input. */
@@ -97,15 +99,14 @@ public class SetupUtils {
// which one is the last callback. To reduce error prune, we update channel
// list again and make all channels of {@code inputId} browsable.
onSetupDone(inputId);
- final ChannelDataManager manager =
- TvSingletons.getSingletons(mContext).getChannelDataManager();
+ final ChannelDataManager manager = mTvApplication.getChannelDataManager();
if (!manager.isDbLoadFinished()) {
manager.addListener(
new ChannelDataManager.Listener() {
@Override
public void onLoadFinished() {
manager.removeListener(this);
- updateChannelsAfterSetup(mContext, inputId, postRunnable);
+ updateChannelsAfterSetup(mTvApplication, inputId, postRunnable);
}
@Override
@@ -115,14 +116,14 @@ public class SetupUtils {
public void onChannelBrowsableChanged() {}
});
} else {
- updateChannelsAfterSetup(mContext, inputId, postRunnable);
+ updateChannelsAfterSetup(mTvApplication, inputId, postRunnable);
}
}
private static void updateChannelsAfterSetup(
Context context, final String inputId, final Runnable postRunnable) {
- TvSingletons tvSingletons = TvSingletons.getSingletons(context);
- final ChannelDataManager manager = tvSingletons.getChannelDataManager();
+ ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
+ final ChannelDataManager manager = appSingletons.getChannelDataManager();
manager.updateChannels(
new Runnable() {
@Override
@@ -158,9 +159,8 @@ public class SetupUtils {
@UiThread
public void markNewChannelsBrowsable() {
Set<String> newInputsWithChannels = new HashSet<>();
- TvSingletons singletons = TvSingletons.getSingletons(mContext);
- TvInputManagerHelper tvInputManagerHelper = singletons.getTvInputManagerHelper();
- ChannelDataManager channelDataManager = singletons.getChannelDataManager();
+ TvInputManagerHelper tvInputManagerHelper = mTvApplication.getTvInputManagerHelper();
+ ChannelDataManager channelDataManager = mTvApplication.getChannelDataManager();
SoftPreconditions.checkState(channelDataManager.isDbLoadFinished());
for (TvInputInfo input : tvInputManagerHelper.getTvInputInfos(true, true)) {
String inputId = input.getId();
@@ -340,7 +340,8 @@ public class SetupUtils {
try {
// Just after booting, input list from TvInputManager are not reliable.
// So we need to double-check package existence. b/29034900
- mContext.getPackageManager()
+ mTvApplication
+ .getPackageManager()
.getPackageInfo(
ComponentName.unflattenFromString(input).getPackageName(),
PackageManager.GET_ACTIVITIES);
diff --git a/src/com/android/tv/util/SqlParams.java b/src/com/android/tv/util/SqlParams.java
deleted file mode 100644
index c4b803b6..00000000
--- a/src/com/android/tv/util/SqlParams.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.tv.util;
-
-import android.database.DatabaseUtils;
-import java.util.Arrays;
-
-/** Convenience class for SQL operations. */
-public class SqlParams {
- private String mTables;
- private String mSelection;
- private String[] mSelectionArgs;
-
- public SqlParams(String tables, String selection, String... selectionArgs) {
- setTables(tables);
- setWhere(selection, selectionArgs);
- }
-
- public String getTables() {
- return mTables;
- }
-
- public String getSelection() {
- return mSelection;
- }
-
- public String[] getSelectionArgs() {
- return mSelectionArgs;
- }
-
- public void setTables(String tables) {
- mTables = tables;
- }
-
- public void setWhere(String selection, String... selectionArgs) {
- mSelection = selection;
- mSelectionArgs = selectionArgs;
- }
-
- public void appendWhere(String selection, String... selectionArgs) {
- mSelection = DatabaseUtils.concatenateWhere(mSelection, selection);
- if (selectionArgs != null) {
- mSelectionArgs = DatabaseUtils.appendSelectionArgs(mSelectionArgs, selectionArgs);
- }
- }
-
- public void appendWhereEquals(String name, String value) {
- appendWhere(name + "=?", value);
- }
-
- @Override
- public String toString() {
- return "tables "
- + getTables()
- + " where "
- + getSelection()
- + " with "
- + Arrays.toString(getSelectionArgs());
- }
-}
diff --git a/src/com/android/tv/util/StringUtils.java b/src/com/android/tv/util/StringUtils.java
new file mode 100644
index 00000000..eeaf33a6
--- /dev/null
+++ b/src/com/android/tv/util/StringUtils.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.util;
+
+/** Utility class for handling {@link String}. */
+public final class StringUtils {
+
+ private StringUtils() {}
+
+ /** Returns compares two strings lexicographically and handles null values quietly. */
+ public static int compare(String a, String b) {
+ if (a == null) {
+ return b == null ? 0 : -1;
+ }
+ if (b == null) {
+ return 1;
+ }
+ return a.compareTo(b);
+ }
+}
diff --git a/src/com/android/tv/util/SystemProperties.java b/src/com/android/tv/util/SystemProperties.java
new file mode 100644
index 00000000..e1b8a398
--- /dev/null
+++ b/src/com/android/tv/util/SystemProperties.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.util;
+
+import com.android.tv.common.BooleanSystemProperty;
+
+/** A convenience class for getting TV related system properties. */
+public final class SystemProperties {
+
+ /** Allow Google Analytics for eng builds. */
+ public static final BooleanSystemProperty ALLOW_ANALYTICS_IN_ENG =
+ new BooleanSystemProperty("tv_allow_analytics_in_eng", false);
+
+ /** Allow Strict mode for debug builds. */
+ public static final BooleanSystemProperty ALLOW_STRICT_MODE =
+ new BooleanSystemProperty("tv_allow_strict_mode", true);
+
+ /** When true {@link android.view.KeyEvent}s are logged. Defaults to false. */
+ public static final BooleanSystemProperty LOG_KEYEVENT =
+ new BooleanSystemProperty("tv_log_keyevent", false);
+ /** When true debug keys are used. Defaults to false. */
+ public static final BooleanSystemProperty USE_DEBUG_KEYS =
+ new BooleanSystemProperty("tv_use_debug_keys", false);
+
+ /** Send {@link com.android.tv.analytics.Tracker} information. Defaults to {@code true}. */
+ public static final BooleanSystemProperty USE_TRACKER =
+ new BooleanSystemProperty("tv_use_tracker", true);
+
+ static {
+ updateSystemProperties();
+ }
+
+ private SystemProperties() {}
+
+ /** Update the TV related system properties. */
+ public static void updateSystemProperties() {
+ BooleanSystemProperty.resetAll();
+ }
+}
diff --git a/src/com/android/tv/util/TvInputManagerHelper.java b/src/com/android/tv/util/TvInputManagerHelper.java
index c4feafb7..e97bc4f9 100644
--- a/src/com/android/tv/util/TvInputManagerHelper.java
+++ b/src/com/android/tv/util/TvInputManagerHelper.java
@@ -21,19 +21,17 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.hardware.hdmi.HdmiDeviceInfo;
-import android.media.tv.TvContentRatingSystemInfo;
import android.media.tv.TvInputInfo;
import android.media.tv.TvInputManager;
import android.media.tv.TvInputManager.TvInputCallback;
import android.os.Handler;
-import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
-import com.android.tv.TvFeatures;
+import com.android.tv.Features;
import com.android.tv.common.SoftPreconditions;
-import com.android.tv.common.util.CommonUtils;
+import com.android.tv.common.TvCommonUtils;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.parental.ParentalControlSettings;
import java.util.ArrayList;
@@ -49,58 +47,6 @@ public class TvInputManagerHelper {
private static final String TAG = "TvInputManagerHelper";
private static final boolean DEBUG = false;
- public interface TvInputManagerInterface {
- TvInputInfo getTvInputInfo(String inputId);
-
- Integer getInputState(String inputId);
-
- void registerCallback(TvInputCallback internalCallback, Handler handler);
-
- void unregisterCallback(TvInputCallback internalCallback);
-
- List<TvInputInfo> getTvInputList();
-
- List<TvContentRatingSystemInfo> getTvContentRatingSystemList();
- }
-
- private static final class TvInputManagerImpl implements TvInputManagerInterface {
- private final TvInputManager delegate;
-
- private TvInputManagerImpl(TvInputManager delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public TvInputInfo getTvInputInfo(String inputId) {
- return delegate.getTvInputInfo(inputId);
- }
-
- @Override
- public Integer getInputState(String inputId) {
- return delegate.getInputState(inputId);
- }
-
- @Override
- public void registerCallback(TvInputCallback internalCallback, Handler handler) {
- delegate.registerCallback(internalCallback, handler);
- }
-
- @Override
- public void unregisterCallback(TvInputCallback internalCallback) {
- delegate.unregisterCallback(internalCallback);
- }
-
- @Override
- public List<TvInputInfo> getTvInputList() {
- return delegate.getTvInputList();
- }
-
- @Override
- public List<TvContentRatingSystemInfo> getTvContentRatingSystemList() {
- return delegate.getTvContentRatingSystemList();
- }
- }
-
/** Types of HDMI device and bundled tuner. */
public static final int TYPE_CEC_DEVICE = -2;
@@ -111,8 +57,7 @@ public class TvInputManagerHelper {
private static final String PERMISSION_ACCESS_ALL_EPG_DATA =
"com.android.providers.tv.permission.ACCESS_ALL_EPG_DATA";
- private static final String[] mPhysicalTunerBlackList = {
- };
+ private static final String[] mPhysicalTunerBlackList = {};
private static final String META_LABEL_SORT_KEY = "input_sort_key";
/** The default tv input priority to show. */
@@ -136,8 +81,7 @@ public class TvInputManagerHelper {
DEFAULT_TV_INPUT_PRIORITY.add(TvInputInfo.TYPE_OTHER);
}
- private static final String[] PARTNER_TUNER_INPUT_PREFIX_BLACKLIST = {
- };
+ private static final String[] PARTNER_TUNER_INPUT_PREFIX_BLACKLIST = {};
private static final String[] TESTABLE_INPUTS = {
"com.android.tv.testinput/.TestTvInputService"
@@ -145,7 +89,7 @@ public class TvInputManagerHelper {
private final Context mContext;
private final PackageManager mPackageManager;
- protected final TvInputManagerInterface mTvInputManager;
+ private final TvInputManager mTvInputManager;
private final Map<String, Integer> mInputStateMap = new HashMap<>();
private final Map<String, TvInputInfo> mInputMap = new HashMap<>();
private final Map<String, String> mTvInputLabels = new ArrayMap<>();
@@ -262,23 +206,10 @@ public class TvInputManagerHelper {
private final Comparator<TvInputInfo> mTvInputInfoComparator;
public TvInputManagerHelper(Context context) {
- this(context, createTvInputManagerWrapper(context));
- }
-
- @Nullable
- protected static TvInputManagerImpl createTvInputManagerWrapper(Context context) {
- TvInputManager tvInputManager =
- (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
- return tvInputManager == null ? null : new TvInputManagerImpl(tvInputManager);
- }
-
- @VisibleForTesting
- protected TvInputManagerHelper(
- Context context, @Nullable TvInputManagerInterface tvInputManager) {
mContext = context.getApplicationContext();
mPackageManager = context.getPackageManager();
- mTvInputManager = tvInputManager;
- mContentRatingsManager = new ContentRatingsManager(context, tvInputManager);
+ mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
+ mContentRatingsManager = new ContentRatingsManager(context);
mParentalControlSettings = new ParentalControlSettings(context);
mTvInputInfoComparator = new InputComparatorInternal(this);
}
@@ -389,7 +320,7 @@ public class TvInputManagerHelper {
/** Is the input one known bundled inputs not written by OEM/SOCs. */
public boolean isBundledInput(TvInputInfo inputInfo) {
return inputInfo != null
- && CommonUtils.isInBundledPackageSet(
+ && Utils.isInBundledPackageSet(
inputInfo.getServiceInfo().applicationInfo.packageName);
}
@@ -497,17 +428,9 @@ public class TvInputManagerHelper {
}
return size;
}
- /**
- * Returns TvInputInfo's input state.
- *
- * @param inputInfo
- * @return An Integer which stands for the input state {@link
- * TvInputManager.INPUT_STATE_DISCONNECTED} if inputInfo is null
- */
- public int getInputState(@Nullable TvInputInfo inputInfo) {
- return inputInfo == null
- ? TvInputManager.INPUT_STATE_DISCONNECTED
- : getInputState(inputInfo.getId());
+
+ public int getInputState(TvInputInfo inputInfo) {
+ return getInputState(inputInfo.getId());
}
public int getInputState(String inputId) {
@@ -578,15 +501,14 @@ public class TvInputManagerHelper {
}
private boolean isInBlackList(String inputId) {
- if (TvFeatures.USE_PARTNER_INPUT_BLACKLIST.isEnabled(mContext)) {
+ if (Features.USE_PARTNER_INPUT_BLACKLIST.isEnabled(mContext)) {
for (String disabledTunerInputPrefix : PARTNER_TUNER_INPUT_PREFIX_BLACKLIST) {
if (inputId.contains(disabledTunerInputPrefix)) {
return true;
}
}
}
- if (CommonUtils.isRoboTest()) return false;
- if (CommonUtils.isRunningInTest()) {
+ if (TvCommonUtils.isRunningInTest()) {
for (String testableInput : TESTABLE_INPUTS) {
if (testableInput.equals(inputId)) {
return false;
diff --git a/src/com/android/tv/util/Utils.java b/src/com/android/tv/util/Utils.java
index 1c8ccd5b..ac3be643 100644
--- a/src/com/android/tv/util/Utils.java
+++ b/src/com/android/tv/util/Utils.java
@@ -38,15 +38,20 @@ import android.support.annotation.VisibleForTesting;
import android.support.annotation.WorkerThread;
import android.text.TextUtils;
import android.text.format.DateUtils;
+import android.util.ArraySet;
import android.util.Log;
import android.view.View;
+import com.android.tv.ApplicationSingletons;
import com.android.tv.R;
-import com.android.tv.TvSingletons;
+import com.android.tv.TvApplication;
+import com.android.tv.common.BuildConfig;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.data.Channel;
import com.android.tv.data.GenreItems;
import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
+import com.android.tv.experiments.Experiments;
+import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -63,11 +68,13 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/** A class that includes convenience methods for accessing TvProvider database. */
-@SuppressWarnings("TryWithResources") // TODO(b/62143348): remove when error prone check fixed
public class Utils {
private static final String TAG = "Utils";
private static final boolean DEBUG = false;
+ private static final SimpleDateFormat ISO_8601 =
+ new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US);
+
public static final String EXTRA_KEY_ACTION = "action";
public static final String EXTRA_ACTION_SHOW_TV_INPUT = "show_tv_input";
public static final String EXTRA_KEY_FROM_LAUNCHER = "from_launcher";
@@ -109,6 +116,15 @@ public class Utils {
private static final long HALF_MINUTE_MS = TimeUnit.SECONDS.toMillis(30);
private static final long ONE_DAY_MS = TimeUnit.DAYS.toMillis(1);
+ // Hardcoded list for known bundled inputs not written by OEM/SOCs.
+ // Bundled (system) inputs not in the list will get the high priority
+ // so they and their channels come first in the UI.
+ private static final Set<String> BUNDLED_PACKAGE_SET = new ArraySet<>();
+
+ static {
+ BUNDLED_PACKAGE_SET.add("com.android.tv");
+ }
+
private enum AspectRatio {
ASPECT_RATIO_4_3(4, 3),
ASPECT_RATIO_16_9(16, 9),
@@ -645,7 +661,7 @@ public class Utils {
return null;
}
TvInputManagerHelper inputManager =
- TvSingletons.getSingletons(context).getTvInputManagerHelper();
+ TvApplication.getSingletons(context).getTvInputManagerHelper();
CharSequence customLabel = inputManager.loadCustomLabel(input);
String label = (customLabel == null) ? null : customLabel.toString();
if (TextUtils.isEmpty(label)) {
@@ -688,6 +704,11 @@ public class Utils {
return toTimeString(timeMillis, true);
}
+ /** Converts time in milliseconds to a ISO 8061 string. */
+ public static String toIsoDateTimeString(long timeMillis) {
+ return ISO_8601.format(new Date(timeMillis));
+ }
+
/**
* Returns a {@link String} object which contains the layout information of the {@code view}.
*/
@@ -754,7 +775,7 @@ public class Utils {
/** Checks where there is any internal TV input. */
public static boolean hasInternalTvInputs(Context context, boolean tunerInputOnly) {
for (TvInputInfo input :
- TvSingletons.getSingletons(context)
+ TvApplication.getSingletons(context)
.getTvInputManagerHelper()
.getTvInputInfos(true, tunerInputOnly)) {
if (isInternalTvInput(context, input.getId())) {
@@ -768,7 +789,7 @@ public class Utils {
public static List<TvInputInfo> getInternalTvInputs(Context context, boolean tunerInputOnly) {
List<TvInputInfo> inputs = new ArrayList<>();
for (TvInputInfo input :
- TvSingletons.getSingletons(context)
+ TvApplication.getSingletons(context)
.getTvInputManagerHelper()
.getTvInputInfos(true, tunerInputOnly)) {
if (isInternalTvInput(context, input.getId())) {
@@ -796,22 +817,47 @@ public class Utils {
/** Returns the TV input for the given channel ID. */
@Nullable
public static TvInputInfo getTvInputInfoForChannelId(Context context, long channelId) {
- TvSingletons tvSingletons = TvSingletons.getSingletons(context);
- Channel channel = tvSingletons.getChannelDataManager().getChannel(channelId);
+ ApplicationSingletons appSingletons = TvApplication.getSingletons(context);
+ Channel channel = appSingletons.getChannelDataManager().getChannel(channelId);
if (channel == null) {
return null;
}
- return tvSingletons.getTvInputManagerHelper().getTvInputInfo(channel.getInputId());
+ return appSingletons.getTvInputManagerHelper().getTvInputInfo(channel.getInputId());
}
/** Returns the {@link TvInputInfo} for the given input ID. */
@Nullable
public static TvInputInfo getTvInputInfoForInputId(Context context, String inputId) {
- return TvSingletons.getSingletons(context)
+ return TvApplication.getSingletons(context)
.getTvInputManagerHelper()
.getTvInputInfo(inputId);
}
+ /** Deletes a file or a directory. */
+ public static void deleteDirOrFile(File fileOrDirectory) {
+ if (fileOrDirectory.isDirectory()) {
+ for (File child : fileOrDirectory.listFiles()) {
+ deleteDirOrFile(child);
+ }
+ }
+ fileOrDirectory.delete();
+ }
+
+ /** Checks whether a given package is in our bundled package set. */
+ public static boolean isInBundledPackageSet(String packageName) {
+ return BUNDLED_PACKAGE_SET.contains(packageName);
+ }
+
+ /** Checks whether a given input is a bundled input. */
+ public static boolean isBundledInput(String inputId) {
+ for (String prefix : BUNDLED_PACKAGE_SET) {
+ if (inputId.startsWith(prefix + "/")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Returns the canonical genre ID's from the {@code genres}. */
public static int[] getCanonicalGenreIds(String genres) {
if (TextUtils.isEmpty(genres)) {
@@ -853,6 +899,11 @@ public class Utils {
return Genres.encode(genres);
}
+ /** Returns true if the current user is a developer. */
+ public static boolean isDeveloper() {
+ return BuildConfig.ENG || Experiments.ENABLE_DEVELOPER_FEATURES.get();
+ }
+
/**
* Runs the method in main thread. If the current thread is not main thread, block it util the
* method is finished.
diff --git a/src/com/android/tv/util/ViewCache.java b/src/com/android/tv/util/ViewCache.java
index b8bdb6b8..2d5ecfe6 100644
--- a/src/com/android/tv/util/ViewCache.java
+++ b/src/com/android/tv/util/ViewCache.java
@@ -1,18 +1,3 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
package com.android.tv.util;
import android.content.Context;
diff --git a/src/com/android/tv/util/account/AccountHelper.java b/src/com/android/tv/util/account/AccountHelper.java
deleted file mode 100644
index e98b42ec..00000000
--- a/src/com/android/tv/util/account/AccountHelper.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.tv.util.account;
-
-import android.accounts.Account;
-import android.support.annotation.Nullable;
-
-/** Helper methods for getting and selecting a user account. */
-public interface AccountHelper {
- /** Returns the currently selected account or {@code null} if none is selected. */
- @Nullable
- Account getSelectedAccount();
- /**
- * Selects the first account available.
- *
- * @return selected account or {@code null} if none is selected.
- */
- @Nullable
- Account selectFirstAccount();
-
- /** Returns all eligible accounts . */
- @Nullable
- Account getFirstEligibleAccount();
-}