summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorRobert Horvath <robhor@google.com>2020-03-12 15:32:24 +0100
committerRobert Horvath <robhor@google.com>2020-03-12 14:56:19 +0000
commitc113e39dfeac7f80fd3e1342292839fcf74a919e (patch)
treee04dee0aa17a0ebb6c16c72a4a0c9be05e1d464a /java
parent28ca1ccf3d4af66d5cb00bc775f8f94a6d7f4fc5 (diff)
downloadtvsystem-c113e39dfeac7f80fd3e1342292839fcf74a919e.tar.gz
Move TvSystem to /frameworks/opt/tv/tvsystem
Bug: 151291114 Test: m com.android.libraries.tv.tvsystem Change-Id: I9c2a8670fe96bd466613b7196632c73b38420662
Diffstat (limited to 'java')
-rw-r--r--java/com/android/libraries/tv/tvsystem/display/DeviceProductInfo.java154
-rw-r--r--java/com/android/libraries/tv/tvsystem/display/DisplayCompatUtil.java67
-rw-r--r--java/com/android/libraries/tv/tvsystem/display/WindowCompatUtil.java38
-rw-r--r--java/com/android/libraries/tv/tvsystem/wifi/SoftApConfiguration.java236
-rw-r--r--java/com/android/libraries/tv/tvsystem/wifi/TvWifiManager.java73
5 files changed, 568 insertions, 0 deletions
diff --git a/java/com/android/libraries/tv/tvsystem/display/DeviceProductInfo.java b/java/com/android/libraries/tv/tvsystem/display/DeviceProductInfo.java
new file mode 100644
index 0000000..7d9a120
--- /dev/null
+++ b/java/com/android/libraries/tv/tvsystem/display/DeviceProductInfo.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2020 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.libraries.tv.tvsystem.display;
+
+import java.util.Objects;
+
+/**
+ * Product-specific information about the display or the directly connected device on the
+ * display chain. For example, if the display is transitively connected, this field may contain
+ * product information about the intermediate device.
+ */
+public final class DeviceProductInfo {
+ private final String mName;
+ private final String mManufacturerPnpId;
+ private final String mProductId;
+ private final Integer mModelYear;
+ private final ManufactureDate mManufactureDate;
+
+ public DeviceProductInfo(
+ String name,
+ String manufacturerPnpId,
+ String productId,
+ Integer modelYear,
+ ManufactureDate manufactureDate) {
+ this.mName = name;
+ this.mManufacturerPnpId = manufacturerPnpId;
+ this.mProductId = productId;
+ this.mModelYear = modelYear;
+ this.mManufactureDate = manufactureDate;
+ }
+
+ /**
+ * @return Display name.
+ */
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * @return Manufacturer Plug and Play ID.
+ */
+ public String getManufacturerPnpId() {
+ return mManufacturerPnpId;
+ }
+
+ /**
+ * @return Manufacturer product ID.
+ */
+ public String getProductId() {
+ return mProductId;
+ }
+
+ /**
+ * @return Model year of the device. Typically exactly one of model year or
+ * manufacture date will be present.
+ */
+ public Integer getModelYear() {
+ return mModelYear;
+ }
+
+ /**
+ * @return Manufacture date. Typically exactly one of model year or manufacture
+ * date will be present.
+ */
+ public ManufactureDate getManufactureDate() {
+ return mManufactureDate;
+ }
+
+ @Override
+ public String toString() {
+ return "DeviceProductInfo{"
+ + "name="
+ + mName
+ + ", manufacturerPnpId="
+ + mManufacturerPnpId
+ + ", productId="
+ + mProductId
+ + ", modelYear="
+ + mModelYear
+ + ", manufactureDate="
+ + mManufactureDate
+ + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DeviceProductInfo that = (DeviceProductInfo) o;
+ return Objects.equals(mName, that.mName)
+ && Objects.equals(mManufacturerPnpId, that.mManufacturerPnpId)
+ && Objects.equals(mProductId, that.mProductId)
+ && Objects.equals(mModelYear, that.mModelYear)
+ && Objects.equals(mManufactureDate, that.mManufactureDate);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mName, mManufacturerPnpId, mProductId, mModelYear, mManufactureDate);
+ }
+
+ /**
+ * Stores information about the date of manufacture.
+ */
+ public static class ManufactureDate {
+ private final Integer mWeek;
+ private final Integer mYear;
+
+ public ManufactureDate(Integer week, Integer year) {
+ mWeek = week;
+ mYear = year;
+ }
+
+ public Integer getYear() {
+ return mYear;
+ }
+
+ public Integer getWeek() {
+ return mWeek;
+ }
+
+ @Override
+ public String toString() {
+ return "ManufactureDate{week=" + mWeek + ", year=" + mYear + '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ManufactureDate that = (ManufactureDate) o;
+ return Objects.equals(mWeek, that.mWeek) && Objects.equals(mYear, that.mYear);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mWeek, mYear);
+ }
+ }
+} \ No newline at end of file
diff --git a/java/com/android/libraries/tv/tvsystem/display/DisplayCompatUtil.java b/java/com/android/libraries/tv/tvsystem/display/DisplayCompatUtil.java
new file mode 100644
index 0000000..4b8da67
--- /dev/null
+++ b/java/com/android/libraries/tv/tvsystem/display/DisplayCompatUtil.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 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.libraries.tv.tvsystem.display;
+
+import android.view.Display;
+import android.view.DisplayInfo;
+
+public final class DisplayCompatUtil {
+
+ /**
+ * <p> Returns true if the connected display can be switched into a mode with minimal
+ * post processing. </p>
+ *
+ * <p> If the Display sink is connected via HDMI, this method will return true if the
+ * display supports either Auto Low Latency Mode or Game Content Type.
+ *
+ * <p> If the Display sink has an internal connection or uses some other protocol than
+ * HDMI, this method will return true if the sink can be switched into an
+ * implementation-defined low latency image processing mode. </p>
+ *
+ * <p> The ability to switch to a mode with minimal post processing may be disabled
+ * by a user setting in the system settings menu. In that case, this method returns
+ * false. </p>
+ *
+ * @see Display#isMinimalPostProcessingSupported
+ * @see WindowCompatUtil#setPreferMinimalPostProcessing
+ */
+ public static boolean isMinimalPostProcessingSupported(Display display) {
+ return display.isMinimalPostProcessingSupported();
+ }
+
+ /**
+ * <p> Returns product-specific information about the display or the directly connected device
+ * on the display chain. For example, if the display is transitively connected, this field may
+ * contain product information about the intermediate device. </p>
+ */
+ public static DeviceProductInfo getDeviceProductInfo(Display display) {
+ DisplayInfo displayInfo = new DisplayInfo();
+ display.getDisplayInfo(displayInfo);
+ android.hardware.display.DeviceProductInfo info = displayInfo.deviceProductInfo;
+ DeviceProductInfo.ManufactureDate manufactureDate;
+ if (info.getManufactureDate() == null) {
+ manufactureDate = null;
+ } else {
+ manufactureDate = new DeviceProductInfo.ManufactureDate(
+ info.getManufactureDate().getWeek(), info.getManufactureDate().getYear());
+ }
+ return new DeviceProductInfo(info.getName(), info.getManufacturerPnpId(),
+ info.getProductId(), info.getModelYear(), manufactureDate);
+ }
+
+ private DisplayCompatUtil() {}
+}
diff --git a/java/com/android/libraries/tv/tvsystem/display/WindowCompatUtil.java b/java/com/android/libraries/tv/tvsystem/display/WindowCompatUtil.java
new file mode 100644
index 0000000..4a0fed9
--- /dev/null
+++ b/java/com/android/libraries/tv/tvsystem/display/WindowCompatUtil.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 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.libraries.tv.tvsystem.display;
+
+import android.view.Window;
+
+public final class WindowCompatUtil {
+
+ /**
+ * Specify whether this Window should request the Display it's presented on to switch to the
+ * minimal post-processing mode, if the Display supports such mode.
+ * Usually minimal post-processing is backed by HDMI ContentType="game" and HDMI Auto
+ * Low-Latency Mode. However, different manufacturers may have their own implementations of
+ * similar features.
+ *
+ * @see Window#setPreferMinimalPostProcessing
+ * @see DisplayCompatUtil#isMinimalPostProcessingSupported
+ */
+ public static void setPreferMinimalPostProcessing(Window window, boolean isPreferred) {
+ window.setPreferMinimalPostProcessing(isPreferred);
+ }
+
+ private WindowCompatUtil() {}
+}
diff --git a/java/com/android/libraries/tv/tvsystem/wifi/SoftApConfiguration.java b/java/com/android/libraries/tv/tvsystem/wifi/SoftApConfiguration.java
new file mode 100644
index 0000000..a467965
--- /dev/null
+++ b/java/com/android/libraries/tv/tvsystem/wifi/SoftApConfiguration.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2020 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.libraries.tv.tvsystem.wifi;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.MacAddress;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * WiFi configuration for a soft access point (a.k.a. Soft AP, SAP, Hotspot).
+ *
+ * This is input for the framework provided by a client app, i.e. it exposes knobs to instruct the
+ * framework how it should open a hotspot. It is not meant to describe the network as it will be
+ * seen by clients; this role is currently served by {@link WifiConfiguration} (see
+ * {@link WifiManager.LocalOnlyHotspotReservation#getWifiConfiguration()}).
+ *
+ * Apps can use this to configure a local-only hotspot using
+ * {@link TvWifiManager#startLocalOnlyHotspot(SoftApConfiguration, Executor,
+ * WifiManager.LocalOnlyHotspotCallback)}.
+ *
+ * Instances of this class are immutable; use {@link SoftApConfiguration.Builder} and its methods to
+ * create a new instance.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SoftApConfiguration implements Parcelable {
+ /**
+ * SSID for the AP, or null for a framework-determined SSID.
+ */
+ private final @Nullable
+ String mSsid;
+ /**
+ * BSSID for the AP, or null to use a framework-determined BSSID.
+ */
+ private final @Nullable
+ MacAddress mBssid;
+ /**
+ * Pre-shared key for WPA2-PSK encryption (non-null enables WPA2-PSK).
+ */
+ private final @Nullable
+ String mWpa2Passphrase;
+
+ /** Private constructor for Builder and Parcelable implementation. */
+ private SoftApConfiguration(
+ @Nullable String ssid, @Nullable MacAddress bssid, String wpa2Passphrase) {
+ mSsid = ssid;
+ mBssid = bssid;
+ mWpa2Passphrase = wpa2Passphrase;
+ }
+
+ @Override
+ public boolean equals(Object otherObj) {
+ if (this == otherObj) {
+ return true;
+ }
+ if (!(otherObj instanceof SoftApConfiguration)) {
+ return false;
+ }
+ SoftApConfiguration other = (SoftApConfiguration) otherObj;
+ return Objects.equals(mSsid, other.mSsid)
+ && Objects.equals(mBssid, other.mBssid)
+ && Objects.equals(mWpa2Passphrase, other.mWpa2Passphrase);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSsid, mBssid, mWpa2Passphrase);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeString(mSsid);
+ dest.writeParcelable(mBssid, flags);
+ dest.writeString(mWpa2Passphrase);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @NonNull
+ public static final Creator<SoftApConfiguration> CREATOR = new Creator<SoftApConfiguration>() {
+ @Override
+ public SoftApConfiguration createFromParcel(Parcel in) {
+ return new SoftApConfiguration(
+ in.readString(),
+ in.readParcelable(MacAddress.class.getClassLoader()),
+ in.readString());
+ }
+
+ @Override
+ public SoftApConfiguration[] newArray(int size) {
+ return new SoftApConfiguration[size];
+ }
+ };
+
+ @Nullable
+ public String getSsid() {
+ return mSsid;
+ }
+
+ @Nullable
+ public MacAddress getBssid() {
+ return mBssid;
+ }
+
+ @Nullable
+ public String getWpa2Passphrase() {
+ return mWpa2Passphrase;
+ }
+
+ /**
+ * Builds a {@link SoftApConfiguration}, which allows an app to configure various aspects of a
+ * Soft AP.
+ *
+ * All fields are optional. By default, SSID and BSSID are automatically chosen by the
+ * framework, and an open network is created.
+ */
+ public static final class Builder {
+ private String mSsid;
+ private MacAddress mBssid;
+ private String mWpa2Passphrase;
+
+ /**
+ * Constructs a Builder with default values (see {@link Builder}).
+ */
+ public Builder() {
+ mSsid = null;
+ mBssid = null;
+ mWpa2Passphrase = null;
+ }
+
+ /**
+ * Constructs a Builder initialized from an existing {@link SoftApConfiguration} instance.
+ */
+ public Builder(@NonNull SoftApConfiguration other) {
+ Objects.requireNonNull(other);
+
+ mSsid = other.mSsid;
+ mBssid = other.mBssid;
+ mWpa2Passphrase = other.mWpa2Passphrase;
+ }
+
+ /**
+ * Builds the {@link SoftApConfiguration}.
+ *
+ * @return A new {@link SoftApConfiguration}, as configured by previous method calls.
+ */
+ @NonNull
+ public SoftApConfiguration build() {
+ return new SoftApConfiguration(mSsid, mBssid, mWpa2Passphrase);
+ }
+
+ /**
+ * Specifies an SSID for the AP.
+ *
+ * @param ssid SSID of valid Unicode characters, or null to have the SSID automatically
+ * chosen by the framework.
+ * @return Builder for chaining.
+ * @throws IllegalArgumentException when the SSID is empty or not valid Unicode.
+ */
+ @NonNull
+ public Builder setSsid(@Nullable String ssid) {
+ if (ssid != null) {
+ Preconditions.checkStringNotEmpty(ssid);
+ Preconditions.checkArgument(StandardCharsets.UTF_8.newEncoder().canEncode(ssid));
+ }
+ mSsid = ssid;
+ return this;
+ }
+
+ /**
+ * Specifies a BSSID for the AP.
+ *
+ * @param bssid BSSID, or null to have the BSSID chosen by the framework. The caller is
+ * responsible for avoiding collisions.
+ * @return Builder for chaining.
+ * @throws IllegalArgumentException when the given BSSID is the all-zero or broadcast MAC
+ * address.
+ */
+ @NonNull
+ public Builder setBssid(@Nullable MacAddress bssid) {
+ if (bssid != null) {
+ Preconditions.checkArgument(!bssid.equals(MacAddress.ALL_ZEROS_ADDRESS));
+ Preconditions.checkArgument(!bssid.equals(MacAddress.BROADCAST_ADDRESS));
+ }
+ mBssid = bssid;
+ return this;
+ }
+
+ /**
+ * Specifies that this AP should use WPA2-PSK with the given passphrase. When set to null
+ * and no other encryption method is configured, an open network is created.
+ *
+ * @param passphrase The passphrase to use, or null to unset a previously-set WPA2-PSK
+ * configuration.
+ * @return Builder for chaining.
+ * @throws IllegalArgumentException when the passphrase is the empty string
+ */
+ @NonNull
+ public Builder setWpa2Passphrase(@Nullable String passphrase) {
+ if (passphrase != null) {
+ Preconditions.checkStringNotEmpty(passphrase);
+ }
+ mWpa2Passphrase = passphrase;
+ return this;
+ }
+ }
+}
diff --git a/java/com/android/libraries/tv/tvsystem/wifi/TvWifiManager.java b/java/com/android/libraries/tv/tvsystem/wifi/TvWifiManager.java
new file mode 100644
index 0000000..2457584
--- /dev/null
+++ b/java/com/android/libraries/tv/tvsystem/wifi/TvWifiManager.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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.libraries.tv.tvsystem.wifi;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+
+import java.util.concurrent.Executor;
+
+/**
+ * Provides access to APIs in {@link WifiManager} that are otherwise @hidden.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TvWifiManager {
+ private final WifiManager mWifiManager;
+
+ public TvWifiManager(@NonNull Context context) {
+ mWifiManager = context.getSystemService(WifiManager.class);
+ }
+
+ /**
+ * Starts a local-only hotspot with a specific configuration applied. See
+ * {@link WifiManager#startLocalOnlyHotspot(WifiManager.LocalOnlyHotspotCallback, Handler)}.
+ *
+ * Applications need either {@link android.Manifest.permission#NETWORK_SETUP_WIZARD} or
+ * {@link android.Manifest.permission#NETWORK_SETTINGS} to call this method.
+ *
+ * Since custom configuration settings may be incompatible with each other, the hotspot started
+ * through this method cannot coexist with another hotspot created through
+ * startLocalOnlyHotspot. If this is attempted, the first hotspot request wins and others
+ * receive {@link WifiManager.LocalOnlyHotspotCallback#ERROR_GENERIC} through
+ * {@link WifiManager.LocalOnlyHotspotCallback#onFailed}.
+ *
+ * @param config Custom configuration for the hotspot. See {@link SoftApConfiguration}.
+ * @param executor Executor to run callback methods on, or null to use the main thread.
+ * @param callback Callback object for updates about hotspot status, or null for no updates.
+ */
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.NETWORK_SETTINGS,
+ android.Manifest.permission.NETWORK_SETUP_WIZARD})
+ public void startLocalOnlyHotspot(@NonNull SoftApConfiguration config,
+ @Nullable Executor executor,
+ @Nullable WifiManager.LocalOnlyHotspotCallback callback) {
+ android.net.wifi.SoftApConfiguration frameworkConfig =
+ new android.net.wifi.SoftApConfiguration.Builder()
+ .setBssid(config.getBssid())
+ .setSsid(config.getSsid())
+ .setWpa2Passphrase(config.getWpa2Passphrase())
+ .build();
+ mWifiManager.startLocalOnlyHotspot(frameworkConfig, executor, callback);
+ }
+}