summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ContextImpl.java4
-rw-r--r--core/java/android/content/Context.java6
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl7
-rw-r--r--core/java/android/net/ConnectivityManager.java20
-rw-r--r--core/java/android/net/IConnectivityManager.aidl2
-rw-r--r--core/java/android/net/NetworkInfo.java9
-rw-r--r--core/java/android/net/NetworkRequest.java22
-rw-r--r--core/java/android/provider/TvContract.java741
-rw-r--r--core/java/android/tv/ITvInputClient.aidl35
-rw-r--r--core/java/android/tv/ITvInputHardware.aidl46
-rw-r--r--core/java/android/tv/ITvInputHardwareCallback.aidl27
-rw-r--r--core/java/android/tv/ITvInputManager.aidl58
-rw-r--r--core/java/android/tv/ITvInputService.aidl31
-rw-r--r--core/java/android/tv/ITvInputServiceCallback.aidl28
-rw-r--r--core/java/android/tv/ITvInputSession.aidl39
-rw-r--r--core/java/android/tv/ITvInputSessionCallback.aidl31
-rw-r--r--core/java/android/tv/ITvInputSessionWrapper.java179
-rw-r--r--core/java/android/tv/TvInputHardwareInfo.aidl20
-rw-r--r--core/java/android/tv/TvInputHardwareInfo.java93
-rw-r--r--core/java/android/tv/TvInputInfo.aidl19
-rw-r--r--core/java/android/tv/TvInputInfo.java163
-rw-r--r--core/java/android/tv/TvInputManager.java850
-rw-r--r--core/java/android/tv/TvInputService.java598
-rw-r--r--core/java/android/tv/TvStreamConfig.aidl20
-rw-r--r--core/java/android/tv/TvStreamConfig.java157
-rw-r--r--core/java/android/tv/TvView.java402
-rw-r--r--core/java/android/view/GLES20Canvas.java114
-rw-r--r--core/java/android/view/GLES20RecordingCanvas.java2
-rw-r--r--core/java/android/view/GLRenderer.java1521
-rw-r--r--core/java/android/view/HardwareCanvas.java42
-rw-r--r--core/java/android/view/HardwareLayer.java37
-rw-r--r--core/java/android/view/HardwareRenderer.java15
-rw-r--r--core/java/android/view/ThreadedRenderer.java10
-rw-r--r--core/java/android/view/View.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java11
35 files changed, 64 insertions, 5301 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4f335bb..e03224c 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -75,6 +75,8 @@ import android.location.LocationManager;
import android.media.AudioManager;
import android.media.MediaRouter;
import android.media.session.MediaSessionManager;
+import android.media.tv.ITvInputManager;
+import android.media.tv.TvInputManager;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
import android.net.EthernetManager;
@@ -119,8 +121,6 @@ import android.service.fingerprint.FingerprintManager;
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintService;
import android.telephony.TelephonyManager;
-import android.tv.ITvInputManager;
-import android.tv.TvInputManager;
import android.content.ClipboardManager;
import android.util.AndroidRuntimeException;
import android.util.ArrayMap;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c69e669..a040efb 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2751,11 +2751,11 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
- * {@link android.tv.TvInputManager} for interacting with TV inputs on the
- * device.
+ * {@link android.media.tv.TvInputManager} for interacting with TV inputs
+ * on the device.
*
* @see #getSystemService
- * @see android.tv.TvInputManager
+ * @see android.media.tv.TvInputManager
*/
public static final String TV_INPUT_SERVICE = "tv_input";
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 44a6a5d..70668e1 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -433,6 +433,13 @@ interface IPackageManager {
in VerificationParams verificationParams,
in ContainerEncryptionParams encryptionParams);
+ void installPackageWithVerificationEncryptionAndAbiOverrideEtc(in Uri packageURI,
+ in IPackageInstallObserver observer, in IPackageInstallObserver2 observer2,
+ int flags, in String installerPackageName,
+ in VerificationParams verificationParams,
+ in ContainerEncryptionParams encryptionParams,
+ in String packageAbiOverride);
+
int installExistingPackageAsUser(String packageName, int userId);
void verifyPendingInstall(int id, int verificationCode);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 24844ba..a48a388 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -905,7 +905,7 @@ public class ConnectivityManager {
return null;
}
- private int networkTypeForNetworkCapabilities(NetworkCapabilities netCap) {
+ private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
if (netCap == null) return TYPE_NONE;
if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
return TYPE_MOBILE_CBS;
@@ -928,6 +928,9 @@ public class ConnectivityManager {
if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
return TYPE_MOBILE_HIPRI;
}
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
+ return TYPE_WIFI_P2P;
+ }
return TYPE_NONE;
}
@@ -988,7 +991,7 @@ public class ConnectivityManager {
private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
int delay = -1;
- int type = networkTypeForNetworkCapabilities(netCap);
+ int type = legacyTypeForNetworkCapabilities(netCap);
try {
delay = mService.getRestoreDefaultNetworkDelay(type);
} catch (RemoteException e) {}
@@ -997,7 +1000,7 @@ public class ConnectivityManager {
l.delay = delay;
l.expireSequenceNumber = 0;
l.networkRequest = sendRequestForNetwork(netCap, l.networkCallbackListener, 0,
- REQUEST, true);
+ REQUEST, type);
if (l.networkRequest == null) return null;
sLegacyRequests.put(netCap, l);
sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
@@ -2144,7 +2147,7 @@ public class ConnectivityManager {
private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener, int timeoutSec, int action,
- boolean legacy) {
+ int legacyType) {
NetworkRequest networkRequest = null;
if (networkCallbackListener == null) {
throw new IllegalArgumentException("null NetworkCallbackListener");
@@ -2157,7 +2160,7 @@ public class ConnectivityManager {
new Binder());
} else {
networkRequest = mService.requestNetwork(need, new Messenger(sCallbackHandler),
- timeoutSec, new Binder(), legacy);
+ timeoutSec, new Binder(), legacyType);
}
if (networkRequest != null) {
synchronized(sNetworkCallbackListener) {
@@ -2187,7 +2190,7 @@ public class ConnectivityManager {
*/
public NetworkRequest requestNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener) {
- return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, false);
+ return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, TYPE_NONE);
}
/**
@@ -2210,7 +2213,8 @@ public class ConnectivityManager {
*/
public NetworkRequest requestNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener, int timeoutSec) {
- return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST, false);
+ return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST,
+ TYPE_NONE);
}
/**
@@ -2288,7 +2292,7 @@ public class ConnectivityManager {
*/
public NetworkRequest listenForNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener) {
- return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, false);
+ return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, TYPE_NONE);
}
/**
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b67ae88..5f1ff3e 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -158,7 +158,7 @@ interface IConnectivityManager
in NetworkCapabilities nc, int score);
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, int timeoutSec, in IBinder binder, boolean legacy);
+ in Messenger messenger, int timeoutSec, in IBinder binder, int legacy);
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation);
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index ccc56e2..d279412 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -188,6 +188,15 @@ public class NetworkInfo implements Parcelable {
}
/**
+ * @hide
+ */
+ public void setType(int type) {
+ synchronized (this) {
+ mNetworkType = type;
+ }
+ }
+
+ /**
* Return a network-type-specific integer describing the subtype
* of the network.
* @return the network subtype
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 480cb05..47377e9 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -47,19 +47,19 @@ public class NetworkRequest implements Parcelable {
public final int requestId;
/**
- * Set for legacy requests and the default.
+ * Set for legacy requests and the default. Set to TYPE_NONE for none.
* Causes CONNECTIVITY_ACTION broadcasts to be sent.
* @hide
*/
- public final boolean needsBroadcasts;
+ public final int legacyType;
/**
* @hide
*/
- public NetworkRequest(NetworkCapabilities nc, boolean needsBroadcasts, int rId) {
+ public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId) {
requestId = rId;
networkCapabilities = nc;
- this.needsBroadcasts = needsBroadcasts;
+ this.legacyType = legacyType;
}
/**
@@ -68,7 +68,7 @@ public class NetworkRequest implements Parcelable {
public NetworkRequest(NetworkRequest that) {
networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
requestId = that.requestId;
- needsBroadcasts = that.needsBroadcasts;
+ this.legacyType = that.legacyType;
}
// implement the Parcelable interface
@@ -77,16 +77,16 @@ public class NetworkRequest implements Parcelable {
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(networkCapabilities, flags);
- dest.writeInt(needsBroadcasts ? 1 : 0);
+ dest.writeInt(legacyType);
dest.writeInt(requestId);
}
public static final Creator<NetworkRequest> CREATOR =
new Creator<NetworkRequest>() {
public NetworkRequest createFromParcel(Parcel in) {
NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
- boolean needsBroadcasts = (in.readInt() == 1);
+ int legacyType = in.readInt();
int requestId = in.readInt();
- NetworkRequest result = new NetworkRequest(nc, needsBroadcasts, requestId);
+ NetworkRequest result = new NetworkRequest(nc, legacyType, requestId);
return result;
}
public NetworkRequest[] newArray(int size) {
@@ -95,14 +95,14 @@ public class NetworkRequest implements Parcelable {
};
public String toString() {
- return "NetworkRequest [ id=" + requestId + ", needsBroadcasts=" + needsBroadcasts +
+ return "NetworkRequest [ id=" + requestId + ", legacyType=" + legacyType +
", " + networkCapabilities.toString() + " ]";
}
public boolean equals(Object obj) {
if (obj instanceof NetworkRequest == false) return false;
NetworkRequest that = (NetworkRequest)obj;
- return (that.needsBroadcasts == this.needsBroadcasts &&
+ return (that.legacyType == this.legacyType &&
that.requestId == this.requestId &&
((that.networkCapabilities == null && this.networkCapabilities == null) ||
(that.networkCapabilities != null &&
@@ -110,7 +110,7 @@ public class NetworkRequest implements Parcelable {
}
public int hashCode() {
- return requestId + (needsBroadcasts ? 1013 : 2026) +
+ return requestId + (legacyType * 1013) +
(networkCapabilities.hashCode() * 1051);
}
}
diff --git a/core/java/android/provider/TvContract.java b/core/java/android/provider/TvContract.java
deleted file mode 100644
index 0d90a16..0000000
--- a/core/java/android/provider/TvContract.java
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * 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 android.provider;
-
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.net.Uri;
-import android.tv.TvInputService;
-
-import java.util.List;
-
-/**
- * <p>
- * The contract between the TV provider and applications. Contains definitions for the supported
- * URIs and columns.
- * </p>
- * <h3>Overview</h3>
- * <p>
- * TvContract defines a basic database of TV content metadata such as channel and program
- * information. The information is stored in {@link Channels} and {@link Programs} tables.
- * </p>
- * <ul>
- * <li>A row in the {@link Channels} table represents information about a TV channel. The data
- * format can vary greatly from standard to standard or according to service provider, thus
- * the columns here are mostly comprised of basic entities that are usually seen to users
- * regardless of standard such as channel number and name.</li>
- * <li>A row in the {@link Programs} table represents a set of data describing a TV program such
- * as program title and start time.</li>
- * </ul>
- */
-public final class TvContract {
- /** The authority for the TV provider. */
- public static final String AUTHORITY = "com.android.tv";
-
- private static final String PATH_CHANNEL = "channel";
- private static final String PATH_PROGRAM = "program";
- private static final String PATH_INPUT = "input";
-
- /**
- * An optional query, update or delete URI parameter that allows the caller to specify start
- * time (in milliseconds since the epoch) to filter programs.
- *
- * @hide
- */
- public static final String PARAM_START_TIME = "start_time";
-
- /**
- * An optional query, update or delete URI parameter that allows the caller to specify end time
- * (in milliseconds since the epoch) to filter programs.
- *
- * @hide
- */
- public static final String PARAM_END_TIME = "end_time";
-
- /**
- * A query, update or delete URI parameter that allows the caller to operate on all or
- * browsable-only channels. If set to "true", the rows that contain non-browsable channels are
- * not affected.
- *
- * @hide
- */
- public static final String PARAM_BROWSABLE_ONLY = "browsable_only";
-
- /**
- * Builds a URI that points to a specific channel.
- *
- * @param channelId The ID of the channel to point to.
- */
- public static final Uri buildChannelUri(long channelId) {
- return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId);
- }
-
- /**
- * Builds a URI that points to all browsable channels from a given TV input.
- *
- * @param name {@link ComponentName} of the {@link android.tv.TvInputService} that implements
- * the given TV input.
- */
- public static final Uri buildChannelsUriForInput(ComponentName name) {
- return buildChannelsUriForInput(name, true);
- }
-
- /**
- * Builds a URI that points to all or browsable-only channels from a given TV input.
- *
- * @param name {@link ComponentName} of the {@link android.tv.TvInputService} that implements
- * the given TV input.
- * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set
- * to {@code false} the URI points to all channels regardless of whether they are
- * browsable or not.
- */
- public static final Uri buildChannelsUriForInput(ComponentName name, boolean browsableOnly) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY)
- .appendPath(PATH_INPUT).appendPath(name.getPackageName())
- .appendPath(name.getClassName()).appendPath(PATH_CHANNEL)
- .appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly)).build();
- }
-
- /**
- * Builds a URI that points to a specific program.
- *
- * @param programId The ID of the program to point to.
- */
- public static final Uri buildProgramUri(long programId) {
- return ContentUris.withAppendedId(Programs.CONTENT_URI, programId);
- }
-
- /**
- * Builds a URI that points to all programs on a given channel.
- *
- * @param channelUri The URI of the channel to return programs for.
- */
- public static final Uri buildProgramsUriForChannel(Uri channelUri) {
- if (!PATH_CHANNEL.equals(channelUri.getPathSegments().get(0))) {
- throw new IllegalArgumentException("Not a channel: " + channelUri);
- }
- String channelId = String.valueOf(ContentUris.parseId(channelUri));
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY)
- .appendPath(PATH_CHANNEL).appendPath(channelId).appendPath(PATH_PROGRAM).build();
- }
-
- /**
- * Builds a URI that points to programs on a specific channel whose schedules overlap with the
- * given time frame.
- *
- * @param channelUri The URI of the channel to return programs for.
- * @param startTime The start time used to filter programs. The returned programs should have
- * {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
- * @param endTime The end time used to filter programs. The returned programs should have
- * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
- */
- public static final Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
- long endTime) {
- Uri uri = buildProgramsUriForChannel(channelUri);
- return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime))
- .appendQueryParameter(PARAM_END_TIME, String.valueOf(endTime)).build();
- }
-
- /**
- * Builds a URI that points to a specific program the user watched.
- *
- * @param watchedProgramId The ID of the watched program to point to.
- * @hide
- */
- public static final Uri buildWatchedProgramUri(long watchedProgramId) {
- return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId);
- }
-
- /**
- * Extracts the {@link Channels#COLUMN_PACKAGE_NAME} from a given URI.
- *
- * @param channelsUri A URI constructed by {@link #buildChannelsUriForInput(ComponentName)} or
- * {@link #buildChannelsUriForInput(ComponentName, boolean)}.
- * @hide
- */
- public static final String getPackageName(Uri channelsUri) {
- final List<String> paths = channelsUri.getPathSegments();
- if (paths.size() < 4) {
- throw new IllegalArgumentException("Not channels: " + channelsUri);
- }
- if (!PATH_INPUT.equals(paths.get(0)) || !PATH_CHANNEL.equals(paths.get(3))) {
- throw new IllegalArgumentException("Not channels: " + channelsUri);
- }
- return paths.get(1);
- }
-
- /**
- * Extracts the {@link Channels#COLUMN_SERVICE_NAME} from a given URI.
- *
- * @param channelsUri A URI constructed by {@link #buildChannelsUriForInput(ComponentName)} or
- * {@link #buildChannelsUriForInput(ComponentName, boolean)}.
- * @hide
- */
- public static final String getServiceName(Uri channelsUri) {
- final List<String> paths = channelsUri.getPathSegments();
- if (paths.size() < 4) {
- throw new IllegalArgumentException("Not channels: " + channelsUri);
- }
- if (!PATH_INPUT.equals(paths.get(0)) || !PATH_CHANNEL.equals(paths.get(3))) {
- throw new IllegalArgumentException("Not channels: " + channelsUri);
- }
- return paths.get(2);
- }
-
- /**
- * Extracts the {@link Channels#_ID} from a given URI.
- *
- * @param programsUri A URI constructed by {@link #buildProgramsUriForChannel(Uri)} or
- * {@link #buildProgramsUriForChannel(Uri, long, long)}.
- * @hide
- */
- public static final String getChannelId(Uri programsUri) {
- final List<String> paths = programsUri.getPathSegments();
- if (paths.size() < 3) {
- throw new IllegalArgumentException("Not programs: " + programsUri);
- }
- if (!PATH_CHANNEL.equals(paths.get(0)) || !PATH_PROGRAM.equals(paths.get(2))) {
- throw new IllegalArgumentException("Not programs: " + programsUri);
- }
- return paths.get(1);
- }
-
-
- private TvContract() {}
-
- /**
- * Common base for the tables of TV channels/programs.
- */
- public interface BaseTvColumns extends BaseColumns {
- /**
- * The name of the package that owns a row in each table.
- * <p>
- * The TV provider fills it in with the name of the package that provides the initial data
- * of that row. If the package is later uninstalled, the rows it owns are automatically
- * removed from the tables.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_PACKAGE_NAME = "package_name";
- }
-
- /** Column definitions for the TV channels table. */
- public static final class Channels implements BaseTvColumns {
-
- /** The content:// style URI for this table. */
- public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
- + PATH_CHANNEL);
-
- /** The MIME type of a directory of TV channels. */
- public static final String CONTENT_TYPE =
- "vnd.android.cursor.dir/vnd.com.android.tv.channels";
-
- /** The MIME type of a single TV channel. */
- public static final String CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.com.android.tv.channels";
-
- /** A generic channel type. */
- public static final int TYPE_OTHER = 0x0;
-
- /** The special channel type used for pass-through inputs such as HDMI. */
- public static final int TYPE_PASSTHROUGH = 0x00010000;
-
- /** The channel type for DVB-T (terrestrial). */
- public static final int TYPE_DVB_T = 0x00020000;
-
- /** The channel type for DVB-T2 (terrestrial). */
- public static final int TYPE_DVB_T2 = 0x00020001;
-
- /** The channel type for DVB-S (satellite). */
- public static final int TYPE_DVB_S = 0x00020100;
-
- /** The channel type for DVB-S2 (satellite). */
- public static final int TYPE_DVB_S2 = 0x00020101;
-
- /** The channel type for DVB-C (cable). */
- public static final int TYPE_DVB_C = 0x00020200;
-
- /** The channel type for DVB-C2 (cable). */
- public static final int TYPE_DVB_C2 = 0x00020201;
-
- /** The channel type for DVB-H (handheld). */
- public static final int TYPE_DVB_H = 0x00020300;
-
- /** The channel type for DVB-SH (satellite). */
- public static final int TYPE_DVB_SH = 0x00020400;
-
- /** The channel type for ATSC (terrestrial). */
- public static final int TYPE_ATSC_T = 0x00030000;
-
- /** The channel type for ATSC (cable). */
- public static final int TYPE_ATSC_C = 0x00030200;
-
- /** The channel type for ATSC-M/H (mobile/handheld). */
- public static final int TYPE_ATSC_M_H = 0x00030200;
-
- /** The channel type for ISDB-T (terrestrial). */
- public static final int TYPE_ISDB_T = 0x00040000;
-
- /** The channel type for ISDB-Tb (Brazil). */
- public static final int TYPE_ISDB_TB = 0x00040100;
-
- /** The channel type for ISDB-S (satellite). */
- public static final int TYPE_ISDB_S = 0x00040200;
-
- /** The channel type for ISDB-C (cable). */
- public static final int TYPE_ISDB_C = 0x00040300;
-
- /** The channel type for 1seg (handheld). */
- public static final int TYPE_1SEG = 0x00040400;
-
- /** The channel type for DTMB (terrestrial). */
- public static final int TYPE_DTMB = 0x00050000;
-
- /** The channel type for CMMB (handheld). */
- public static final int TYPE_CMMB = 0x00050100;
-
- /** The channel type for T-DMB (terrestrial). */
- public static final int TYPE_T_DMB = 0x00060000;
-
- /** The channel type for S-DMB (satellite). */
- public static final int TYPE_S_DMB = 0x00060100;
-
- /** A generic service type. */
- public static final int SERVICE_TYPE_OTHER = 0x0;
-
- /** The service type for regular TV channels. */
- public static final int SERVICE_TYPE_TV = 0x1;
-
- /** The service type for radio channels. */
- public static final int SERVICE_TYPE_RADIO = 0x2;
-
- /**
- * The name of the {@link TvInputService} subclass that provides this TV channel. This
- * should be a fully qualified class name (such as, "com.example.project.TvInputService").
- * <p>
- * This is a required field.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_SERVICE_NAME = "service_name";
-
- /**
- * The predefined type of this TV channel.
- * <p>
- * This is primarily used to indicate which broadcast standard (e.g. ATSC, DVB or ISDB) the
- * current channel conforms to, with an exception being {@link #TYPE_PASSTHROUGH}, which is
- * a special channel type used only by pass-through inputs such as HDMI. The value should
- * match to one of the followings: {@link #TYPE_OTHER}, {@link #TYPE_PASSTHROUGH},
- * {@link #TYPE_DVB_T}, {@link #TYPE_DVB_T2}, {@link #TYPE_DVB_S}, {@link #TYPE_DVB_S2},
- * {@link #TYPE_DVB_C}, {@link #TYPE_DVB_C2}, {@link #TYPE_DVB_H}, {@link #TYPE_DVB_SH},
- * {@link #TYPE_ATSC_T}, {@link #TYPE_ATSC_C}, {@link #TYPE_ATSC_M_H}, {@link #TYPE_ISDB_T},
- * {@link #TYPE_ISDB_TB}, {@link #TYPE_ISDB_S}, {@link #TYPE_ISDB_C} {@link #TYPE_1SEG},
- * {@link #TYPE_DTMB}, {@link #TYPE_CMMB}, {@link #TYPE_T_DMB}, {@link #TYPE_S_DMB}
- * </p><p>
- * This is a required field.
- * </p><p>
- * Type: INTEGER
- * </p>
- */
- public static final String COLUMN_TYPE = "type";
-
- /**
- * The predefined service type of this TV channel.
- * <p>
- * This is primarily used to indicate whether the current channel is a regular TV channel or
- * a radio-like channel. Use the same coding for {@code service_type} in the underlying
- * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB
- * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER},
- * {@link #SERVICE_TYPE_TV}, {@link #SERVICE_TYPE_RADIO}
- * </p><p>
- * This is a required field.
- * </p><p>
- * Type: INTEGER
- * </p>
- */
- public static final String COLUMN_SERVICE_TYPE = "service_type";
-
- /**
- * The original network ID of this TV channel.
- * <p>
- * This is used to identify the originating delivery system, if applicable. Use the same
- * coding for {@code origianal_network_id} in the underlying broadcast standard if it is
- * defined there (e.g. ETSI EN 300 468/TR 101 211 and ARIB STD-B10). If channels cannot be
- * globally identified by 2-tuple {{@link #COLUMN_TRANSPORT_STREAM_ID},
- * {@link #COLUMN_SERVICE_ID}}, one must carefully assign a value to this field to form a
- * unique 3-tuple identification {{@link #COLUMN_ORIGINAL_NETWORK_ID},
- * {@link #COLUMN_TRANSPORT_STREAM_ID}, {@link #COLUMN_SERVICE_ID}} for its channels.
- * </p><p>
- * This is a required field if the channel cannot be uniquely identified by a 2-tuple
- * {{@link #COLUMN_TRANSPORT_STREAM_ID}, {@link #COLUMN_SERVICE_ID}}.
- * </p><p>
- * Type: INTEGER
- * </p>
- */
- public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
-
- /**
- * The transport stream ID of this channel.
- * <p>
- * This is used to identify the Transport Stream that contains the current channel from any
- * other multiplex within a network, if applicable. Use the same coding for
- * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via
- * the MPEG Transport Stream as is the case for many digital broadcast standards.
- * </p><p>
- * This is a required field if the current channel is transmitted via the MPEG Transport
- * Stream.
- * </p><p>
- * Type: INTEGER
- * </p>
- */
- public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
-
- /**
- * The service ID of this channel.
- * <p>
- * This is used to identify the current service (roughly equivalent to channel) from any
- * other service within the Transport Stream, if applicable. Use the same coding for
- * {@code service_id} in the underlying broadcast standard if it is defined there (e.g. ETSI
- * EN 300 468 and ARIB STD-B10) or {@code program_number} (which usually has the same value
- * as {@code service_id}) in ISO/IEC 13818-1 if the channel is transmitted via the MPEG
- * Transport Stream.
- * </p><p>
- * This is a required field if the current channel is transmitted via the MPEG Transport
- * Stream.
- * </p><p>
- * Type: INTEGER
- * </p>
- */
- public static final String COLUMN_SERVICE_ID = "service_id";
-
- /**
- * The channel number that is displayed to the user.
- * <p>
- * The format can vary depending on broadcast standard and product specification.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_DISPLAY_NUMBER = "display_number";
-
- /**
- * The channel name that is displayed to the user.
- * <p>
- * A call sign is a good candidate to use for this purpose but any name that helps the user
- * recognize the current channel will be enough. Can also be empty depending on broadcast
- * standard.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_DISPLAY_NAME = "display_name";
-
- /**
- * The description of this TV channel.
- * <p>
- * Can be empty initially.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_DESCRIPTION = "description";
-
- /**
- * The flag indicating whether this TV channel is browsable or not.
- * <p>
- * A value of 1 indicates the channel is included in the channel list that applications use
- * to browse channels, a value of 0 indicates the channel is not included in the list. If
- * not specified, this value is set to 1 (browsable) by default.
- * </p><p>
- * Type: INTEGER (boolean)
- * </p>
- */
- public static final String COLUMN_BROWSABLE = "browsable";
-
- /**
- * The flag indicating whether this TV channel is searchable or not.
- * <p>
- * In some regions, it is not allowed to surface search results for a given channel without
- * broadcaster's consent. This is used to impose such restriction. A value of 1 indicates
- * the channel is searchable and can be included in search results, a value of 0 indicates
- * the channel and its TV programs are hidden from search. If not specified, this value is
- * set to 1 (searchable) by default.
- * </p>
- * <p>
- * Type: INTEGER (boolean)
- * </p>
- */
- public static final String COLUMN_SEARCHABLE = "searchable";
-
- /**
- * The flag indicating whether this TV channel is locked or not.
- * <p>
- * This is primarily used for alternative parental control to prevent unauthorized users
- * from watching the current channel regardless of the content rating. A value of 1
- * indicates the channel is locked and the user is required to enter passcode to unlock it
- * in order to watch the current program from the channel, a value of 0 indicates the
- * channel is not locked thus the user is not prompted to enter passcode If not specified,
- * this value is set to 0 (not locked) by default.
- * </p><p>
- * Type: INTEGER (boolean)
- * </p>
- */
- public static final String COLUMN_LOCKED = "locked";
-
- /**
- * Generic data used by individual TV input services.
- * <p>
- * Type: BLOB
- * </p>
- */
- public static final String COLUMN_DATA = "data";
-
-
- /**
- * The version number of this row entry used by TV input services.
- * <p>
- * This is best used by sync adapters to identify the rows to update. The number can be
- * defined by individual TV input services. One may assign the same value as
- * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are
- * coming from a TV broadcast.
- * </p><p>
- * Type: INTEGER
- * </p>
- */
- public static final String COLUMN_VERSION_NUMBER = "version_number";
-
- private Channels() {}
- }
-
- /** Column definitions for the TV programs table. */
- public static final class Programs implements BaseTvColumns {
-
- /** The content:// style URI for this table. */
- public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
- + PATH_PROGRAM);
-
- /** The MIME type of a directory of TV programs. */
- public static final String CONTENT_TYPE =
- "vnd.android.cursor.dir/vnd.com.android.tv.programs";
-
- /** The MIME type of a single TV program. */
- public static final String CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.com.android.tv.programs";
-
- /**
- * The ID of the TV channel that contains this TV program.
- * <p>
- * This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
- * </p><p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_CHANNEL_ID = "channel_id";
-
- /**
- * The title of this TV program.
- * <p>
- * Type: TEXT
- * </p>
- **/
- public static final String COLUMN_TITLE = "title";
-
- /**
- * The start time of this TV program, in milliseconds since the epoch.
- * <p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
-
- /**
- * The end time of this TV program, in milliseconds since the epoch.
- * <p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
-
- /**
- * The comma-separated genre string of this TV program.
- * <p>
- * Use the same language appeared in the underlying broadcast standard, if applicable. (For
- * example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
- * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, use one of the
- * following genres:
- * <ul>
- * <li>Family/Kids</li>
- * <li>Sports</li>
- * <li>Shopping</li>
- * <li>Movies</li>
- * <li>Comedy</li>
- * <li>Travel</li>
- * <li>Drama</li>
- * <li>Education</li>
- * <li>Animal/Wildlife</li>
- * <li>News</li>
- * <li>Gaming</li>
- * <li>Others</li>
- * </ul>
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_GENRE = "genre";
-
- /**
- * The description of this TV program that is displayed to the user by default.
- * <p>
- * The maximum length of this field is 256 characters.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_DESCRIPTION = "description";
-
- /**
- * The detailed, lengthy description of this TV program that is displayed only when the user
- * wants to see more information.
- * <p>
- * TV input services should leave this field empty if they have no additional
- * details beyond {@link #COLUMN_DESCRIPTION}.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_LONG_DESCRIPTION = "long_description";
-
- /**
- * The comma-separated audio languages of this TV program.
- * <p>
- * This is used to describe available audio languages included in the program. Use
- * 3-character language code as specified by ISO 639-2.
- * </p><p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";
-
- /**
- * Generic data used by TV input services.
- * <p>
- * Type: BLOB
- * </p>
- */
- public static final String COLUMN_DATA = "data";
-
- /**
- * The version number of this row entry used by TV input services.
- * <p>
- * This is best used by sync adapters to identify the rows to update. The number can be
- * defined by individual TV input services. One may assign the same value as
- * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV
- * broadcast.
- * </p><p>
- * Type: INTEGER
- * </p>
- */
- public static final String COLUMN_VERSION_NUMBER = "version_number";
-
- private Programs() {}
- }
-
- /**
- * Column definitions for the TV programs that the user watched. Applications do not have access
- * to this table.
- *
- * @hide
- */
- public static final class WatchedPrograms implements BaseColumns {
-
- /** The content:// style URI for this table. */
- public static final Uri CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/watched_program");
-
- /** The MIME type of a directory of watched programs. */
- public static final String CONTENT_TYPE =
- "vnd.android.cursor.dir/vnd.com.android.tv.watched_programs";
-
- /** The MIME type of a single item in this table. */
- public static final String CONTENT_ITEM_TYPE =
- "vnd.android.cursor.item/vnd.com.android.tv.watched_programs";
-
- /**
- * The UTC time that the user started watching this TV program, in milliseconds since the
- * epoch.
- * <p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS =
- "watch_start_time_utc_millis";
-
- /**
- * The UTC time that the user stopped watching this TV program, in milliseconds since the
- * epoch.
- * <p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis";
-
- /**
- * The channel ID that contains this TV program.
- * <p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_CHANNEL_ID = "channel_id";
-
- /**
- * The title of this TV program.
- * <p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_TITLE = "title";
-
- /**
- * The start time of this TV program, in milliseconds since the epoch.
- * <p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
-
- /**
- * The end time of this TV program, in milliseconds since the epoch.
- * <p>
- * Type: INTEGER (long)
- * </p>
- */
- public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
-
- /**
- * The description of this TV program.
- * <p>
- * Type: TEXT
- * </p>
- */
- public static final String COLUMN_DESCRIPTION = "description";
-
- private WatchedPrograms() {}
- }
-}
diff --git a/core/java/android/tv/ITvInputClient.aidl b/core/java/android/tv/ITvInputClient.aidl
deleted file mode 100644
index ef89c68..0000000
--- a/core/java/android/tv/ITvInputClient.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.content.ComponentName;
-import android.os.Bundle;
-import android.tv.ITvInputSession;
-import android.view.InputChannel;
-
-/**
- * Interface a client of the ITvInputManager implements, to identify itself and receive information
- * about changes to the state of each TV input service.
- * @hide
- */
-oneway interface ITvInputClient {
- void onSessionCreated(in String inputId, IBinder token, in InputChannel channel, int seq);
- void onAvailabilityChanged(in String inputId, boolean isAvailable);
- void onSessionReleased(int seq);
- void onSessionEvent(in String name, in Bundle args, int seq);
- void onVideoSizeChanged(int width, int height, int seq);
-}
diff --git a/core/java/android/tv/ITvInputHardware.aidl b/core/java/android/tv/ITvInputHardware.aidl
deleted file mode 100644
index 7250453..0000000
--- a/core/java/android/tv/ITvInputHardware.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.tv.TvStreamConfig;
-import android.view.KeyEvent;
-import android.view.Surface;
-
-/**
- * TvInputService representing a physical port should connect to HAL through this interface.
- * Framework will take care of communication among system services including TvInputManagerService,
- * HdmiControlService, AudioService, etc.
- *
- * @hide
- */
-interface ITvInputHardware {
- /**
- * Make the input render on the surface according to the config. In case of HDMI, this will
- * trigger CEC commands for adjusting active HDMI source. Returns true on success.
- */
- boolean setSurface(in Surface surface, in TvStreamConfig config);
- /**
- * Set volume for this stream via AudioGain. (TBD)
- */
- void setVolume(float volume);
-
- /**
- * Dispatch key event to HDMI service. The events would be automatically converted to
- * HDMI CEC commands. If the hardware is not representing an HDMI port, this method will fail.
- */
- boolean dispatchKeyEventToHdmi(in KeyEvent event);
-}
diff --git a/core/java/android/tv/ITvInputHardwareCallback.aidl b/core/java/android/tv/ITvInputHardwareCallback.aidl
deleted file mode 100644
index 83041be..0000000
--- a/core/java/android/tv/ITvInputHardwareCallback.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.tv.TvStreamConfig;
-
-/**
- * @hide
- */
-oneway interface ITvInputHardwareCallback {
- void onReleased();
- void onStreamConfigChanged(in TvStreamConfig[] configs);
-}
diff --git a/core/java/android/tv/ITvInputManager.aidl b/core/java/android/tv/ITvInputManager.aidl
deleted file mode 100644
index c6f8d79..0000000
--- a/core/java/android/tv/ITvInputManager.aidl
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.content.ComponentName;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.tv.ITvInputHardware;
-import android.tv.ITvInputHardwareCallback;
-import android.tv.ITvInputClient;
-import android.tv.TvInputHardwareInfo;
-import android.tv.TvInputInfo;
-import android.view.Surface;
-
-/**
- * Interface to the TV input manager service.
- * @hide
- */
-interface ITvInputManager {
- List<TvInputInfo> getTvInputList(int userId);
-
- boolean getAvailability(in ITvInputClient client, in String inputId, int userId);
-
- void registerCallback(in ITvInputClient client, in String inputId, int userId);
- void unregisterCallback(in ITvInputClient client, in String inputId, int userId);
-
- void createSession(in ITvInputClient client, in String inputId, int seq, int userId);
- void releaseSession(in IBinder sessionToken, int userId);
-
- void setSurface(in IBinder sessionToken, in Surface surface, int userId);
- void setVolume(in IBinder sessionToken, float volume, int userId);
- void tune(in IBinder sessionToken, in Uri channelUri, int userId);
-
- void createOverlayView(in IBinder sessionToken, in IBinder windowToken, in Rect frame,
- int userId);
- void relayoutOverlayView(in IBinder sessionToken, in Rect frame, int userId);
- void removeOverlayView(in IBinder sessionToken, int userId);
-
- // For TV input hardware binding
- List<TvInputHardwareInfo> getHardwareList();
- ITvInputHardware acquireTvInputHardware(int deviceId, in ITvInputHardwareCallback callback,
- int userId);
- void releaseTvInputHardware(int deviceId, in ITvInputHardware hardware, int userId);
-}
diff --git a/core/java/android/tv/ITvInputService.aidl b/core/java/android/tv/ITvInputService.aidl
deleted file mode 100644
index 4f1bc2b..0000000
--- a/core/java/android/tv/ITvInputService.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.tv.ITvInputServiceCallback;
-import android.tv.ITvInputSessionCallback;
-import android.view.InputChannel;
-
-/**
- * Top-level interface to a TV input component (implemented in a Service).
- * @hide
- */
-oneway interface ITvInputService {
- void registerCallback(ITvInputServiceCallback callback);
- void unregisterCallback(in ITvInputServiceCallback callback);
- void createSession(in InputChannel channel, ITvInputSessionCallback callback);
-}
diff --git a/core/java/android/tv/ITvInputServiceCallback.aidl b/core/java/android/tv/ITvInputServiceCallback.aidl
deleted file mode 100644
index 71fc780..0000000
--- a/core/java/android/tv/ITvInputServiceCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.content.ComponentName;
-
-/**
- * Helper interface for ITvInputService to allow the TV input to notify the client when its status
- * has been changed.
- * @hide
- */
-oneway interface ITvInputServiceCallback {
- void onAvailabilityChanged(in String inputId, boolean isAvailable);
-}
diff --git a/core/java/android/tv/ITvInputSession.aidl b/core/java/android/tv/ITvInputSession.aidl
deleted file mode 100644
index 32fee4b..0000000
--- a/core/java/android/tv/ITvInputSession.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.graphics.Rect;
-import android.net.Uri;
-import android.view.Surface;
-
-/**
- * Sub-interface of ITvInputService which is created per session and has its own context.
- * @hide
- */
-oneway interface ITvInputSession {
- void release();
-
- void setSurface(in Surface surface);
- // TODO: Remove this once it becomes irrelevant for applications to handle audio focus. The plan
- // is to introduce some new concepts that will solve a number of problems in audio policy today.
- void setVolume(float volume);
- void tune(in Uri channelUri);
-
- void createOverlayView(in IBinder windowToken, in Rect frame);
- void relayoutOverlayView(in Rect frame);
- void removeOverlayView();
-}
diff --git a/core/java/android/tv/ITvInputSessionCallback.aidl b/core/java/android/tv/ITvInputSessionCallback.aidl
deleted file mode 100644
index e27b8bf..0000000
--- a/core/java/android/tv/ITvInputSessionCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.os.Bundle;
-import android.tv.ITvInputSession;
-
-/**
- * Helper interface for ITvInputSession to allow the TV input to notify the system service when a
- * new session has been created.
- * @hide
- */
-oneway interface ITvInputSessionCallback {
- void onSessionCreated(ITvInputSession session);
- void onSessionEvent(in String name, in Bundle args);
- void onVideoSizeChanged(int width, int height);
-}
diff --git a/core/java/android/tv/ITvInputSessionWrapper.java b/core/java/android/tv/ITvInputSessionWrapper.java
deleted file mode 100644
index 3ccccf3..0000000
--- a/core/java/android/tv/ITvInputSessionWrapper.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.tv.TvInputManager.Session;
-import android.tv.TvInputService.TvInputSessionImpl;
-import android.util.Log;
-import android.view.InputChannel;
-import android.view.InputEvent;
-import android.view.InputEventReceiver;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-
-import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.SomeArgs;
-
-/**
- * Implements the internal ITvInputSession interface to convert incoming calls on to it back to
- * calls on the public TvInputSession interface, scheduling them on the main thread of the process.
- *
- * @hide
- */
-public class ITvInputSessionWrapper extends ITvInputSession.Stub implements HandlerCaller.Callback {
- private static final String TAG = "TvInputSessionWrapper";
-
- private static final int DO_RELEASE = 1;
- private static final int DO_SET_SURFACE = 2;
- private static final int DO_SET_VOLUME = 3;
- private static final int DO_TUNE = 4;
- private static final int DO_CREATE_OVERLAY_VIEW = 5;
- private static final int DO_RELAYOUT_OVERLAY_VIEW = 6;
- private static final int DO_REMOVE_OVERLAY_VIEW = 7;
-
- private final HandlerCaller mCaller;
-
- private TvInputSessionImpl mTvInputSessionImpl;
- private InputChannel mChannel;
- private TvInputEventReceiver mReceiver;
-
- public ITvInputSessionWrapper(Context context, TvInputSessionImpl sessionImpl,
- InputChannel channel) {
- mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
- mTvInputSessionImpl = sessionImpl;
- mChannel = channel;
- if (channel != null) {
- mReceiver = new TvInputEventReceiver(channel, context.getMainLooper());
- }
- }
-
- @Override
- public void executeMessage(Message msg) {
- if (mTvInputSessionImpl == null) {
- return;
- }
-
- switch (msg.what) {
- case DO_RELEASE: {
- mTvInputSessionImpl.release();
- mTvInputSessionImpl = null;
- if (mReceiver != null) {
- mReceiver.dispose();
- mReceiver = null;
- }
- if (mChannel != null) {
- mChannel.dispose();
- mChannel = null;
- }
- return;
- }
- case DO_SET_SURFACE: {
- mTvInputSessionImpl.setSurface((Surface) msg.obj);
- return;
- }
- case DO_SET_VOLUME: {
- mTvInputSessionImpl.setVolume((Float) msg.obj);
- return;
- }
- case DO_TUNE: {
- mTvInputSessionImpl.tune((Uri) msg.obj);
- return;
- }
- case DO_CREATE_OVERLAY_VIEW: {
- SomeArgs args = (SomeArgs) msg.obj;
- mTvInputSessionImpl.createOverlayView((IBinder) args.arg1, (Rect) args.arg2);
- args.recycle();
- return;
- }
- case DO_RELAYOUT_OVERLAY_VIEW: {
- mTvInputSessionImpl.relayoutOverlayView((Rect) msg.obj);
- return;
- }
- case DO_REMOVE_OVERLAY_VIEW: {
- mTvInputSessionImpl.removeOverlayView(true);
- return;
- }
- default: {
- Log.w(TAG, "Unhandled message code: " + msg.what);
- return;
- }
- }
- }
-
- @Override
- public void release() {
- mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_RELEASE));
- }
-
- @Override
- public void setSurface(Surface surface) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_SURFACE, surface));
- }
-
- @Override
- public final void setVolume(float volume) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_VOLUME, volume));
- }
-
- @Override
- public void tune(Uri channelUri) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_TUNE, channelUri));
- }
-
- @Override
- public void createOverlayView(IBinder windowToken, Rect frame) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CREATE_OVERLAY_VIEW, windowToken,
- frame));
- }
-
- @Override
- public void relayoutOverlayView(Rect frame) {
- mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RELAYOUT_OVERLAY_VIEW, frame));
- }
-
- @Override
- public void removeOverlayView() {
- mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_OVERLAY_VIEW));
- }
-
- private final class TvInputEventReceiver extends InputEventReceiver {
- public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
- super(inputChannel, looper);
- }
-
- @Override
- public void onInputEvent(InputEvent event) {
- if (mTvInputSessionImpl == null) {
- // The session has been finished.
- finishInputEvent(event, false);
- return;
- }
-
- int handled = mTvInputSessionImpl.dispatchInputEvent(event, this);
- if (handled != Session.DISPATCH_IN_PROGRESS) {
- finishInputEvent(event, handled == Session.DISPATCH_HANDLED);
- }
- }
- }
-}
diff --git a/core/java/android/tv/TvInputHardwareInfo.aidl b/core/java/android/tv/TvInputHardwareInfo.aidl
deleted file mode 100644
index 484ab60..0000000
--- a/core/java/android/tv/TvInputHardwareInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 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 android.tv;
-
-parcelable TvInputHardwareInfo;
diff --git a/core/java/android/tv/TvInputHardwareInfo.java b/core/java/android/tv/TvInputHardwareInfo.java
deleted file mode 100644
index b0dc58e..0000000
--- a/core/java/android/tv/TvInputHardwareInfo.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-/**
- * Simple container for information about TV input hardware.
- * Not for third-party developers.
- *
- * @hide
- */
-public final class TvInputHardwareInfo implements Parcelable {
- static final String TAG = "TvInputHardwareInfo";
-
- // Match hardware/libhardware/include/hardware/tv_input.h
- public static final int TV_INPUT_TYPE_HDMI = 1;
- public static final int TV_INPUT_TYPE_BUILT_IN_TUNER = 2;
- public static final int TV_INPUT_TYPE_PASSTHROUGH = 3;
-
- public static final Parcelable.Creator<TvInputHardwareInfo> CREATOR =
- new Parcelable.Creator<TvInputHardwareInfo>() {
- @Override
- public TvInputHardwareInfo createFromParcel(Parcel source) {
- try {
- TvInputHardwareInfo info = new TvInputHardwareInfo();
- info.readFromParcel(source);
- return info;
- } catch (Exception e) {
- Log.e(TAG, "Exception creating TvInputHardwareInfo from parcel", e);
- return null;
- }
- }
-
- @Override
- public TvInputHardwareInfo[] newArray(int size) {
- return new TvInputHardwareInfo[size];
- }
- };
-
- private int mDeviceId;
- private int mType;
- // TODO: Add audio port & audio address for audio service.
- // TODO: Add HDMI handle for HDMI service.
-
- public TvInputHardwareInfo() { }
-
- public TvInputHardwareInfo(int deviceId, int type) {
- mDeviceId = deviceId;
- mType = type;
- }
-
- public int getDeviceId() {
- return mDeviceId;
- }
-
- public int getType() {
- return mType;
- }
-
- // Parcelable
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mDeviceId);
- dest.writeInt(mType);
- }
-
- public void readFromParcel(Parcel source) {
- mDeviceId = source.readInt();
- mType = source.readInt();
- }
-}
diff --git a/core/java/android/tv/TvInputInfo.aidl b/core/java/android/tv/TvInputInfo.aidl
deleted file mode 100644
index abc4b47..0000000
--- a/core/java/android/tv/TvInputInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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 android.tv;
-
-parcelable TvInputInfo;
diff --git a/core/java/android/tv/TvInputInfo.java b/core/java/android/tv/TvInputInfo.java
deleted file mode 100644
index 217e4b7..0000000
--- a/core/java/android/tv/TvInputInfo.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.content.ComponentName;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * This class is used to specify meta information of a TV input.
- */
-public final class TvInputInfo implements Parcelable {
- private final ResolveInfo mService;
- private final String mId;
-
- /**
- * Constructor.
- *
- * @param service The ResolveInfo returned from the package manager about this TV input service.
- * @hide
- */
- public TvInputInfo(ResolveInfo service) {
- mService = service;
- ServiceInfo si = service.serviceInfo;
- mId = generateInputIdForComponentName(new ComponentName(si.packageName, si.name));
- }
-
- /**
- * Returns a unique ID for this TV input. The ID is generated from the package and class name
- * implementing the TV input service.
- */
- public String getId() {
- return mId;
- }
-
- /**
- * Returns the .apk package that implements this TV input service.
- */
- public String getPackageName() {
- return mService.serviceInfo.packageName;
- }
-
- /**
- * Returns the class name of the service component that implements this TV input service.
- */
- public String getServiceName() {
- return mService.serviceInfo.name;
- }
-
- /**
- * Returns the component of the service that implements this TV input.
- */
- public ComponentName getComponent() {
- return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name);
- }
-
- /**
- * Loads the user-displayed label for this TV input service.
- *
- * @param pm Supplies a PackageManager used to load the TV input's resources.
- * @return a CharSequence containing the TV input's label. If the TV input does not have
- * a label, its name is returned.
- */
- public CharSequence loadLabel(PackageManager pm) {
- return mService.loadLabel(pm);
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public int hashCode() {
- return mId.hashCode();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == this) {
- return true;
- }
-
- if (!(o instanceof TvInputInfo)) {
- return false;
- }
-
- TvInputInfo obj = (TvInputInfo) o;
- return mId.equals(obj.mId)
- && mService.serviceInfo.packageName.equals(obj.mService.serviceInfo.packageName)
- && mService.serviceInfo.name.equals(obj.mService.serviceInfo.name);
- }
-
- @Override
- public String toString() {
- return "TvInputInfo{id=" + mId
- + ", pkg=" + mService.serviceInfo.packageName
- + ", service=" + mService.serviceInfo.name + "}";
- }
-
- /**
- * Used to package this object into a {@link Parcel}.
- *
- * @param dest The {@link Parcel} to be written.
- * @param flags The flags used for parceling.
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(mId);
- mService.writeToParcel(dest, flags);
- }
-
- /**
- * Used to generate an input id from a ComponentName.
- *
- * @param name the component name for generating an input id.
- * @return the generated input id for the given {@code name}.
- * @hide
- */
- public static final String generateInputIdForComponentName(ComponentName name) {
- return name.flattenToShortString();
- }
-
- /**
- * Used to make this class parcelable.
- *
- * @hide
- */
- public static final Parcelable.Creator<TvInputInfo> CREATOR =
- new Parcelable.Creator<TvInputInfo>() {
- @Override
- public TvInputInfo createFromParcel(Parcel in) {
- return new TvInputInfo(in);
- }
-
- @Override
- public TvInputInfo[] newArray(int size) {
- return new TvInputInfo[size];
- }
- };
-
- private TvInputInfo(Parcel in) {
- mId = in.readString();
- mService = ResolveInfo.CREATOR.createFromParcel(in);
- }
-}
diff --git a/core/java/android/tv/TvInputManager.java b/core/java/android/tv/TvInputManager.java
deleted file mode 100644
index d0c2ca6..0000000
--- a/core/java/android/tv/TvInputManager.java
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Log;
-import android.util.Pools.Pool;
-import android.util.Pools.SimplePool;
-import android.util.SparseArray;
-import android.view.InputChannel;
-import android.view.InputEvent;
-import android.view.InputEventSender;
-import android.view.Surface;
-import android.view.View;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Central system API to the overall TV input framework (TIF) architecture, which arbitrates
- * interaction between applications and the selected TV inputs.
- */
-public final class TvInputManager {
- private static final String TAG = "TvInputManager";
-
- private final ITvInputManager mService;
-
- // A mapping from an input to the list of its TvInputListenerRecords.
- private final Map<String, List<TvInputListenerRecord>> mTvInputListenerRecordsMap =
- new HashMap<String, List<TvInputListenerRecord>>();
-
- // A mapping from the sequence number of a session to its SessionCallbackRecord.
- private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap =
- new SparseArray<SessionCallbackRecord>();
-
- // A sequence number for the next session to be created. Should be protected by a lock
- // {@code mSessionCallbackRecordMap}.
- private int mNextSeq;
-
- private final ITvInputClient mClient;
-
- private final int mUserId;
-
- /**
- * Interface used to receive the created session.
- */
- public abstract static class SessionCallback {
- /**
- * This is called after {@link TvInputManager#createSession} has been processed.
- *
- * @param session A {@link TvInputManager.Session} instance created. This can be
- * {@code null} if the creation request failed.
- */
- public void onSessionCreated(Session session) {
- }
-
- /**
- * This is called when {@link TvInputManager.Session} is released.
- * This typically happens when the process hosting the session has crashed or been killed.
- *
- * @param session A {@link TvInputManager.Session} instance released.
- */
- public void onSessionReleased(Session session) {
- }
-
- /**
- * This is called at the beginning of the playback of a channel and later when the size of
- * the video has been changed.
- *
- * @param session A {@link TvInputManager.Session} associated with this callback
- * @param width the width of the video
- * @param height the height of the video
- * @hide
- */
- public void onVideoSizeChanged(Session session, int width, int height) {
- }
-
- /**
- * This is called when a custom event has been sent from this session.
- *
- * @param session A {@link TvInputManager.Session} associated with this callback
- * @param eventType The type of the event.
- * @param eventArgs Optional arguments of the event.
- * @hide
- */
- public void onSessionEvent(Session session, String eventType, Bundle eventArgs) {
- }
- }
-
- private static final class SessionCallbackRecord {
- private final SessionCallback mSessionCallback;
- private final Handler mHandler;
- private Session mSession;
-
- public SessionCallbackRecord(SessionCallback sessionCallback,
- Handler handler) {
- mSessionCallback = sessionCallback;
- mHandler = handler;
- }
-
- public void postSessionCreated(final Session session) {
- mSession = session;
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mSessionCallback.onSessionCreated(session);
- }
- });
- }
-
- public void postSessionReleased() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mSessionCallback.onSessionReleased(mSession);
- }
- });
- }
-
- public void postVideoSizeChanged(final int width, final int height) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mSessionCallback.onVideoSizeChanged(mSession, width, height);
- }
- });
- }
-
- public void postSessionEvent(final String eventType, final Bundle eventArgs) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mSessionCallback.onSessionEvent(mSession, eventType, eventArgs);
- }
- });
- }
- }
-
- /**
- * Interface used to monitor status of the TV input.
- */
- public abstract static class TvInputListener {
- /**
- * This is called when the availability status of a given TV input is changed.
- *
- * @param inputId the id of the TV input.
- * @param isAvailable {@code true} if the given TV input is available to show TV programs.
- * {@code false} otherwise.
- */
- public void onAvailabilityChanged(String inputId, boolean isAvailable) {
- }
- }
-
- private static final class TvInputListenerRecord {
- private final TvInputListener mListener;
- private final Handler mHandler;
-
- public TvInputListenerRecord(TvInputListener listener, Handler handler) {
- mListener = listener;
- mHandler = handler;
- }
-
- public TvInputListener getListener() {
- return mListener;
- }
-
- public void postAvailabilityChanged(final String inputId, final boolean isAvailable) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mListener.onAvailabilityChanged(inputId, isAvailable);
- }
- });
- }
- }
-
- /**
- * @hide
- */
- public TvInputManager(ITvInputManager service, int userId) {
- mService = service;
- mUserId = userId;
- mClient = new ITvInputClient.Stub() {
- @Override
- public void onSessionCreated(String inputId, IBinder token, InputChannel channel,
- int seq) {
- synchronized (mSessionCallbackRecordMap) {
- SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
- if (record == null) {
- Log.e(TAG, "Callback not found for " + token);
- return;
- }
- Session session = null;
- if (token != null) {
- session = new Session(token, channel, mService, mUserId, seq,
- mSessionCallbackRecordMap);
- }
- record.postSessionCreated(session);
- }
- }
-
- @Override
- public void onSessionReleased(int seq) {
- synchronized (mSessionCallbackRecordMap) {
- SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
- mSessionCallbackRecordMap.delete(seq);
- if (record == null) {
- Log.e(TAG, "Callback not found for seq:" + seq);
- return;
- }
- record.mSession.releaseInternal();
- record.postSessionReleased();
- }
- }
-
- @Override
- public void onVideoSizeChanged(int width, int height, int seq) {
- synchronized (mSessionCallbackRecordMap) {
- SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
- if (record == null) {
- Log.e(TAG, "Callback not found for seq " + seq);
- return;
- }
- record.postVideoSizeChanged(width, height);
- }
- }
-
- @Override
- public void onSessionEvent(String eventType, Bundle eventArgs, int seq) {
- synchronized (mSessionCallbackRecordMap) {
- SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
- if (record == null) {
- Log.e(TAG, "Callback not found for seq " + seq);
- return;
- }
- record.postSessionEvent(eventType, eventArgs);
- }
- }
-
- @Override
- public void onAvailabilityChanged(String inputId, boolean isAvailable) {
- synchronized (mTvInputListenerRecordsMap) {
- List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId);
- if (records == null) {
- // Silently ignore - no listener is registered yet.
- return;
- }
- int recordsCount = records.size();
- for (int i = 0; i < recordsCount; i++) {
- records.get(i).postAvailabilityChanged(inputId, isAvailable);
- }
- }
- }
- };
- }
-
- /**
- * Returns the complete list of TV inputs on the system.
- *
- * @return List of {@link TvInputInfo} for each TV input that describes its meta information.
- */
- public List<TvInputInfo> getTvInputList() {
- try {
- return mService.getTvInputList(mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Returns the availability of a given TV input.
- *
- * @param inputId the id of the TV input.
- * @throws IllegalArgumentException if the argument is {@code null}.
- * @throws IllegalStateException If there is no {@link TvInputListener} registered on the given
- * TV input.
- */
- public boolean getAvailability(String inputId) {
- if (inputId == null) {
- throw new IllegalArgumentException("id cannot be null");
- }
- synchronized (mTvInputListenerRecordsMap) {
- List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId);
- if (records == null || records.size() == 0) {
- throw new IllegalStateException("At least one listener should be registered.");
- }
- }
- try {
- return mService.getAvailability(mClient, inputId, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Registers a {@link TvInputListener} for a given TV input.
- *
- * @param inputId the id of the TV input.
- * @param listener a listener used to monitor status of the given TV input.
- * @param handler a {@link Handler} that the status change will be delivered to.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
- */
- public void registerListener(String inputId, TvInputListener listener, Handler handler) {
- if (inputId == null) {
- throw new IllegalArgumentException("id cannot be null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null");
- }
- if (handler == null) {
- throw new IllegalArgumentException("handler cannot be null");
- }
- synchronized (mTvInputListenerRecordsMap) {
- List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId);
- if (records == null) {
- records = new ArrayList<TvInputListenerRecord>();
- mTvInputListenerRecordsMap.put(inputId, records);
- try {
- mService.registerCallback(mClient, inputId, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
- records.add(new TvInputListenerRecord(listener, handler));
- }
- }
-
- /**
- * Unregisters the existing {@link TvInputListener} for a given TV input.
- *
- * @param inputId the id of the TV input.
- * @param listener the existing listener to remove for the given TV input.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
- */
- public void unregisterListener(String inputId, final TvInputListener listener) {
- if (inputId == null) {
- throw new IllegalArgumentException("id cannot be null");
- }
- if (listener == null) {
- throw new IllegalArgumentException("listener cannot be null");
- }
- synchronized (mTvInputListenerRecordsMap) {
- List<TvInputListenerRecord> records = mTvInputListenerRecordsMap.get(inputId);
- if (records == null) {
- Log.e(TAG, "No listener found for " + inputId);
- return;
- }
- for (Iterator<TvInputListenerRecord> it = records.iterator(); it.hasNext();) {
- TvInputListenerRecord record = it.next();
- if (record.getListener() == listener) {
- it.remove();
- }
- }
- if (records.isEmpty()) {
- try {
- mService.unregisterCallback(mClient, inputId, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- } finally {
- mTvInputListenerRecordsMap.remove(inputId);
- }
- }
- }
- }
-
- /**
- * Creates a {@link Session} for a given TV input.
- * <p>
- * The number of sessions that can be created at the same time is limited by the capability of
- * the given TV input.
- * </p>
- *
- * @param inputId the id of the TV input.
- * @param callback a callback used to receive the created session.
- * @param handler a {@link Handler} that the session creation will be delivered to.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
- */
- public void createSession(String inputId, final SessionCallback callback,
- Handler handler) {
- if (inputId == null) {
- throw new IllegalArgumentException("id cannot be null");
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback cannot be null");
- }
- if (handler == null) {
- throw new IllegalArgumentException("handler cannot be null");
- }
- SessionCallbackRecord record = new SessionCallbackRecord(callback, handler);
- synchronized (mSessionCallbackRecordMap) {
- int seq = mNextSeq++;
- mSessionCallbackRecordMap.put(seq, record);
- try {
- mService.createSession(mClient, inputId, seq, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- /** The Session provides the per-session functionality of TV inputs. */
- public static final class Session {
- static final int DISPATCH_IN_PROGRESS = -1;
- static final int DISPATCH_NOT_HANDLED = 0;
- static final int DISPATCH_HANDLED = 1;
-
- private static final long INPUT_SESSION_NOT_RESPONDING_TIMEOUT = 2500;
-
- private final ITvInputManager mService;
- private final int mUserId;
- private final int mSeq;
-
- // For scheduling input event handling on the main thread. This also serves as a lock to
- // protect pending input events and the input channel.
- private final InputEventHandler mHandler = new InputEventHandler(Looper.getMainLooper());
-
- private final Pool<PendingEvent> mPendingEventPool = new SimplePool<PendingEvent>(20);
- private final SparseArray<PendingEvent> mPendingEvents = new SparseArray<PendingEvent>(20);
- private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap;
-
- private IBinder mToken;
- private TvInputEventSender mSender;
- private InputChannel mChannel;
-
- /** @hide */
- private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId,
- int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) {
- mToken = token;
- mChannel = channel;
- mService = service;
- mUserId = userId;
- mSeq = seq;
- mSessionCallbackRecordMap = sessionCallbackRecordMap;
- }
-
- /**
- * Releases this session.
- *
- * @throws IllegalStateException if the session has been already released.
- */
- public void release() {
- if (mToken == null) {
- throw new IllegalStateException("the session has been already released");
- }
- try {
- mService.releaseSession(mToken, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
-
- releaseInternal();
- }
-
- /**
- * Sets the {@link android.view.Surface} for this session.
- *
- * @param surface A {@link android.view.Surface} used to render video.
- * @throws IllegalStateException if the session has been already released.
- * @hide
- */
- public void setSurface(Surface surface) {
- if (mToken == null) {
- throw new IllegalStateException("the session has been already released");
- }
- // surface can be null.
- try {
- mService.setSurface(mToken, surface, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Sets the relative volume of this session to handle a change of audio focus.
- *
- * @param volume A volume value between 0.0f to 1.0f.
- * @throws IllegalArgumentException if the volume value is out of range.
- * @throws IllegalStateException if the session has been already released.
- */
- public void setVolume(float volume) {
- if (mToken == null) {
- throw new IllegalStateException("the session has been already released");
- }
- try {
- if (volume < 0.0f || volume > 1.0f) {
- throw new IllegalArgumentException("volume should be between 0.0f and 1.0f");
- }
- mService.setVolume(mToken, volume, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Tunes to a given channel.
- *
- * @param channelUri The URI of a channel.
- * @throws IllegalArgumentException if the argument is {@code null}.
- * @throws IllegalStateException if the session has been already released.
- */
- public void tune(Uri channelUri) {
- if (channelUri == null) {
- throw new IllegalArgumentException("channelUri cannot be null");
- }
- if (mToken == null) {
- throw new IllegalStateException("the session has been already released");
- }
- try {
- mService.tune(mToken, channelUri, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Creates an overlay view. Once the overlay view is created, {@link #relayoutOverlayView}
- * should be called whenever the layout of its containing view is changed.
- * {@link #removeOverlayView()} should be called to remove the overlay view.
- * Since a session can have only one overlay view, this method should be called only once
- * or it can be called again after calling {@link #removeOverlayView()}.
- *
- * @param view A view playing TV.
- * @param frame A position of the overlay view.
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
- * @throws IllegalStateException if {@code view} is not attached to a window or
- * if the session has been already released.
- */
- void createOverlayView(View view, Rect frame) {
- if (view == null) {
- throw new IllegalArgumentException("view cannot be null");
- }
- if (frame == null) {
- throw new IllegalArgumentException("frame cannot be null");
- }
- if (view.getWindowToken() == null) {
- throw new IllegalStateException("view must be attached to a window");
- }
- if (mToken == null) {
- throw new IllegalStateException("the session has been already released");
- }
- try {
- mService.createOverlayView(mToken, view.getWindowToken(), frame, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Relayouts the current overlay view.
- *
- * @param frame A new position of the overlay view.
- * @throws IllegalArgumentException if the arguments is {@code null}.
- * @throws IllegalStateException if the session has been already released.
- */
- void relayoutOverlayView(Rect frame) {
- if (frame == null) {
- throw new IllegalArgumentException("frame cannot be null");
- }
- if (mToken == null) {
- throw new IllegalStateException("the session has been already released");
- }
- try {
- mService.relayoutOverlayView(mToken, frame, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Removes the current overlay view.
- *
- * @throws IllegalStateException if the session has been already released.
- */
- void removeOverlayView() {
- if (mToken == null) {
- throw new IllegalStateException("the session has been already released");
- }
- try {
- mService.removeOverlayView(mToken, mUserId);
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Dispatches an input event to this session.
- *
- * @param event {@link InputEvent} to dispatch.
- * @param token A token used to identify the input event later in the callback.
- * @param callback A callback used to receive the dispatch result.
- * @param handler {@link Handler} that the dispatch result will be delivered to.
- * @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns
- * {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns
- * {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will
- * be invoked later.
- * @throws IllegalArgumentException if any of the necessary arguments is {@code null}.
- * @hide
- */
- public int dispatchInputEvent(InputEvent event, Object token,
- FinishedInputEventCallback callback, Handler handler) {
- if (event == null) {
- throw new IllegalArgumentException("event cannot be null");
- }
- if (callback != null && handler == null) {
- throw new IllegalArgumentException("handler cannot be null");
- }
- synchronized (mHandler) {
- if (mChannel == null) {
- return DISPATCH_NOT_HANDLED;
- }
- PendingEvent p = obtainPendingEventLocked(event, token, callback, handler);
- if (Looper.myLooper() == Looper.getMainLooper()) {
- // Already running on the main thread so we can send the event immediately.
- return sendInputEventOnMainLooperLocked(p);
- }
-
- // Post the event to the main thread.
- Message msg = mHandler.obtainMessage(InputEventHandler.MSG_SEND_INPUT_EVENT, p);
- msg.setAsynchronous(true);
- mHandler.sendMessage(msg);
- return DISPATCH_IN_PROGRESS;
- }
- }
-
- /**
- * Callback that is invoked when an input event that was dispatched to this session has been
- * finished.
- *
- * @hide
- */
- public interface FinishedInputEventCallback {
- /**
- * Called when the dispatched input event is finished.
- *
- * @param token a token passed to {@link #dispatchInputEvent}.
- * @param handled {@code true} if the dispatched input event was handled properly.
- * {@code false} otherwise.
- */
- public void onFinishedInputEvent(Object token, boolean handled);
- }
-
- // Must be called on the main looper
- private void sendInputEventAndReportResultOnMainLooper(PendingEvent p) {
- synchronized (mHandler) {
- int result = sendInputEventOnMainLooperLocked(p);
- if (result == DISPATCH_IN_PROGRESS) {
- return;
- }
- }
-
- invokeFinishedInputEventCallback(p, false);
- }
-
- private int sendInputEventOnMainLooperLocked(PendingEvent p) {
- if (mChannel != null) {
- if (mSender == null) {
- mSender = new TvInputEventSender(mChannel, mHandler.getLooper());
- }
-
- final InputEvent event = p.mEvent;
- final int seq = event.getSequenceNumber();
- if (mSender.sendInputEvent(seq, event)) {
- mPendingEvents.put(seq, p);
- Message msg = mHandler.obtainMessage(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p);
- msg.setAsynchronous(true);
- mHandler.sendMessageDelayed(msg, INPUT_SESSION_NOT_RESPONDING_TIMEOUT);
- return DISPATCH_IN_PROGRESS;
- }
-
- Log.w(TAG, "Unable to send input event to session: " + mToken + " dropping:"
- + event);
- }
- return DISPATCH_NOT_HANDLED;
- }
-
- void finishedInputEvent(int seq, boolean handled, boolean timeout) {
- final PendingEvent p;
- synchronized (mHandler) {
- int index = mPendingEvents.indexOfKey(seq);
- if (index < 0) {
- return; // spurious, event already finished or timed out
- }
-
- p = mPendingEvents.valueAt(index);
- mPendingEvents.removeAt(index);
-
- if (timeout) {
- Log.w(TAG, "Timeout waiting for seesion to handle input event after "
- + INPUT_SESSION_NOT_RESPONDING_TIMEOUT + " ms: " + mToken);
- } else {
- mHandler.removeMessages(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p);
- }
- }
-
- invokeFinishedInputEventCallback(p, handled);
- }
-
- // Assumes the event has already been removed from the queue.
- void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) {
- p.mHandled = handled;
- if (p.mHandler.getLooper().isCurrentThread()) {
- // Already running on the callback handler thread so we can send the callback
- // immediately.
- p.run();
- } else {
- // Post the event to the callback handler thread.
- // In this case, the callback will be responsible for recycling the event.
- Message msg = Message.obtain(p.mHandler, p);
- msg.setAsynchronous(true);
- msg.sendToTarget();
- }
- }
-
- private void flushPendingEventsLocked() {
- mHandler.removeMessages(InputEventHandler.MSG_FLUSH_INPUT_EVENT);
-
- final int count = mPendingEvents.size();
- for (int i = 0; i < count; i++) {
- int seq = mPendingEvents.keyAt(i);
- Message msg = mHandler.obtainMessage(InputEventHandler.MSG_FLUSH_INPUT_EVENT, seq, 0);
- msg.setAsynchronous(true);
- msg.sendToTarget();
- }
- }
-
- private PendingEvent obtainPendingEventLocked(InputEvent event, Object token,
- FinishedInputEventCallback callback, Handler handler) {
- PendingEvent p = mPendingEventPool.acquire();
- if (p == null) {
- p = new PendingEvent();
- }
- p.mEvent = event;
- p.mToken = token;
- p.mCallback = callback;
- p.mHandler = handler;
- return p;
- }
-
- private void recyclePendingEventLocked(PendingEvent p) {
- p.recycle();
- mPendingEventPool.release(p);
- }
-
- private void releaseInternal() {
- mToken = null;
- synchronized (mHandler) {
- if (mChannel != null) {
- if (mSender != null) {
- flushPendingEventsLocked();
- mSender.dispose();
- mSender = null;
- }
- mChannel.dispose();
- mChannel = null;
- }
- }
- synchronized (mSessionCallbackRecordMap) {
- mSessionCallbackRecordMap.remove(mSeq);
- }
- }
-
- private final class InputEventHandler extends Handler {
- public static final int MSG_SEND_INPUT_EVENT = 1;
- public static final int MSG_TIMEOUT_INPUT_EVENT = 2;
- public static final int MSG_FLUSH_INPUT_EVENT = 3;
-
- InputEventHandler(Looper looper) {
- super(looper, null, true);
- }
-
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_SEND_INPUT_EVENT: {
- sendInputEventAndReportResultOnMainLooper((PendingEvent) msg.obj);
- return;
- }
- case MSG_TIMEOUT_INPUT_EVENT: {
- finishedInputEvent(msg.arg1, false, true);
- return;
- }
- case MSG_FLUSH_INPUT_EVENT: {
- finishedInputEvent(msg.arg1, false, false);
- return;
- }
- }
- }
- }
-
- private final class TvInputEventSender extends InputEventSender {
- public TvInputEventSender(InputChannel inputChannel, Looper looper) {
- super(inputChannel, looper);
- }
-
- @Override
- public void onInputEventFinished(int seq, boolean handled) {
- finishedInputEvent(seq, handled, false);
- }
- }
-
- private final class PendingEvent implements Runnable {
- public InputEvent mEvent;
- public Object mToken;
- public FinishedInputEventCallback mCallback;
- public Handler mHandler;
- public boolean mHandled;
-
- public void recycle() {
- mEvent = null;
- mToken = null;
- mCallback = null;
- mHandler = null;
- mHandled = false;
- }
-
- @Override
- public void run() {
- mCallback.onFinishedInputEvent(mToken, mHandled);
-
- synchronized (mHandler) {
- recyclePendingEventLocked(this);
- }
- }
- }
- }
-}
diff --git a/core/java/android/tv/TvInputService.java b/core/java/android/tv/TvInputService.java
deleted file mode 100644
index 03d24db..0000000
--- a/core/java/android/tv/TvInputService.java
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.tv.TvInputManager.Session;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.InputChannel;
-import android.view.InputDevice;
-import android.view.InputEvent;
-import android.view.InputEventReceiver;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.View;
-import android.view.WindowManager;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.os.SomeArgs;
-
-/**
- * A base class for implementing television input service.
- */
-public abstract class TvInputService extends Service {
- // STOPSHIP: Turn debugging off.
- private static final boolean DEBUG = true;
- private static final String TAG = "TvInputService";
-
- /**
- * This is the interface name that a service implementing a TV input should say that it support
- * -- that is, this is the action it uses for its intent filter. To be supported, the service
- * must also require the {@link android.Manifest.permission#BIND_TV_INPUT} permission so that
- * other applications cannot abuse it.
- */
- public static final String SERVICE_INTERFACE = "android.tv.TvInputService";
-
- private String mId;
- private final Handler mHandler = new ServiceHandler();
- private final RemoteCallbackList<ITvInputServiceCallback> mCallbacks =
- new RemoteCallbackList<ITvInputServiceCallback>();
- private boolean mAvailable;
-
- @Override
- public void onCreate() {
- super.onCreate();
- mId = TvInputInfo.generateInputIdForComponentName(
- new ComponentName(getPackageName(), getClass().getName()));
- }
-
- @Override
- public final IBinder onBind(Intent intent) {
- return new ITvInputService.Stub() {
- @Override
- public void registerCallback(ITvInputServiceCallback cb) {
- if (cb != null) {
- mCallbacks.register(cb);
- // The first time a callback is registered, the service needs to report its
- // availability status so that the system can know its initial value.
- try {
- cb.onAvailabilityChanged(mId, mAvailable);
- } catch (RemoteException e) {
- Log.e(TAG, "error in onAvailabilityChanged", e);
- }
- }
- }
-
- @Override
- public void unregisterCallback(ITvInputServiceCallback cb) {
- if (cb != null) {
- mCallbacks.unregister(cb);
- }
- }
-
- @Override
- public void createSession(InputChannel channel, ITvInputSessionCallback cb) {
- if (channel == null) {
- Log.w(TAG, "Creating session without input channel");
- }
- if (cb == null) {
- return;
- }
- SomeArgs args = SomeArgs.obtain();
- args.arg1 = channel;
- args.arg2 = cb;
- mHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION, args).sendToTarget();
- }
- };
- }
-
- /**
- * Convenience method to notify an availability change of this TV input service.
- *
- * @param available {@code true} if the input service is available to show TV programs.
- */
- public final void setAvailable(boolean available) {
- if (available != mAvailable) {
- mAvailable = available;
- mHandler.obtainMessage(ServiceHandler.DO_BROADCAST_AVAILABILITY_CHANGE, available)
- .sendToTarget();
- }
- }
-
- /**
- * Get the number of callbacks that are registered.
- *
- * @hide
- */
- @VisibleForTesting
- public final int getRegisteredCallbackCount() {
- return mCallbacks.getRegisteredCallbackCount();
- }
-
- /**
- * Returns a concrete implementation of {@link TvInputSessionImpl}.
- * <p>
- * May return {@code null} if this TV input service fails to create a session for some reason.
- * </p>
- */
- public abstract TvInputSessionImpl onCreateSession();
-
- /**
- * Base class for derived classes to implement to provide {@link TvInputManager.Session}.
- */
- public abstract class TvInputSessionImpl implements KeyEvent.Callback {
- private final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
- private final WindowManager mWindowManager;
- private WindowManager.LayoutParams mWindowParams;
- private Surface mSurface;
- private View mOverlayView;
- private boolean mOverlayViewEnabled;
- private IBinder mWindowToken;
- private Rect mOverlayFrame;
- private ITvInputSessionCallback mSessionCallback;
-
- public TvInputSessionImpl() {
- mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
- }
-
- /**
- * Enables or disables the overlay view. By default, the overlay view is disabled. Must be
- * called explicitly after the session is created to enable the overlay view.
- *
- * @param enable {@code true} if you want to enable the overlay view. {@code false}
- * otherwise.
- */
- public void setOverlayViewEnabled(final boolean enable) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (enable == mOverlayViewEnabled) {
- return;
- }
- mOverlayViewEnabled = enable;
- if (enable) {
- if (mWindowToken != null) {
- createOverlayView(mWindowToken, mOverlayFrame);
- }
- } else {
- removeOverlayView(false);
- }
- }
- });
- }
-
- /**
- * Dispatches an event to the application using this session.
- *
- * @param eventType The type of the event.
- * @param eventArgs Optional arguments of the event.
- * @hide
- */
- public void dispatchSessionEvent(final String eventType, final Bundle eventArgs) {
- if (eventType == null) {
- throw new IllegalArgumentException("eventType should not be null.");
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- try {
- if (DEBUG) Log.d(TAG, "dispatchSessionEvent(" + eventType + ")");
- mSessionCallback.onSessionEvent(eventType, eventArgs);
- } catch (RemoteException e) {
- Log.w(TAG, "error in sending event (event=" + eventType + ")");
- }
- }
- });
- }
-
- /**
- * Sends the change on the size of the video. This is expected to be called at the
- * beginning of the playback and later when the size has been changed.
- *
- * @param width The width of the video.
- * @param height The height of the video.
- * @hide
- */
- public void dispatchVideoSizeChanged(final int width, final int height) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- try {
- if (DEBUG) Log.d(TAG, "dispatchVideoSizeChanged");
- mSessionCallback.onVideoSizeChanged(width, height);
- } catch (RemoteException e) {
- Log.w(TAG, "error in dispatchVideoSizeChanged");
- }
- }
- });
- }
-
- /**
- * Called when the session is released.
- */
- public abstract void onRelease();
-
- /**
- * Sets the {@link Surface} for the current input session on which the TV input renders
- * video.
- *
- * @param surface {@link Surface} an application passes to this TV input session.
- * @return {@code true} if the surface was set, {@code false} otherwise.
- */
- public abstract boolean onSetSurface(Surface surface);
-
- /**
- * Sets the relative volume of the current TV input session to handle the change of audio
- * focus by setting.
- *
- * @param volume Volume scale from 0.0 to 1.0.
- */
- public abstract void onSetVolume(float volume);
-
- /**
- * Tunes to a given channel.
- *
- * @param channelUri The URI of the channel.
- * @return {@code true} the tuning was successful, {@code false} otherwise.
- */
- public abstract boolean onTune(Uri channelUri);
-
- /**
- * Called when an application requests to create an overlay view. Each session
- * implementation can override this method and return its own view.
- *
- * @return a view attached to the overlay window
- */
- public View onCreateOverlayView() {
- return null;
- }
-
- /**
- * Default implementation of {@link android.view.KeyEvent.Callback#onKeyDown(int, KeyEvent)
- * KeyEvent.Callback.onKeyDown()}: always returns false (doesn't handle the event).
- * <p>
- * Override this to intercept key down events before they are processed by the application.
- * If you return true, the application will not process the event itself. If you return
- * false, the normal application processing will occur as if the TV input had not seen the
- * event at all.
- *
- * @param keyCode The value in event.getKeyCode().
- * @param event Description of the key event.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- return false;
- }
-
- /**
- * Default implementation of
- * {@link android.view.KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
- * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle the event).
- * <p>
- * Override this to intercept key long press events before they are processed by the
- * application. If you return true, the application will not process the event itself. If
- * you return false, the normal application processing will occur as if the TV input had not
- * seen the event at all.
- *
- * @param keyCode The value in event.getKeyCode().
- * @param event Description of the key event.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- */
- @Override
- public boolean onKeyLongPress(int keyCode, KeyEvent event) {
- return false;
- }
-
- /**
- * Default implementation of
- * {@link android.view.KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
- * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle the event).
- * <p>
- * Override this to intercept special key multiple events before they are processed by the
- * application. If you return true, the application will not itself process the event. If
- * you return false, the normal application processing will occur as if the TV input had not
- * seen the event at all.
- *
- * @param keyCode The value in event.getKeyCode().
- * @param count The number of times the action was made.
- * @param event Description of the key event.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- */
- @Override
- public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
- return false;
- }
-
- /**
- * Default implementation of {@link android.view.KeyEvent.Callback#onKeyUp(int, KeyEvent)
- * KeyEvent.Callback.onKeyUp()}: always returns false (doesn't handle the event).
- * <p>
- * Override this to intercept key up events before they are processed by the application. If
- * you return true, the application will not itself process the event. If you return false,
- * the normal application processing will occur as if the TV input had not seen the event at
- * all.
- *
- * @param keyCode The value in event.getKeyCode().
- * @param event Description of the key event.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- */
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- return false;
- }
-
- /**
- * Implement this method to handle touch screen motion events on the current input session.
- *
- * @param event The motion event being received.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- * @see View#onTouchEvent
- */
- public boolean onTouchEvent(MotionEvent event) {
- return false;
- }
-
- /**
- * Implement this method to handle trackball events on the current input session.
- *
- * @param event The motion event being received.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- * @see View#onTrackballEvent
- */
- public boolean onTrackballEvent(MotionEvent event) {
- return false;
- }
-
- /**
- * Implement this method to handle generic motion events on the current input session.
- *
- * @param event The motion event being received.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- * @see View#onGenericMotionEvent
- */
- public boolean onGenericMotionEvent(MotionEvent event) {
- return false;
- }
-
- /**
- * This method is called when the application would like to stop using the current input
- * session.
- */
- void release() {
- onRelease();
- if (mSurface != null) {
- mSurface.release();
- mSurface = null;
- }
- removeOverlayView(true);
- }
-
- /**
- * Calls {@link #onSetSurface}.
- */
- void setSurface(Surface surface) {
- onSetSurface(surface);
- if (mSurface != null) {
- mSurface.release();
- }
- mSurface = surface;
- // TODO: Handle failure.
- }
-
- /**
- * Calls {@link #onSetVolume}.
- */
- void setVolume(float volume) {
- onSetVolume(volume);
- }
-
- /**
- * Calls {@link #onTune}.
- */
- void tune(Uri channelUri) {
- onTune(channelUri);
- // TODO: Handle failure.
- }
-
- /**
- * Creates an overlay view. This calls {@link #onCreateOverlayView} to get a view to attach
- * to the overlay window.
- *
- * @param windowToken A window token of an application.
- * @param frame A position of the overlay view.
- */
- void createOverlayView(IBinder windowToken, Rect frame) {
- if (mOverlayView != null) {
- mWindowManager.removeView(mOverlayView);
- mOverlayView = null;
- }
- if (DEBUG) Log.d(TAG, "create overlay view(" + frame + ")");
- mWindowToken = windowToken;
- mOverlayFrame = frame;
- if (!mOverlayViewEnabled) {
- return;
- }
- mOverlayView = onCreateOverlayView();
- if (mOverlayView == null) {
- return;
- }
- // TvView's window type is TYPE_APPLICATION_MEDIA and we want to create
- // an overlay window above the media window but below the application window.
- int type = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
- // We make the overlay view non-focusable and non-touchable so that
- // the application that owns the window token can decide whether to consume or
- // dispatch the input events.
- int flag = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
- mWindowParams = new WindowManager.LayoutParams(
- frame.right - frame.left, frame.bottom - frame.top,
- frame.left, frame.top, type, flag, PixelFormat.TRANSPARENT);
- mWindowParams.privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
- mWindowParams.gravity = Gravity.START | Gravity.TOP;
- mWindowParams.token = windowToken;
- mWindowManager.addView(mOverlayView, mWindowParams);
- }
-
- /**
- * Relayouts the current overlay view.
- *
- * @param frame A new position of the overlay view.
- */
- void relayoutOverlayView(Rect frame) {
- if (DEBUG) Log.d(TAG, "relayoutOverlayView(" + frame + ")");
- mOverlayFrame = frame;
- if (!mOverlayViewEnabled || mOverlayView == null) {
- return;
- }
- mWindowParams.x = frame.left;
- mWindowParams.y = frame.top;
- mWindowParams.width = frame.right - frame.left;
- mWindowParams.height = frame.bottom - frame.top;
- mWindowManager.updateViewLayout(mOverlayView, mWindowParams);
- }
-
- /**
- * Removes the current overlay view.
- */
- void removeOverlayView(boolean clearWindowToken) {
- if (DEBUG) Log.d(TAG, "removeOverlayView(" + mOverlayView + ")");
- if (clearWindowToken) {
- mWindowToken = null;
- mOverlayFrame = null;
- }
- if (mOverlayView != null) {
- mWindowManager.removeView(mOverlayView);
- mOverlayView = null;
- mWindowParams = null;
- }
- }
-
- /**
- * Takes care of dispatching incoming input events and tells whether the event was handled.
- */
- int dispatchInputEvent(InputEvent event, InputEventReceiver receiver) {
- if (DEBUG) Log.d(TAG, "dispatchInputEvent(" + event + ")");
- if (event instanceof KeyEvent) {
- if (((KeyEvent) event).dispatch(this, mDispatcherState, this)) {
- return Session.DISPATCH_HANDLED;
- }
- } else if (event instanceof MotionEvent) {
- MotionEvent motionEvent = (MotionEvent) event;
- final int source = motionEvent.getSource();
- if (motionEvent.isTouchEvent()) {
- if (onTouchEvent(motionEvent)) {
- return Session.DISPATCH_HANDLED;
- }
- } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
- if (onTrackballEvent(motionEvent)) {
- return Session.DISPATCH_HANDLED;
- }
- } else {
- if (onGenericMotionEvent(motionEvent)) {
- return Session.DISPATCH_HANDLED;
- }
- }
- }
- if (mOverlayView == null || !mOverlayView.isAttachedToWindow()) {
- return Session.DISPATCH_NOT_HANDLED;
- }
- if (!mOverlayView.hasWindowFocus()) {
- mOverlayView.getViewRootImpl().windowFocusChanged(true, true);
- }
- mOverlayView.getViewRootImpl().dispatchInputEvent(event, receiver);
- return Session.DISPATCH_IN_PROGRESS;
- }
-
- private void setSessionCallback(ITvInputSessionCallback callback) {
- mSessionCallback = callback;
- }
- }
-
- private final class ServiceHandler extends Handler {
- private static final int DO_CREATE_SESSION = 1;
- private static final int DO_BROADCAST_AVAILABILITY_CHANGE = 2;
-
- @Override
- public final void handleMessage(Message msg) {
- switch (msg.what) {
- case DO_CREATE_SESSION: {
- SomeArgs args = (SomeArgs) msg.obj;
- InputChannel channel = (InputChannel) args.arg1;
- ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
- try {
- TvInputSessionImpl sessionImpl = onCreateSession();
- if (sessionImpl == null) {
- // Failed to create a session.
- cb.onSessionCreated(null);
- } else {
- sessionImpl.setSessionCallback(cb);
- ITvInputSession stub = new ITvInputSessionWrapper(TvInputService.this,
- sessionImpl, channel);
- cb.onSessionCreated(stub);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "error in onSessionCreated");
- }
- args.recycle();
- return;
- }
- case DO_BROADCAST_AVAILABILITY_CHANGE: {
- boolean isAvailable = (Boolean) msg.obj;
- int n = mCallbacks.beginBroadcast();
- try {
- for (int i = 0; i < n; i++) {
- mCallbacks.getBroadcastItem(i).onAvailabilityChanged(mId, isAvailable);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Unexpected exception", e);
- } finally {
- mCallbacks.finishBroadcast();
- }
- return;
- }
- default: {
- Log.w(TAG, "Unhandled message code: " + msg.what);
- return;
- }
- }
- }
- }
-}
diff --git a/core/java/android/tv/TvStreamConfig.aidl b/core/java/android/tv/TvStreamConfig.aidl
deleted file mode 100644
index 4d0add4..0000000
--- a/core/java/android/tv/TvStreamConfig.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- *
- * Copyright 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 android.tv;
-
-parcelable TvStreamConfig; \ No newline at end of file
diff --git a/core/java/android/tv/TvStreamConfig.java b/core/java/android/tv/TvStreamConfig.java
deleted file mode 100644
index 03e63b1..0000000
--- a/core/java/android/tv/TvStreamConfig.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-/**
- * @hide
- */
-public class TvStreamConfig implements Parcelable {
- static final String TAG = TvStreamConfig.class.getSimpleName();
-
- public final static int STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE = 1;
- public final static int STREAM_TYPE_BUFFER_PRODUCER = 2;
-
- private int mStreamId;
- private int mType;
- // TODO: Revisit if max widht/height really make sense.
- private int mMaxWidth;
- private int mMaxHeight;
- /**
- * Generations are incremented once framework receives STREAM_CONFIGURATION_CHANGED event from
- * HAL module. Framework should throw away outdated configurations and get new configurations
- * via tv_input_device::get_stream_configurations().
- */
- private int mGeneration;
-
- public static final Parcelable.Creator<TvStreamConfig> CREATOR =
- new Parcelable.Creator<TvStreamConfig>() {
- @Override
- public TvStreamConfig createFromParcel(Parcel source) {
- try {
- return new Builder().
- streamId(source.readInt()).
- type(source.readInt()).
- maxWidth(source.readInt()).
- maxHeight(source.readInt()).
- generation(source.readInt()).build();
- } catch (Exception e) {
- Log.e(TAG, "Exception creating TvStreamConfig from parcel", e);
- return null;
- }
- }
-
- @Override
- public TvStreamConfig[] newArray(int size) {
- return new TvStreamConfig[size];
- }
- };
-
- private TvStreamConfig() {}
-
- public int getStreamId() {
- return mStreamId;
- }
-
- public int getType() {
- return mType;
- }
-
- public int getMaxWidth() {
- return mMaxWidth;
- }
-
- public int getMaxHeight() {
- return mMaxHeight;
- }
-
- public int getGeneration() {
- return mGeneration;
- }
-
- // Parcelable
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mStreamId);
- dest.writeInt(mType);
- dest.writeInt(mMaxWidth);
- dest.writeInt(mMaxHeight);
- dest.writeInt(mGeneration);
- }
-
- /**
- * A helper class for creating a TvStreamConfig object.
- */
- public static final class Builder {
- private Integer mStreamId;
- private Integer mType;
- private Integer mMaxWidth;
- private Integer mMaxHeight;
- private Integer mGeneration;
-
- public Builder() {
- }
-
- public Builder streamId(int streamId) {
- mStreamId = streamId;
- return this;
- }
-
- public Builder type(int type) {
- mType = type;
- return this;
- }
-
- public Builder maxWidth(int maxWidth) {
- mMaxWidth = maxWidth;
- return this;
- }
-
- public Builder maxHeight(int maxHeight) {
- mMaxHeight = maxHeight;
- return this;
- }
-
- public Builder generation(int generation) {
- mGeneration = generation;
- return this;
- }
-
- public TvStreamConfig build() {
- if (mStreamId == null || mType == null || mMaxWidth == null || mMaxHeight == null
- || mGeneration == null) {
- throw new UnsupportedOperationException();
- }
-
- TvStreamConfig config = new TvStreamConfig();
- config.mStreamId = mStreamId;
- config.mType = mType;
- config.mMaxWidth = mMaxWidth;
- config.mMaxHeight = mMaxHeight;
- config.mGeneration = mGeneration;
- return config;
- }
- }
-} \ No newline at end of file
diff --git a/core/java/android/tv/TvView.java b/core/java/android/tv/TvView.java
deleted file mode 100644
index 2d31701..0000000
--- a/core/java/android/tv/TvView.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * 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 android.tv;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.os.Handler;
-import android.text.TextUtils;
-import android.tv.TvInputManager.Session;
-import android.tv.TvInputManager.Session.FinishedInputEventCallback;
-import android.tv.TvInputManager.SessionCallback;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.InputEvent;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.ViewRootImpl;
-
-/**
- * View playing TV
- */
-public class TvView extends SurfaceView {
- // STOPSHIP: Turn debugging off.
- private static final boolean DEBUG = true;
- private static final String TAG = "TvView";
-
- private final Handler mHandler = new Handler();
- private TvInputManager.Session mSession;
- private Surface mSurface;
- private boolean mOverlayViewCreated;
- private Rect mOverlayViewFrame;
- private final TvInputManager mTvInputManager;
- private SessionCallback mSessionCallback;
- private OnUnhandledInputEventListener mOnUnhandledInputEventListener;
-
- private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- Log.d(TAG, "surfaceChanged(holder=" + holder + ", format=" + format + ", width=" + width
- + ", height=" + height + ")");
- if (holder.getSurface() == mSurface) {
- return;
- }
- mSurface = holder.getSurface();
- setSessionSurface(mSurface);
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- mSurface = holder.getSurface();
- setSessionSurface(mSurface);
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- mSurface = null;
- setSessionSurface(null);
- }
- };
-
- private final FinishedInputEventCallback mFinishedInputEventCallback =
- new FinishedInputEventCallback() {
- @Override
- public void onFinishedInputEvent(Object token, boolean handled) {
- if (DEBUG) {
- Log.d(TAG, "onFinishedInputEvent(token=" + token + ", handled=" + handled + ")");
- }
- if (handled) {
- return;
- }
- // TODO: Re-order unhandled events.
- InputEvent event = (InputEvent) token;
- if (dispatchUnhandledInputEvent(event)) {
- return;
- }
- ViewRootImpl viewRootImpl = getViewRootImpl();
- if (viewRootImpl != null) {
- viewRootImpl.dispatchUnhandledInputEvent(event);
- }
- }
- };
-
- public TvView(Context context) {
- this(context, null, 0);
- }
-
- public TvView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public TvView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- getHolder().addCallback(mSurfaceHolderCallback);
- mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE);
- }
-
- /**
- * Binds a TV input to this view. {@link SessionCallback#onSessionCreated} will be
- * called to send the result of this binding with {@link TvInputManager.Session}.
- * If a TV input is already bound, the input will be unbound from this view and its session
- * will be released.
- *
- * @param inputId the id of TV input which will be bound to this view.
- * @param callback called when TV input is bound. The callback sends
- * {@link TvInputManager.Session}
- * @throws IllegalArgumentException if any of the arguments is {@code null}.
- */
- public void bindTvInput(String inputId, SessionCallback callback) {
- if (TextUtils.isEmpty(inputId)) {
- throw new IllegalArgumentException("inputId cannot be null or an empty string");
- }
- if (callback == null) {
- throw new IllegalArgumentException("callback cannot be null");
- }
- if (mSession != null) {
- release();
- }
- // When bindTvInput is called multiple times before the callback is called,
- // only the callback of the last bindTvInput call will be actually called back.
- // The previous callbacks will be ignored. For the logic, mSessionCallback
- // is newly assigned for every bindTvInput call and compared with
- // MySessionCreateCallback.this.
- mSessionCallback = new MySessionCallback(callback);
- mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
- }
-
- /**
- * Unbinds a TV input currently bound. Its corresponding {@link TvInputManager.Session}
- * is released.
- */
- public void unbindTvInput() {
- if (mSession != null) {
- release();
- }
- mSessionCallback = null;
- }
-
- /**
- * Dispatches an unhandled input event to the next receiver.
- * <p>
- * Except system keys, TvView always consumes input events in the normal flow. This is called
- * asynchronously from where the event is dispatched. It gives the host application a chance to
- * dispatch the unhandled input events.
- *
- * @param event The input event.
- * @return {@code true} if the event was handled by the view, {@code false} otherwise.
- */
- public boolean dispatchUnhandledInputEvent(InputEvent event) {
- if (mOnUnhandledInputEventListener != null) {
- if (mOnUnhandledInputEventListener.onUnhandledInputEvent(event)) {
- return true;
- }
- }
- return onUnhandledInputEvent(event);
- }
-
- /**
- * Called when an unhandled input event was also not handled by the user provided callback. This
- * is the last chance to handle the unhandled input event in the TvView.
- *
- * @param event The input event.
- * @return If you handled the event, return {@code true}. If you want to allow the event to be
- * handled by the next receiver, return {@code false}.
- */
- public boolean onUnhandledInputEvent(InputEvent event) {
- return false;
- }
-
- /**
- * Registers a callback to be invoked when an input event was not handled by the bound TV input.
- *
- * @param listener The callback to invoke when the unhandled input event was received.
- */
- public void setOnUnhandledInputEventListener(OnUnhandledInputEventListener listener) {
- mOnUnhandledInputEventListener = listener;
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- if (super.dispatchKeyEvent(event)) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "dispatchKeyEvent(" + event + ")");
- if (mSession == null) {
- return false;
- }
- InputEvent copiedEvent = event.copy();
- int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
- mHandler);
- return ret != Session.DISPATCH_NOT_HANDLED;
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- if (super.dispatchTouchEvent(event)) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "dispatchTouchEvent(" + event + ")");
- if (mSession == null) {
- return false;
- }
- InputEvent copiedEvent = event.copy();
- int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
- mHandler);
- return ret != Session.DISPATCH_NOT_HANDLED;
- }
-
- @Override
- public boolean dispatchTrackballEvent(MotionEvent event) {
- if (super.dispatchTrackballEvent(event)) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "dispatchTrackballEvent(" + event + ")");
- if (mSession == null) {
- return false;
- }
- InputEvent copiedEvent = event.copy();
- int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
- mHandler);
- return ret != Session.DISPATCH_NOT_HANDLED;
- }
-
- @Override
- public boolean dispatchGenericMotionEvent(MotionEvent event) {
- if (super.dispatchGenericMotionEvent(event)) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "dispatchGenericMotionEvent(" + event + ")");
- if (mSession == null) {
- return false;
- }
- InputEvent copiedEvent = event.copy();
- int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
- mHandler);
- return ret != Session.DISPATCH_NOT_HANDLED;
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- createSessionOverlayView();
- }
-
- @Override
- protected void onDetachedFromWindow() {
- removeSessionOverlayView();
- super.onDetachedFromWindow();
- }
-
- /** @hide */
- @Override
- protected void updateWindow(boolean force, boolean redrawNeeded) {
- super.updateWindow(force, redrawNeeded);
- relayoutSessionOverlayView();
- }
-
- private void release() {
- setSessionSurface(null);
- removeSessionOverlayView();
- mSession.release();
- mSession = null;
- }
-
- private void setSessionSurface(Surface surface) {
- if (mSession == null) {
- return;
- }
- mSession.setSurface(surface);
- }
-
- private void createSessionOverlayView() {
- if (mSession == null || !isAttachedToWindow()
- || mOverlayViewCreated) {
- return;
- }
- mOverlayViewFrame = getViewFrameOnScreen();
- mSession.createOverlayView(this, mOverlayViewFrame);
- mOverlayViewCreated = true;
- }
-
- private void removeSessionOverlayView() {
- if (mSession == null || !mOverlayViewCreated) {
- return;
- }
- mSession.removeOverlayView();
- mOverlayViewCreated = false;
- mOverlayViewFrame = null;
- }
-
- private void relayoutSessionOverlayView() {
- if (mSession == null || !isAttachedToWindow()
- || !mOverlayViewCreated) {
- return;
- }
- Rect viewFrame = getViewFrameOnScreen();
- if (viewFrame.equals(mOverlayViewFrame)) {
- return;
- }
- mSession.relayoutOverlayView(viewFrame);
- mOverlayViewFrame = viewFrame;
- }
-
- private Rect getViewFrameOnScreen() {
- int[] location = new int[2];
- getLocationOnScreen(location);
- return new Rect(location[0], location[1],
- location[0] + getWidth(), location[1] + getHeight());
- }
-
- /**
- * Interface definition for a callback to be invoked when the unhandled input event is received.
- */
- public interface OnUnhandledInputEventListener {
- /**
- * Called when an input event was not handled by the bound TV input.
- * <p>
- * This is called asynchronously from where the event is dispatched. It gives the host
- * application a chance to handle the unhandled input events.
- *
- * @param event The input event.
- * @return If you handled the event, return {@code true}. If you want to allow the event to
- * be handled by the next receiver, return {@code false}.
- */
- boolean onUnhandledInputEvent(InputEvent event);
- }
-
- private class MySessionCallback extends SessionCallback {
- final SessionCallback mExternalCallback;
-
- MySessionCallback(SessionCallback externalCallback) {
- mExternalCallback = externalCallback;
- }
-
- @Override
- public void onSessionCreated(Session session) {
- if (this != mSessionCallback) {
- // This callback is obsolete.
- if (session != null) {
- session.release();
- }
- return;
- }
- mSession = session;
- if (session != null) {
- // mSurface may not be ready yet as soon as starting an application.
- // In the case, we don't send Session.setSurface(null) unnecessarily.
- // setSessionSurface will be called in surfaceCreated.
- if (mSurface != null) {
- setSessionSurface(mSurface);
- }
- createSessionOverlayView();
- }
- if (mExternalCallback != null) {
- mExternalCallback.onSessionCreated(session);
- }
- }
-
- @Override
- public void onSessionReleased(Session session) {
- mSession = null;
- if (mExternalCallback != null) {
- mExternalCallback.onSessionReleased(session);
- }
- }
-
- @Override
- public void onVideoSizeChanged(Session session, int width, int height) {
- if (DEBUG) {
- Log.d(TAG, "onVideoSizeChanged(" + width + ", " + height + ")");
- }
- if (mExternalCallback != null) {
- mExternalCallback.onVideoSizeChanged(session, width, height);
- }
- }
-
- @Override
- public void onSessionEvent(TvInputManager.Session session, String eventType,
- Bundle eventArgs) {
- if (mExternalCallback != null) {
- mExternalCallback.onSessionEvent(session, eventType, eventArgs);
- }
- }
- }
-}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 424d860..5056097 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -75,22 +75,10 @@ class GLES20Canvas extends HardwareCanvas {
// Constructors
///////////////////////////////////////////////////////////////////////////
- /**
- * Creates a canvas to render directly on screen.
- */
- GLES20Canvas(boolean translucent) {
- this(false, translucent);
- }
-
- protected GLES20Canvas(boolean record, boolean translucent) {
- mOpaque = !translucent;
-
- if (record) {
- mRenderer = nCreateDisplayListRenderer();
- } else {
- mRenderer = nCreateRenderer();
- }
-
+ // TODO: Merge with GLES20RecordingCanvas
+ protected GLES20Canvas() {
+ mOpaque = false;
+ mRenderer = nCreateDisplayListRenderer();
setupFinalizer();
}
@@ -102,7 +90,6 @@ class GLES20Canvas extends HardwareCanvas {
}
}
- private static native long nCreateRenderer();
private static native long nCreateDisplayListRenderer();
private static native void nResetDisplayListRenderer(long renderer);
private static native void nDestroyRenderer(long renderer);
@@ -131,36 +118,6 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nSetProperty(String name, String value);
///////////////////////////////////////////////////////////////////////////
- // Hardware layers
- ///////////////////////////////////////////////////////////////////////////
-
- @Override
- void pushLayerUpdate(HardwareLayer layer) {
- nPushLayerUpdate(mRenderer, layer.getLayer());
- }
-
- @Override
- void cancelLayerUpdate(HardwareLayer layer) {
- nCancelLayerUpdate(mRenderer, layer.getLayer());
- }
-
- @Override
- void flushLayerUpdates() {
- nFlushLayerUpdates(mRenderer);
- }
-
- @Override
- void clearLayerUpdates() {
- nClearLayerUpdates(mRenderer);
- }
-
- static native boolean nCopyLayer(long layerId, long bitmap);
- private static native void nClearLayerUpdates(long renderer);
- private static native void nFlushLayerUpdates(long renderer);
- private static native void nPushLayerUpdate(long renderer, long layer);
- private static native void nCancelLayerUpdate(long renderer, long layer);
-
- ///////////////////////////////////////////////////////////////////////////
// Canvas management
///////////////////////////////////////////////////////////////////////////
@@ -234,20 +191,6 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nFinish(long renderer);
- /**
- * Returns the size of the stencil buffer required by the underlying
- * implementation.
- *
- * @return The minimum number of bits the stencil buffer must. Always >= 0.
- *
- * @hide
- */
- public static int getStencilSize() {
- return nGetStencilSize();
- }
-
- private static native int nGetStencilSize();
-
///////////////////////////////////////////////////////////////////////////
// Functor
///////////////////////////////////////////////////////////////////////////
@@ -284,49 +227,6 @@ class GLES20Canvas extends HardwareCanvas {
*/
static final int FLUSH_CACHES_FULL = 2;
- /**
- * Flush caches to reclaim as much memory as possible. The amount of memory
- * to reclaim is indicate by the level parameter.
- *
- * The level can be one of {@link #FLUSH_CACHES_MODERATE} or
- * {@link #FLUSH_CACHES_FULL}.
- *
- * @param level Hint about the amount of memory to reclaim
- */
- static void flushCaches(int level) {
- nFlushCaches(level);
- }
-
- private static native void nFlushCaches(int level);
-
- /**
- * Release all resources associated with the underlying caches. This should
- * only be called after a full flushCaches().
- *
- * @hide
- */
- static void terminateCaches() {
- nTerminateCaches();
- }
-
- private static native void nTerminateCaches();
-
- static boolean initCaches() {
- return nInitCaches();
- }
-
- private static native boolean nInitCaches();
-
- ///////////////////////////////////////////////////////////////////////////
- // Atlas
- ///////////////////////////////////////////////////////////////////////////
-
- static void initAtlas(GraphicBuffer buffer, long[] map) {
- nInitAtlas(buffer, map, map.length);
- }
-
- private static native void nInitAtlas(GraphicBuffer buffer, long[] map, int count);
-
///////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////
@@ -899,12 +799,6 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nDrawPath(long renderer, long path, long paint);
private static native void nDrawRects(long renderer, long region, long paint);
- void drawRects(float[] rects, int count, Paint paint) {
- nDrawRects(mRenderer, rects, count, paint.mNativePaint);
- }
-
- private static native void nDrawRects(long renderer, float[] rects, int count, long paint);
-
@Override
public void drawPicture(Picture picture) {
if (picture.createdFromStream) {
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index a94ec3a..b2961e5 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -36,7 +36,7 @@ class GLES20RecordingCanvas extends GLES20Canvas {
RenderNode mNode;
private GLES20RecordingCanvas() {
- super(true, true);
+ super();
}
static GLES20RecordingCanvas obtain(@NonNull RenderNode node) {
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
deleted file mode 100644
index f1163e2..0000000
--- a/core/java/android/view/GLRenderer.java
+++ /dev/null
@@ -1,1521 +0,0 @@
-/*
- * Copyright (C) 2013 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 android.view;
-
-import static javax.microedition.khronos.egl.EGL10.EGL_ALPHA_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_BAD_NATIVE_WINDOW;
-import static javax.microedition.khronos.egl.EGL10.EGL_BLUE_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_CONFIG_CAVEAT;
-import static javax.microedition.khronos.egl.EGL10.EGL_DEFAULT_DISPLAY;
-import static javax.microedition.khronos.egl.EGL10.EGL_DEPTH_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_DRAW;
-import static javax.microedition.khronos.egl.EGL10.EGL_GREEN_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_HEIGHT;
-import static javax.microedition.khronos.egl.EGL10.EGL_NONE;
-import static javax.microedition.khronos.egl.EGL10.EGL_NO_CONTEXT;
-import static javax.microedition.khronos.egl.EGL10.EGL_NO_DISPLAY;
-import static javax.microedition.khronos.egl.EGL10.EGL_NO_SURFACE;
-import static javax.microedition.khronos.egl.EGL10.EGL_RED_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_RENDERABLE_TYPE;
-import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLES;
-import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLE_BUFFERS;
-import static javax.microedition.khronos.egl.EGL10.EGL_STENCIL_SIZE;
-import static javax.microedition.khronos.egl.EGL10.EGL_SUCCESS;
-import static javax.microedition.khronos.egl.EGL10.EGL_SURFACE_TYPE;
-import static javax.microedition.khronos.egl.EGL10.EGL_WIDTH;
-import static javax.microedition.khronos.egl.EGL10.EGL_WINDOW_BIT;
-
-import android.content.ComponentCallbacks2;
-import android.graphics.Bitmap;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-import android.opengl.EGL14;
-import android.opengl.GLUtils;
-import android.opengl.ManagedEGLContext;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.Trace;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.Surface.OutOfResourcesException;
-
-import com.google.android.gles_jni.EGLImpl;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGL11;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.egl.EGLDisplay;
-import javax.microedition.khronos.egl.EGLSurface;
-import javax.microedition.khronos.opengles.GL;
-
-/**
- * Hardware renderer using OpenGL
- *
- * @hide
- */
-public class GLRenderer extends HardwareRenderer {
- static final int SURFACE_STATE_ERROR = 0;
- static final int SURFACE_STATE_SUCCESS = 1;
- static final int SURFACE_STATE_UPDATED = 2;
-
- static final int FUNCTOR_PROCESS_DELAY = 4;
-
- /**
- * Number of frames to profile.
- */
- private static final int PROFILE_MAX_FRAMES = 128;
-
- /**
- * Number of floats per profiled frame.
- */
- private static final int PROFILE_FRAME_DATA_COUNT = 3;
-
- private static final int PROFILE_DRAW_MARGIN = 0;
- private static final int PROFILE_DRAW_WIDTH = 3;
- private static final int[] PROFILE_DRAW_COLORS = { 0xcf3e66cc, 0xcfdc3912, 0xcfe69800 };
- private static final int PROFILE_DRAW_CURRENT_FRAME_COLOR = 0xcf5faa4d;
- private static final int PROFILE_DRAW_THRESHOLD_COLOR = 0xff5faa4d;
- private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
- private static final int PROFILE_DRAW_DP_PER_MS = 7;
-
- private static final String[] VISUALIZERS = {
- PROFILE_PROPERTY_VISUALIZE_BARS,
- };
-
- private static final String[] OVERDRAW = {
- OVERDRAW_PROPERTY_SHOW,
- };
- private static final int GL_VERSION = 2;
-
- static EGL10 sEgl;
- static EGLDisplay sEglDisplay;
- static EGLConfig sEglConfig;
- static final Object[] sEglLock = new Object[0];
- int mWidth = -1, mHeight = -1;
-
- static final ThreadLocal<ManagedEGLContext> sEglContextStorage
- = new ThreadLocal<ManagedEGLContext>();
-
- EGLContext mEglContext;
- Thread mEglThread;
-
- EGLSurface mEglSurface;
-
- GL mGl;
- HardwareCanvas mCanvas;
-
- String mName;
-
- long mFrameCount;
- Paint mDebugPaint;
-
- static boolean sDirtyRegions;
- static final boolean sDirtyRegionsRequested;
- static {
- String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
- //noinspection PointlessBooleanExpression,ConstantConditions
- sDirtyRegions = "true".equalsIgnoreCase(dirtyProperty);
- sDirtyRegionsRequested = sDirtyRegions;
- }
-
- boolean mDirtyRegionsEnabled;
- boolean mUpdateDirtyRegions;
-
- boolean mProfileEnabled;
- int mProfileVisualizerType = -1;
- float[] mProfileData;
- ReentrantLock mProfileLock;
- int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
-
- GraphDataProvider mDebugDataProvider;
- float[][] mProfileShapes;
- Paint mProfilePaint;
-
- boolean mDebugDirtyRegions;
- int mDebugOverdraw = -1;
-
- final boolean mTranslucent;
-
- private boolean mDestroyed;
-
- private final Rect mRedrawClip = new Rect();
-
- private final int[] mSurfaceSize = new int[2];
-
- private long mDrawDelta = Long.MAX_VALUE;
-
- private GLES20Canvas mGlCanvas;
-
- private DisplayMetrics mDisplayMetrics;
-
- private static EGLSurface sPbuffer;
- private static final Object[] sPbufferLock = new Object[0];
-
- private List<HardwareLayer> mLayerUpdates = new ArrayList<HardwareLayer>();
-
- private static class GLRendererEglContext extends ManagedEGLContext {
- final Handler mHandler = new Handler();
-
- public GLRendererEglContext(EGLContext context) {
- super(context);
- }
-
- @Override
- public void onTerminate(final EGLContext eglContext) {
- // Make sure we do this on the correct thread.
- if (mHandler.getLooper() != Looper.myLooper()) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- onTerminate(eglContext);
- }
- });
- return;
- }
-
- synchronized (sEglLock) {
- if (sEgl == null) return;
-
- if (EGLImpl.getInitCount(sEglDisplay) == 1) {
- usePbufferSurface(eglContext);
- GLES20Canvas.terminateCaches();
-
- sEgl.eglDestroyContext(sEglDisplay, eglContext);
- sEglContextStorage.set(null);
- sEglContextStorage.remove();
-
- sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
- sEgl.eglReleaseThread();
- sEgl.eglTerminate(sEglDisplay);
-
- sEgl = null;
- sEglDisplay = null;
- sEglConfig = null;
- sPbuffer = null;
- }
- }
- }
- }
-
- HardwareCanvas createCanvas() {
- return mGlCanvas = new GLES20Canvas(mTranslucent);
- }
-
- ManagedEGLContext createManagedContext(EGLContext eglContext) {
- return new GLRendererEglContext(mEglContext);
- }
-
- int[] getConfig(boolean dirtyRegions) {
- //noinspection PointlessBooleanExpression,ConstantConditions
- final int stencilSize = GLES20Canvas.getStencilSize();
- final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
-
- return new int[] {
- EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_DEPTH_SIZE, 0,
- EGL_CONFIG_CAVEAT, EGL_NONE,
- EGL_STENCIL_SIZE, stencilSize,
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
- EGL_NONE
- };
- }
-
- void initCaches() {
- if (GLES20Canvas.initCaches()) {
- // Caches were (re)initialized, rebind atlas
- initAtlas();
- }
- }
-
- void initAtlas() {
- IBinder binder = ServiceManager.getService("assetatlas");
- if (binder == null) return;
-
- IAssetAtlas atlas = IAssetAtlas.Stub.asInterface(binder);
- try {
- if (atlas.isCompatible(android.os.Process.myPpid())) {
- GraphicBuffer buffer = atlas.getBuffer();
- if (buffer != null) {
- long[] map = atlas.getMap();
- if (map != null) {
- GLES20Canvas.initAtlas(buffer, map);
- }
- // If IAssetAtlas is not the same class as the IBinder
- // we are using a remote service and we can safely
- // destroy the graphic buffer
- if (atlas.getClass() != binder.getClass()) {
- buffer.destroy();
- }
- }
- }
- } catch (RemoteException e) {
- Log.w(LOG_TAG, "Could not acquire atlas", e);
- }
- }
-
- boolean canDraw() {
- return mGl != null && mCanvas != null && mGlCanvas != null;
- }
-
- int onPreDraw(Rect dirty) {
- return mGlCanvas.onPreDraw(dirty);
- }
-
- void onPostDraw() {
- mGlCanvas.onPostDraw();
- }
-
- void drawProfileData(View.AttachInfo attachInfo) {
- if (mDebugDataProvider != null) {
- final GraphDataProvider provider = mDebugDataProvider;
- initProfileDrawData(attachInfo, provider);
-
- final int height = provider.getVerticalUnitSize();
- final int margin = provider.getHorizontaUnitMargin();
- final int width = provider.getHorizontalUnitSize();
-
- int x = 0;
- int count = 0;
- int current = 0;
-
- final float[] data = provider.getData();
- final int elementCount = provider.getElementCount();
- final int graphType = provider.getGraphType();
-
- int totalCount = provider.getFrameCount() * elementCount;
- if (graphType == GraphDataProvider.GRAPH_TYPE_LINES) {
- totalCount -= elementCount;
- }
-
- for (int i = 0; i < totalCount; i += elementCount) {
- if (data[i] < 0.0f) break;
-
- int index = count * 4;
- if (i == provider.getCurrentFrame() * elementCount) current = index;
-
- x += margin;
- int x2 = x + width;
-
- int y2 = mHeight;
- int y1 = (int) (y2 - data[i] * height);
-
- switch (graphType) {
- case GraphDataProvider.GRAPH_TYPE_BARS: {
- for (int j = 0; j < elementCount; j++) {
- //noinspection MismatchedReadAndWriteOfArray
- final float[] r = mProfileShapes[j];
- r[index] = x;
- r[index + 1] = y1;
- r[index + 2] = x2;
- r[index + 3] = y2;
-
- y2 = y1;
- if (j < elementCount - 1) {
- y1 = (int) (y2 - data[i + j + 1] * height);
- }
- }
- } break;
- case GraphDataProvider.GRAPH_TYPE_LINES: {
- for (int j = 0; j < elementCount; j++) {
- //noinspection MismatchedReadAndWriteOfArray
- final float[] r = mProfileShapes[j];
- r[index] = (x + x2) * 0.5f;
- r[index + 1] = index == 0 ? y1 : r[index - 1];
- r[index + 2] = r[index] + width;
- r[index + 3] = y1;
-
- y2 = y1;
- if (j < elementCount - 1) {
- y1 = (int) (y2 - data[i + j + 1] * height);
- }
- }
- } break;
- }
-
-
- x += width;
- count++;
- }
-
- x += margin;
-
- drawGraph(graphType, count);
- drawCurrentFrame(graphType, current);
- drawThreshold(x, height);
- }
- }
-
- private void drawGraph(int graphType, int count) {
- for (int i = 0; i < mProfileShapes.length; i++) {
- mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
- switch (graphType) {
- case GraphDataProvider.GRAPH_TYPE_BARS:
- mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
- break;
- case GraphDataProvider.GRAPH_TYPE_LINES:
- mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
- break;
- }
- }
- }
-
- private void drawCurrentFrame(int graphType, int index) {
- if (index >= 0) {
- mDebugDataProvider.setupCurrentFramePaint(mProfilePaint);
- switch (graphType) {
- case GraphDataProvider.GRAPH_TYPE_BARS:
- mGlCanvas.drawRect(mProfileShapes[2][index], mProfileShapes[2][index + 1],
- mProfileShapes[2][index + 2], mProfileShapes[0][index + 3],
- mProfilePaint);
- break;
- case GraphDataProvider.GRAPH_TYPE_LINES:
- mGlCanvas.drawLine(mProfileShapes[2][index], mProfileShapes[2][index + 1],
- mProfileShapes[2][index], mHeight, mProfilePaint);
- break;
- }
- }
- }
-
- private void drawThreshold(int x, int height) {
- float threshold = mDebugDataProvider.getThreshold();
- if (threshold > 0.0f) {
- mDebugDataProvider.setupThresholdPaint(mProfilePaint);
- int y = (int) (mHeight - threshold * height);
- mGlCanvas.drawLine(0.0f, y, x, y, mProfilePaint);
- }
- }
-
- private void initProfileDrawData(View.AttachInfo attachInfo, GraphDataProvider provider) {
- if (mProfileShapes == null) {
- final int elementCount = provider.getElementCount();
- final int frameCount = provider.getFrameCount();
-
- mProfileShapes = new float[elementCount][];
- for (int i = 0; i < elementCount; i++) {
- mProfileShapes[i] = new float[frameCount * 4];
- }
-
- mProfilePaint = new Paint();
- }
-
- mProfilePaint.reset();
- if (provider.getGraphType() == GraphDataProvider.GRAPH_TYPE_LINES) {
- mProfilePaint.setAntiAlias(true);
- }
-
- if (mDisplayMetrics == null) {
- mDisplayMetrics = new DisplayMetrics();
- }
-
- attachInfo.mDisplay.getMetrics(mDisplayMetrics);
- provider.prepare(mDisplayMetrics);
- }
-
- @Override
- void destroy(boolean full) {
- try {
- if (full && mCanvas != null) {
- mCanvas = null;
- }
-
- if (!isEnabled() || mDestroyed) {
- setEnabled(false);
- return;
- }
-
- destroySurface();
- setEnabled(false);
-
- mDestroyed = true;
- mGl = null;
- } finally {
- if (full && mGlCanvas != null) {
- mGlCanvas = null;
- }
- }
- }
-
- @Override
- void pushLayerUpdate(HardwareLayer layer) {
- mLayerUpdates.add(layer);
- }
-
- @Override
- void flushLayerUpdates() {
- if (validate()) {
- flushLayerChanges();
- mGlCanvas.flushLayerUpdates();
- }
- }
-
- @Override
- HardwareLayer createTextureLayer() {
- validate();
- return HardwareLayer.createTextureLayer(this);
- }
-
- @Override
- public HardwareLayer createDisplayListLayer(int width, int height) {
- validate();
- return HardwareLayer.createDisplayListLayer(this, width, height);
- }
-
- boolean hasContext() {
- return sEgl != null && mEglContext != null
- && mEglContext.equals(sEgl.eglGetCurrentContext());
- }
-
- @Override
- void onLayerDestroyed(HardwareLayer layer) {
- if (mGlCanvas != null) {
- mGlCanvas.cancelLayerUpdate(layer);
- }
- mLayerUpdates.remove(layer);
- }
-
- @Override
- public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
- return layer.createSurfaceTexture();
- }
-
- @Override
- boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap) {
- if (!validate()) {
- throw new IllegalStateException("Could not acquire hardware rendering context");
- }
- layer.flushChanges();
- return GLES20Canvas.nCopyLayer(layer.getLayer(), bitmap.mNativeBitmap);
- }
-
- @Override
- boolean safelyRun(Runnable action) {
- boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
-
- if (needsContext) {
- GLRendererEglContext managedContext =
- (GLRendererEglContext) sEglContextStorage.get();
- if (managedContext == null) return false;
- usePbufferSurface(managedContext.getContext());
- }
-
- try {
- action.run();
- } finally {
- if (needsContext) {
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- }
-
- return true;
- }
-
- @Override
- void invokeFunctor(long functor, boolean waitForCompletion) {
- boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
- boolean hasContext = !needsContext;
-
- if (needsContext) {
- GLRendererEglContext managedContext =
- (GLRendererEglContext) sEglContextStorage.get();
- if (managedContext != null) {
- usePbufferSurface(managedContext.getContext());
- hasContext = true;
- }
- }
-
- try {
- nInvokeFunctor(functor, hasContext);
- } finally {
- if (needsContext) {
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- }
- }
-
- private static native void nInvokeFunctor(long functor, boolean hasContext);
-
- @Override
- void destroyHardwareResources(final View view) {
- if (view != null) {
- safelyRun(new Runnable() {
- @Override
- public void run() {
- if (mCanvas != null) {
- mCanvas.clearLayerUpdates();
- }
- destroyResources(view);
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
- }
- });
- }
- }
-
- private static void destroyResources(View view) {
- view.destroyHardwareResources();
-
- if (view instanceof ViewGroup) {
- ViewGroup group = (ViewGroup) view;
-
- int count = group.getChildCount();
- for (int i = 0; i < count; i++) {
- destroyResources(group.getChildAt(i));
- }
- }
- }
-
- static void startTrimMemory(int level) {
- if (sEgl == null || sEglConfig == null) return;
-
- GLRendererEglContext managedContext =
- (GLRendererEglContext) sEglContextStorage.get();
- // We do not have OpenGL objects
- if (managedContext == null) {
- return;
- } else {
- usePbufferSurface(managedContext.getContext());
- }
-
- if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
- } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
- GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
- }
- }
-
- static void endTrimMemory() {
- if (sEgl != null && sEglDisplay != null) {
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- }
-
- private static void usePbufferSurface(EGLContext eglContext) {
- synchronized (sPbufferLock) {
- // Create a temporary 1x1 pbuffer so we have a context
- // to clear our OpenGL objects
- if (sPbuffer == null) {
- sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] {
- EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE
- });
- }
- }
- sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
- }
-
- GLRenderer(boolean translucent) {
- mTranslucent = translucent;
-
- loadSystemProperties();
- }
-
- @Override
- void setOpaque(boolean opaque) {
- // Not supported
- }
-
- @Override
- boolean loadSystemProperties() {
- boolean value;
- boolean changed = false;
-
- String profiling = SystemProperties.get(PROFILE_PROPERTY);
- int graphType = search(VISUALIZERS, profiling);
- value = graphType >= 0;
-
- if (graphType != mProfileVisualizerType) {
- changed = true;
- mProfileVisualizerType = graphType;
-
- mProfileShapes = null;
- mProfilePaint = null;
-
- if (value) {
- mDebugDataProvider = new GraphDataProvider(graphType);
- } else {
- mDebugDataProvider = null;
- }
- }
-
- // If on-screen profiling is not enabled, we need to check whether
- // console profiling only is enabled
- if (!value) {
- value = Boolean.parseBoolean(profiling);
- }
-
- if (value != mProfileEnabled) {
- changed = true;
- mProfileEnabled = value;
-
- if (mProfileEnabled) {
- Log.d(LOG_TAG, "Profiling hardware renderer");
-
- int maxProfileFrames = SystemProperties.getInt(PROFILE_MAXFRAMES_PROPERTY,
- PROFILE_MAX_FRAMES);
- mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT];
- for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
- mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
- }
-
- mProfileLock = new ReentrantLock();
- } else {
- mProfileData = null;
- mProfileLock = null;
- mProfileVisualizerType = -1;
- }
-
- mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
- }
-
- value = SystemProperties.getBoolean(DEBUG_DIRTY_REGIONS_PROPERTY, false);
- if (value != mDebugDirtyRegions) {
- changed = true;
- mDebugDirtyRegions = value;
-
- if (mDebugDirtyRegions) {
- Log.d(LOG_TAG, "Debugging dirty regions");
- }
- }
-
- String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
- int debugOverdraw = search(OVERDRAW, overdraw);
- if (debugOverdraw != mDebugOverdraw) {
- changed = true;
- mDebugOverdraw = debugOverdraw;
- }
-
- if (loadProperties()) {
- changed = true;
- }
-
- return changed;
- }
-
- private static int search(String[] values, String value) {
- for (int i = 0; i < values.length; i++) {
- if (values[i].equals(value)) return i;
- }
- return -1;
- }
-
- @Override
- void dumpGfxInfo(PrintWriter pw, FileDescriptor fd) {
- if (mProfileEnabled) {
- pw.printf("\n\tDraw\tProcess\tExecute\n");
-
- mProfileLock.lock();
- try {
- for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
- if (mProfileData[i] < 0) {
- break;
- }
- pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
- mProfileData[i + 2]);
- mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
- }
- mProfileCurrentFrame = mProfileData.length;
- } finally {
- mProfileLock.unlock();
- }
- }
- }
-
- /**
- * Indicates whether this renderer instance can track and update dirty regions.
- */
- boolean hasDirtyRegions() {
- return mDirtyRegionsEnabled;
- }
-
- /**
- * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
- * is invoked and the requested flag is turned off. The error code is
- * also logged as a warning.
- */
- void checkEglErrors() {
- if (isEnabled()) {
- checkEglErrorsForced();
- }
- }
-
- private void checkEglErrorsForced() {
- int error = sEgl.eglGetError();
- if (error != EGL_SUCCESS) {
- // something bad has happened revert to
- // normal rendering.
- Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
- fallback(error != EGL11.EGL_CONTEXT_LOST);
- }
- }
-
- private void fallback(boolean fallback) {
- destroy(true);
- if (fallback) {
- // we'll try again if it was context lost
- setRequested(false);
- Log.w(LOG_TAG, "Mountain View, we've had a problem here. "
- + "Switching back to software rendering.");
- }
- }
-
- @Override
- boolean initialize(Surface surface) throws OutOfResourcesException {
- if (isRequested() && !isEnabled()) {
- boolean contextCreated = initializeEgl();
- mGl = createEglSurface(surface);
- mDestroyed = false;
-
- if (mGl != null) {
- int err = sEgl.eglGetError();
- if (err != EGL_SUCCESS) {
- destroy(true);
- setRequested(false);
- } else {
- if (mCanvas == null) {
- mCanvas = createCanvas();
- }
- setEnabled(true);
-
- if (contextCreated) {
- initAtlas();
- }
- }
-
- return mCanvas != null;
- }
- }
- return false;
- }
-
- @Override
- void updateSurface(Surface surface) throws OutOfResourcesException {
- if (isRequested() && isEnabled()) {
- createEglSurface(surface);
- }
- }
-
- @Override
- void pauseSurface(Surface surface) {
- // No-op
- }
-
- boolean initializeEgl() {
- synchronized (sEglLock) {
- if (sEgl == null && sEglConfig == null) {
- sEgl = (EGL10) EGLContext.getEGL();
-
- // Get to the default display.
- sEglDisplay = sEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
-
- if (sEglDisplay == EGL_NO_DISPLAY) {
- throw new RuntimeException("eglGetDisplay failed "
- + GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- // We can now initialize EGL for that display
- int[] version = new int[2];
- if (!sEgl.eglInitialize(sEglDisplay, version)) {
- throw new RuntimeException("eglInitialize failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- checkEglErrorsForced();
-
- sEglConfig = loadEglConfig();
- }
- }
-
- ManagedEGLContext managedContext = sEglContextStorage.get();
- mEglContext = managedContext != null ? managedContext.getContext() : null;
- mEglThread = Thread.currentThread();
-
- if (mEglContext == null) {
- mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
- sEglContextStorage.set(createManagedContext(mEglContext));
- return true;
- }
-
- return false;
- }
-
- private EGLConfig loadEglConfig() {
- EGLConfig eglConfig = chooseEglConfig();
- if (eglConfig == null) {
- // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
- if (sDirtyRegions) {
- sDirtyRegions = false;
- eglConfig = chooseEglConfig();
- if (eglConfig == null) {
- throw new RuntimeException("eglConfig not initialized");
- }
- } else {
- throw new RuntimeException("eglConfig not initialized");
- }
- }
- return eglConfig;
- }
-
- private EGLConfig chooseEglConfig() {
- EGLConfig[] configs = new EGLConfig[1];
- int[] configsCount = new int[1];
- int[] configSpec = getConfig(sDirtyRegions);
-
- // Debug
- final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, "");
- if ("all".equalsIgnoreCase(debug)) {
- sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount);
-
- EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]];
- sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs,
- configsCount[0], configsCount);
-
- for (EGLConfig config : debugConfigs) {
- printConfig(config);
- }
- }
-
- if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
- throw new IllegalArgumentException("eglChooseConfig failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- } else if (configsCount[0] > 0) {
- if ("choice".equalsIgnoreCase(debug)) {
- printConfig(configs[0]);
- }
- return configs[0];
- }
-
- return null;
- }
-
- private static void printConfig(EGLConfig config) {
- int[] value = new int[1];
-
- Log.d(LOG_TAG, "EGL configuration " + config + ":");
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value);
- Log.d(LOG_TAG, " RED_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value);
- Log.d(LOG_TAG, " GREEN_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value);
- Log.d(LOG_TAG, " BLUE_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value);
- Log.d(LOG_TAG, " ALPHA_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value);
- Log.d(LOG_TAG, " DEPTH_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
- Log.d(LOG_TAG, " STENCIL_SIZE = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
- Log.d(LOG_TAG, " SAMPLE_BUFFERS = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
- Log.d(LOG_TAG, " SAMPLES = " + value[0]);
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
- Log.d(LOG_TAG, " SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
-
- sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
- Log.d(LOG_TAG, " CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
- }
-
- GL createEglSurface(Surface surface) throws OutOfResourcesException {
- // Check preconditions.
- if (sEgl == null) {
- throw new RuntimeException("egl not initialized");
- }
- if (sEglDisplay == null) {
- throw new RuntimeException("eglDisplay not initialized");
- }
- if (sEglConfig == null) {
- throw new RuntimeException("eglConfig not initialized");
- }
- if (Thread.currentThread() != mEglThread) {
- throw new IllegalStateException("HardwareRenderer cannot be used "
- + "from multiple threads");
- }
-
- // In case we need to destroy an existing surface
- destroySurface();
-
- // Create an EGL surface we can render into.
- if (!createSurface(surface)) {
- return null;
- }
-
- initCaches();
-
- return mEglContext.getGL();
- }
-
- private void enableDirtyRegions() {
- // If mDirtyRegions is set, this means we have an EGL configuration
- // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
- if (sDirtyRegions) {
- if (!(mDirtyRegionsEnabled = preserveBackBuffer())) {
- Log.w(LOG_TAG, "Backbuffer cannot be preserved");
- }
- } else if (sDirtyRegionsRequested) {
- // If mDirtyRegions is not set, our EGL configuration does not
- // have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default
- // swap behavior might be EGL_BUFFER_PRESERVED, which means we
- // want to set mDirtyRegions. We try to do this only if dirty
- // regions were initially requested as part of the device
- // configuration (see RENDER_DIRTY_REGIONS)
- mDirtyRegionsEnabled = isBackBufferPreserved();
- }
- }
-
- EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
- final int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, GL_VERSION, EGL_NONE };
-
- EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT,
- attribs);
- if (context == null || context == EGL_NO_CONTEXT) {
- //noinspection ConstantConditions
- throw new IllegalStateException(
- "Could not create an EGL context. eglCreateContext failed with error: " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- return context;
- }
-
- void destroySurface() {
- if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
- if (mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW))) {
- sEgl.eglMakeCurrent(sEglDisplay,
- EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- }
- sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
- mEglSurface = null;
- }
- }
-
- @Override
- void invalidate(Surface surface) {
- // Cancels any existing buffer to ensure we'll get a buffer
- // of the right size before we call eglSwapBuffers
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
- if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
- sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
- mEglSurface = null;
- setEnabled(false);
- }
-
- if (surface.isValid()) {
- if (!createSurface(surface)) {
- return;
- }
-
- mUpdateDirtyRegions = true;
-
- if (mCanvas != null) {
- setEnabled(true);
- }
- }
- }
-
- private boolean createSurface(Surface surface) {
- mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, surface, null);
-
- if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
- int error = sEgl.eglGetError();
- if (error == EGL_BAD_NATIVE_WINDOW) {
- Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
- return false;
- }
- throw new RuntimeException("createWindowSurface failed "
- + GLUtils.getEGLErrorString(error));
- }
-
- if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
- throw new IllegalStateException("eglMakeCurrent failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- }
-
- enableDirtyRegions();
-
- return true;
- }
-
- boolean validate() {
- return checkRenderContext() != SURFACE_STATE_ERROR;
- }
-
- @Override
- void setup(int width, int height, float lightX, float lightY, float lightZ, float lightRadius) {
- if (validate()) {
- mCanvas.setViewport(width, height);
- mCanvas.initializeLight(lightX, lightY, lightZ, lightRadius);
- mWidth = width;
- mHeight = height;
- }
- }
-
- @Override
- int getWidth() {
- return mWidth;
- }
-
- @Override
- int getHeight() {
- return mHeight;
- }
-
- @Override
- void setName(String name) {
- mName = name;
- }
-
- @Override
- void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
- Rect dirty) {
- if (canDraw()) {
- if (!hasDirtyRegions()) {
- dirty = null;
- }
- attachInfo.mIgnoreDirtyState = true;
- attachInfo.mDrawingTime = SystemClock.uptimeMillis();
-
- view.mPrivateFlags |= View.PFLAG_DRAWN;
-
- // We are already on the correct thread
- final int surfaceState = checkRenderContextUnsafe();
- if (surfaceState != SURFACE_STATE_ERROR) {
- HardwareCanvas canvas = mCanvas;
-
- if (mProfileEnabled) {
- mProfileLock.lock();
- }
-
- dirty = beginFrame(canvas, dirty, surfaceState);
-
- RenderNode displayList = buildDisplayList(view, canvas);
-
- flushLayerChanges();
-
- // buildDisplayList() calls into user code which can cause
- // an eglMakeCurrent to happen with a different surface/context.
- // We must therefore check again here.
- if (checkRenderContextUnsafe() == SURFACE_STATE_ERROR) {
- return;
- }
-
- int saveCount = 0;
- int status = RenderNode.STATUS_DONE;
-
- long start = getSystemTime();
- try {
- status = prepareFrame(dirty);
-
- saveCount = canvas.save();
- callbacks.onHardwarePreDraw(canvas);
-
- if (displayList != null) {
- status |= drawDisplayList(canvas, displayList, status);
- } else {
- // Shouldn't reach here
- view.draw(canvas);
- }
- } catch (Exception e) {
- Log.e(LOG_TAG, "An error has occurred while drawing:", e);
- } finally {
- callbacks.onHardwarePostDraw(canvas);
- canvas.restoreToCount(saveCount);
- view.mRecreateDisplayList = false;
-
- mDrawDelta = getSystemTime() - start;
-
- if (mDrawDelta > 0) {
- mFrameCount++;
-
- debugDirtyRegions(dirty, canvas);
- drawProfileData(attachInfo);
- }
- }
-
- onPostDraw();
-
- swapBuffers(status);
-
- if (mProfileEnabled) {
- mProfileLock.unlock();
- }
-
- attachInfo.mIgnoreDirtyState = false;
- }
- }
- }
-
- private void flushLayerChanges() {
- // Loop through and apply any pending layer changes
- for (int i = 0; i < mLayerUpdates.size(); i++) {
- HardwareLayer layer = mLayerUpdates.get(i);
- layer.flushChanges();
- if (!layer.isValid()) {
- // The layer was removed from mAttachedLayers, rewind i by 1
- // Note that this shouldn't actually happen as View.getHardwareLayer()
- // is already flushing for error checking reasons
- i--;
- } else if (layer.hasDisplayList()) {
- mCanvas.pushLayerUpdate(layer);
- }
- }
- mLayerUpdates.clear();
- }
-
- @Override
- void fence() {
- // Everything is immediate, so this is a no-op
- }
-
- private RenderNode buildDisplayList(View view, HardwareCanvas canvas) {
- view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
- == View.PFLAG_INVALIDATED;
- view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
-
- long buildDisplayListStartTime = startBuildDisplayListProfiling();
- canvas.clearLayerUpdates();
-
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
- RenderNode renderNode = view.getDisplayList();
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-
- endBuildDisplayListProfiling(buildDisplayListStartTime);
-
- return renderNode;
- }
-
- private Rect beginFrame(HardwareCanvas canvas, Rect dirty, int surfaceState) {
- // We had to change the current surface and/or context, redraw everything
- if (surfaceState == SURFACE_STATE_UPDATED) {
- dirty = null;
- beginFrame(null);
- } else {
- int[] size = mSurfaceSize;
- beginFrame(size);
-
- if (size[1] != mHeight || size[0] != mWidth) {
- mWidth = size[0];
- mHeight = size[1];
-
- canvas.setViewport(mWidth, mHeight);
-
- dirty = null;
- }
- }
-
- if (mDebugDataProvider != null) dirty = null;
-
- return dirty;
- }
-
- private long startBuildDisplayListProfiling() {
- if (mProfileEnabled) {
- mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT;
- if (mProfileCurrentFrame >= mProfileData.length) {
- mProfileCurrentFrame = 0;
- }
-
- return System.nanoTime();
- }
- return 0;
- }
-
- private void endBuildDisplayListProfiling(long getDisplayListStartTime) {
- if (mProfileEnabled) {
- long now = System.nanoTime();
- float total = (now - getDisplayListStartTime) * 0.000001f;
- //noinspection PointlessArithmeticExpression
- mProfileData[mProfileCurrentFrame] = total;
- }
- }
-
- private int prepareFrame(Rect dirty) {
- int status;
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame");
- try {
- status = onPreDraw(dirty);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
- return status;
- }
-
- private int drawDisplayList(HardwareCanvas canvas, RenderNode displayList,
- int status) {
-
- long drawDisplayListStartTime = 0;
- if (mProfileEnabled) {
- drawDisplayListStartTime = System.nanoTime();
- }
-
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
- nPrepareTree(displayList.getNativeDisplayList());
- try {
- status |= canvas.drawDisplayList(displayList, mRedrawClip,
- RenderNode.FLAG_CLIP_CHILDREN);
- } finally {
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- }
-
- if (mProfileEnabled) {
- long now = System.nanoTime();
- float total = (now - drawDisplayListStartTime) * 0.000001f;
- mProfileData[mProfileCurrentFrame + 1] = total;
- }
-
- return status;
- }
-
- private void swapBuffers(int status) {
- if ((status & RenderNode.STATUS_DREW) == RenderNode.STATUS_DREW) {
- long eglSwapBuffersStartTime = 0;
- if (mProfileEnabled) {
- eglSwapBuffersStartTime = System.nanoTime();
- }
-
- sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
-
- if (mProfileEnabled) {
- long now = System.nanoTime();
- float total = (now - eglSwapBuffersStartTime) * 0.000001f;
- mProfileData[mProfileCurrentFrame + 2] = total;
- }
-
- checkEglErrors();
- }
- }
-
- private void debugDirtyRegions(Rect dirty, HardwareCanvas canvas) {
- if (mDebugDirtyRegions) {
- if (mDebugPaint == null) {
- mDebugPaint = new Paint();
- mDebugPaint.setColor(0x7fff0000);
- }
-
- if (dirty != null && (mFrameCount & 1) == 0) {
- canvas.drawRect(dirty, mDebugPaint);
- }
- }
- }
-
- /**
- * Ensures the current EGL context and surface are the ones we expect.
- * This method throws an IllegalStateException if invoked from a thread
- * that did not initialize EGL.
- *
- * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
- * {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
- * {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
- *
- * @see #checkRenderContextUnsafe()
- */
- int checkRenderContext() {
- if (mEglThread != Thread.currentThread()) {
- throw new IllegalStateException("Hardware acceleration can only be used with a " +
- "single UI thread.\nOriginal thread: " + mEglThread + "\n" +
- "Current thread: " + Thread.currentThread());
- }
-
- return checkRenderContextUnsafe();
- }
-
- /**
- * Ensures the current EGL context and surface are the ones we expect.
- * This method does not check the current thread.
- *
- * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
- * {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
- * {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
- *
- * @see #checkRenderContext()
- */
- private int checkRenderContextUnsafe() {
- if (!mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL_DRAW)) ||
- !mEglContext.equals(sEgl.eglGetCurrentContext())) {
- if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
- Log.e(LOG_TAG, "eglMakeCurrent failed " +
- GLUtils.getEGLErrorString(sEgl.eglGetError()));
- fallback(true);
- return SURFACE_STATE_ERROR;
- } else {
- if (mUpdateDirtyRegions) {
- enableDirtyRegions();
- mUpdateDirtyRegions = false;
- }
- return SURFACE_STATE_UPDATED;
- }
- }
- return SURFACE_STATE_SUCCESS;
- }
-
- private static int dpToPx(int dp, float density) {
- return (int) (dp * density + 0.5f);
- }
-
- static native boolean loadProperties();
-
- static native void setupShadersDiskCache(String cacheFile);
-
- /**
- * Notifies EGL that the frame is about to be rendered.
- * @param size
- */
- static native void beginFrame(int[] size);
-
- /**
- * Returns the current system time according to the renderer.
- * This method is used for debugging only and should not be used
- * as a clock.
- */
- static native long getSystemTime();
-
- /**
- * Preserves the back buffer of the current surface after a buffer swap.
- * Calling this method sets the EGL_SWAP_BEHAVIOR attribute of the current
- * surface to EGL_BUFFER_PRESERVED. Calling this method requires an EGL
- * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
- *
- * @return True if the swap behavior was successfully changed,
- * false otherwise.
- */
- static native boolean preserveBackBuffer();
-
- /**
- * Indicates whether the current surface preserves its back buffer
- * after a buffer swap.
- *
- * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
- * false otherwise
- */
- static native boolean isBackBufferPreserved();
-
- static native void nDestroyLayer(long layerPtr);
-
- private static native void nPrepareTree(long displayListPtr);
-
- class GraphDataProvider {
- /**
- * Draws the graph as bars. Frame elements are stacked on top of
- * each other.
- */
- public static final int GRAPH_TYPE_BARS = 0;
- /**
- * Draws the graph as lines. The number of series drawn corresponds
- * to the number of elements.
- */
- public static final int GRAPH_TYPE_LINES = 1;
-
- private final int mGraphType;
-
- private int mVerticalUnit;
- private int mHorizontalUnit;
- private int mHorizontalMargin;
- private int mThresholdStroke;
-
- public GraphDataProvider(int graphType) {
- mGraphType = graphType;
- }
-
- void prepare(DisplayMetrics metrics) {
- final float density = metrics.density;
-
- mVerticalUnit = dpToPx(PROFILE_DRAW_DP_PER_MS, density);
- mHorizontalUnit = dpToPx(PROFILE_DRAW_WIDTH, density);
- mHorizontalMargin = dpToPx(PROFILE_DRAW_MARGIN, density);
- mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
- }
-
- int getGraphType() {
- return mGraphType;
- }
-
- int getVerticalUnitSize() {
- return mVerticalUnit;
- }
-
- int getHorizontalUnitSize() {
- return mHorizontalUnit;
- }
-
- int getHorizontaUnitMargin() {
- return mHorizontalMargin;
- }
-
- float[] getData() {
- return mProfileData;
- }
-
- float getThreshold() {
- return 16;
- }
-
- int getFrameCount() {
- return mProfileData.length / PROFILE_FRAME_DATA_COUNT;
- }
-
- int getElementCount() {
- return PROFILE_FRAME_DATA_COUNT;
- }
-
- int getCurrentFrame() {
- return mProfileCurrentFrame / PROFILE_FRAME_DATA_COUNT;
- }
-
- void setupGraphPaint(Paint paint, int elementIndex) {
- paint.setColor(PROFILE_DRAW_COLORS[elementIndex]);
- if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
- }
-
- void setupThresholdPaint(Paint paint) {
- paint.setColor(PROFILE_DRAW_THRESHOLD_COLOR);
- paint.setStrokeWidth(mThresholdStroke);
- }
-
- void setupCurrentFramePaint(Paint paint) {
- paint.setColor(PROFILE_DRAW_CURRENT_FRAME_COLOR);
- if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
- }
- }
-}
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index 9568760..b8e7d8c 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -110,48 +110,6 @@ public abstract class HardwareCanvas extends Canvas {
return RenderNode.STATUS_DONE;
}
- /**
- * Indicates that the specified layer must be updated as soon as possible.
- *
- * @param layer The layer to update
- *
- * @see #clearLayerUpdates()
- *
- * @hide
- */
- abstract void pushLayerUpdate(HardwareLayer layer);
-
- /**
- * Cancels a queued layer update. If the specified layer was not
- * queued for update, this method has no effect.
- *
- * @param layer The layer whose update to cancel
- *
- * @see #pushLayerUpdate(HardwareLayer)
- * @see #clearLayerUpdates()
- *
- * @hide
- */
- abstract void cancelLayerUpdate(HardwareLayer layer);
-
- /**
- * Immediately executes all enqueued layer updates.
- *
- * @see #pushLayerUpdate(HardwareLayer)
- *
- * @hide
- */
- abstract void flushLayerUpdates();
-
- /**
- * Removes all enqueued layer updates.
- *
- * @see #pushLayerUpdate(HardwareLayer)
- *
- * @hide
- */
- abstract void clearLayerUpdates();
-
public abstract void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
CanvasProperty<Float> radius, CanvasProperty<Paint> paint);
}
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 652bcd2..6acb134 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -172,24 +172,6 @@ final class HardwareLayer {
});
}
- /**
- * This exists to minimize impact into the current HardwareLayer paths as
- * some of the specifics of how to handle error cases in the fully
- * deferred model will work
- */
- @Deprecated
- public void flushChanges() {
- if (HardwareRenderer.sUseRenderThread) {
- // Not supported, don't try.
- return;
- }
-
- boolean success = nFlushChanges(mFinalizer.get());
- if (!success) {
- destroy();
- }
- }
-
public long getLayer() {
return nGetLayer(mFinalizer.get());
}
@@ -216,33 +198,14 @@ final class HardwareLayer {
return st;
}
- /**
- * This should only be used by HardwareRenderer! Do not call directly
- */
- static HardwareLayer createTextureLayer(HardwareRenderer renderer) {
- return new HardwareLayer(renderer, nCreateTextureLayer(), LAYER_TYPE_TEXTURE);
- }
-
static HardwareLayer adoptTextureLayer(HardwareRenderer renderer, long layer) {
return new HardwareLayer(renderer, layer, LAYER_TYPE_TEXTURE);
}
- /**
- * This should only be used by HardwareRenderer! Do not call directly
- */
- static HardwareLayer createDisplayListLayer(HardwareRenderer renderer,
- int width, int height) {
- return new HardwareLayer(renderer, nCreateRenderLayer(width, height), LAYER_TYPE_DISPLAY_LIST);
- }
-
static HardwareLayer adoptDisplayListLayer(HardwareRenderer renderer, long layer) {
return new HardwareLayer(renderer, layer, LAYER_TYPE_DISPLAY_LIST);
}
- /** This also creates the underlying layer */
- private static native long nCreateTextureLayer();
- private static native long nCreateRenderLayer(int width, int height);
-
private static native void nOnTextureDestroyed(long layerUpdater);
private static native boolean nPrepare(long layerUpdater, int width, int height, boolean isOpaque);
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index d71de9f..d67c974 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -171,9 +171,6 @@ public abstract class HardwareRenderer {
*/
public static boolean sSystemRendererDisabled = false;
- /** @hide */
- public static boolean sUseRenderThread = true;
-
private boolean mEnabled;
private boolean mRequested = true;
@@ -309,7 +306,7 @@ public abstract class HardwareRenderer {
* @hide
*/
public static void setupDiskCache(File cacheDir) {
- GLRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
+ ThreadedRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
}
/**
@@ -469,11 +466,7 @@ public abstract class HardwareRenderer {
static HardwareRenderer create(boolean translucent) {
HardwareRenderer renderer = null;
if (GLES20Canvas.isAvailable()) {
- if (sUseRenderThread) {
- renderer = new ThreadedRenderer(translucent);
- } else {
- renderer = new GLRenderer(translucent);
- }
+ renderer = new ThreadedRenderer(translucent);
}
return renderer;
}
@@ -500,7 +493,7 @@ public abstract class HardwareRenderer {
* see {@link android.content.ComponentCallbacks}
*/
static void startTrimMemory(int level) {
- GLRenderer.startTrimMemory(level);
+ ThreadedRenderer.startTrimMemory(level);
}
/**
@@ -508,7 +501,7 @@ public abstract class HardwareRenderer {
* cleanup special resources used by the memory trimming process.
*/
static void endTrimMemory() {
- GLRenderer.endTrimMemory();
+ ThreadedRenderer.endTrimMemory();
}
/**
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 11db996..9b3ef7f 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -331,6 +331,14 @@ public class ThreadedRenderer extends HardwareRenderer {
}
}
+ static void startTrimMemory(int level) {
+ // TODO
+ }
+
+ static void endTrimMemory() {
+ // TODO
+ }
+
private static class AtlasInitializer {
static AtlasInitializer sInstance = new AtlasInitializer();
@@ -367,6 +375,8 @@ public class ThreadedRenderer extends HardwareRenderer {
}
}
+ static native void setupShadersDiskCache(String cacheFile);
+
private static native void nSetAtlas(GraphicBuffer buffer, long[] map);
private static native long nCreateRootRenderNode();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ce266d7..b500e46 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13593,12 +13593,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
- // The layer is not valid if the underlying GPU resources cannot be allocated
- mHardwareLayer.flushChanges();
- if (!mHardwareLayer.isValid()) {
- return null;
- }
-
mHardwareLayer.setLayerPaint(mLayerPaint);
RenderNode displayList = mHardwareLayer.startRecording();
updateDisplayListIfDirty(displayList, true);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ac25b57..f3d1e3c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -716,17 +716,6 @@ public final class ViewRootImpl implements ViewParent,
if (!HardwareRenderer.sRendererDisabled || (HardwareRenderer.sSystemRendererDisabled
&& forceHwAccelerated)) {
- if (!HardwareRenderer.sUseRenderThread) {
- // TODO: Delete
- // Don't enable hardware acceleration when we're not on the main thread
- if (!HardwareRenderer.sSystemRendererDisabled &&
- Looper.getMainLooper() != Looper.myLooper()) {
- Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
- + "acceleration outside of the main thread, aborting");
- return;
- }
- }
-
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
}