diff --git a/play-services-cast/build.gradle b/play-services-cast/build.gradle
new file mode 100644
index 0000000..4146083
--- /dev/null
+++ b/play-services-cast/build.gradle
@@ -0,0 +1,24 @@
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.3.1'
+ classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
+ }
+}
+
+apply plugin: 'com.android.library'
+apply plugin: 'com.github.dcendents.android-maven'
+
+dependencies {
+ compile project(':play-services-base')
+}
+
+android {
+ compileSdkVersion 22
+ buildToolsVersion "22.0.1"
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_7
+ }
+}
diff --git a/play-services-cast/src/main/AndroidManifest.xml b/play-services-cast/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c2dd4c3
--- /dev/null
+++ b/play-services-cast/src/main/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/ApplicationMetadata.java b/play-services-cast/src/main/java/com/google/android/gms/cast/ApplicationMetadata.java
new file mode 100644
index 0000000..4eb6a97
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/ApplicationMetadata.java
@@ -0,0 +1,104 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import android.net.Uri;
+import android.os.Parcel;
+import com.google.android.gms.common.images.WebImage;
+import org.microg.gms.common.Objects;
+import org.microg.safeparcel.AutoSafeParcelable;
+import org.microg.safeparcel.SafeParcelUtil;
+import org.microg.safeparcel.SafeParcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class ApplicationMetadata implements SafeParcelable {
+
+ public static final android.os.Parcelable.Creator CREATOR = new AutoSafeParcelable.AutoCreator<>(ApplicationMetadata.class);
+
+ private final int versionCode;
+ String applicationId;
+ String name;
+ List images;
+ List namespaces;
+ String senderAppIdentifier;
+ Uri senderAppLaunchUrl;
+
+ ApplicationMetadata(int versionCode, String applicationId, String name, List images, List namespaces, String senderAppIdentifier, Uri senderAppLaunchUrl) {
+ this.versionCode = versionCode;
+ this.applicationId = applicationId;
+ this.name = name;
+ this.images = images;
+ this.namespaces = namespaces;
+ this.senderAppIdentifier = senderAppIdentifier;
+ this.senderAppLaunchUrl = senderAppLaunchUrl;
+ }
+
+ private ApplicationMetadata() {
+ versionCode = 1;
+ images = new ArrayList<>();
+ namespaces = new ArrayList<>();
+ }
+
+ int getVersionCode() {
+ return versionCode;
+ }
+
+ public String getApplicationId() {
+ return applicationId;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isNamespaceSupported(String namespace) {
+ return namespaces != null && namespaces.contains(namespace);
+ }
+
+ public boolean areNamespacesSupported(List namespaces) {
+ return this.namespaces != null && this.namespaces.containsAll(namespaces);
+ }
+
+ public String getSenderAppIdentifier() {
+ return senderAppIdentifier;
+ }
+
+ public Uri zzhh() {
+ return senderAppLaunchUrl;
+ }
+
+ public List getImages() {
+ return images;
+ }
+
+ public String toString() {
+ return (new StringBuilder()).append("applicationId: ").append(applicationId).append(", name: ").append(name).append(", images.count: ").append(images != null ? images.size() : 0).append(", namespaces.count: ").append(namespaces != null ? namespaces.size() : 0).append(", senderAppIdentifier: ").append(senderAppIdentifier).append(", senderAppLaunchUrl: ").append(senderAppLaunchUrl).toString();
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ SafeParcelUtil.writeObject(this, out, flags);
+ }
+
+ public int hashCode() {
+ return Objects.hash(versionCode, applicationId, name, images, namespaces, senderAppIdentifier, senderAppLaunchUrl);
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof ApplicationMetadata)) {
+ return false;
+ } else {
+ ApplicationMetadata applicationmetadata = (ApplicationMetadata) obj;
+ return Objects.equals(applicationId, applicationmetadata.applicationId) && Objects.equals(images, applicationmetadata.images) && Objects.equals(name, applicationmetadata.name) && Objects.equals(namespaces, applicationmetadata.namespaces) && Objects.equals(senderAppIdentifier, applicationmetadata.senderAppIdentifier) && Objects.equals(senderAppLaunchUrl, applicationmetadata.senderAppLaunchUrl);
+ }
+ }
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java b/play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java
new file mode 100644
index 0000000..78a9c1c
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java
@@ -0,0 +1,298 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.google.android.gms.cast;
+
+import android.content.Context;
+import android.os.Looper;
+import com.google.android.gms.common.api.*;
+import com.google.android.gms.common.api.Api.ApiOptions.HasOptions;
+import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
+import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
+import com.google.android.gms.common.images.WebImage;
+import org.microg.gms.common.Objects;
+import org.microg.gms.common.api.ApiBuilder;
+import org.microg.gms.common.api.ApiConnection;
+import org.microg.gms.common.api.DummyPendingResult;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+
+public final class Cast {
+ public static final int MAX_MESSAGE_LENGTH = 65536;
+ public static final int MAX_NAMESPACE_LENGTH = 128;
+ public static final String EXTRA_APP_NO_LONGER_RUNNING = "com.google.android.gms.cast.EXTRA_APP_NO_LONGER_RUNNING";
+ public static final Api API;
+ public static final Cast.CastApi CastApi;
+
+ private Cast() {
+ }
+
+ static {
+ CastApi = new CastApi.CastApiImpl();
+ API = new Api<>(new ApiBuilder() {
+ @Override
+ public ApiConnection build(Context context, Looper looper, CastOptions options, AccountInfo accountInfo, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
+ return new ApiConnection() {
+ private boolean connected = false;
+
+ @Override
+ public void connect() {
+ connected = true;
+ }
+
+ @Override
+ public void disconnect() {
+ connected = false;
+ }
+
+ @Override
+ public boolean isConnected() {
+ return connected;
+ }
+
+ @Override
+ public boolean isConnecting() {
+ return false;
+ }
+ };
+ }
+ });
+ }
+
+ public interface CastApi {
+ void requestStatus(GoogleApiClient var1) throws IOException, IllegalStateException;
+
+ PendingResult sendMessage(GoogleApiClient var1, String var2, String var3);
+
+ PendingResult launchApplication(GoogleApiClient var1, String var2);
+
+ @Deprecated
+ PendingResult launchApplication(GoogleApiClient var1, String var2, boolean var3);
+
+ PendingResult launchApplication(GoogleApiClient var1, String var2, LaunchOptions var3);
+
+ PendingResult joinApplication(GoogleApiClient var1, String var2, String var3);
+
+ PendingResult joinApplication(GoogleApiClient var1, String var2);
+
+ PendingResult joinApplication(GoogleApiClient var1);
+
+ PendingResult leaveApplication(GoogleApiClient var1);
+
+ PendingResult stopApplication(GoogleApiClient var1);
+
+ PendingResult stopApplication(GoogleApiClient var1, String var2);
+
+ void setVolume(GoogleApiClient var1, double var2) throws IOException, IllegalArgumentException, IllegalStateException;
+
+ double getVolume(GoogleApiClient var1) throws IllegalStateException;
+
+ void setMute(GoogleApiClient var1, boolean var2) throws IOException, IllegalStateException;
+
+ boolean isMute(GoogleApiClient var1) throws IllegalStateException;
+
+ ApplicationMetadata getApplicationMetadata(GoogleApiClient var1) throws IllegalStateException;
+
+ String getApplicationStatus(GoogleApiClient var1) throws IllegalStateException;
+
+ void setMessageReceivedCallbacks(GoogleApiClient var1, String var2, Cast.MessageReceivedCallback var3) throws IOException, IllegalStateException;
+
+ void removeMessageReceivedCallbacks(GoogleApiClient var1, String var2) throws IOException, IllegalArgumentException;
+
+ public static final class CastApiImpl implements Cast.CastApi {
+ private double volume;
+ private boolean mute;
+ private ApplicationMetadata applicationMetadata = new ApplicationMetadata(1, "bob", "bob", new ArrayList(), new ArrayList<>(Collections.singletonList("bob")), "bob", null);
+
+ public CastApiImpl() {
+ }
+
+ public void requestStatus(GoogleApiClient client) throws IOException, IllegalStateException {
+
+ }
+
+ public PendingResult sendMessage(final GoogleApiClient client, final String namespace, final String message) {
+ return new DummyPendingResult<>(Status.SUCCESS);
+ }
+
+ public PendingResult launchApplication(final GoogleApiClient client, final String applicationId) {
+ return new DummyPendingResult<>(dummyApplicationConnectionResult(Status.INTERRUPTED, applicationMetadata));
+ }
+
+ public PendingResult launchApplication(final GoogleApiClient client, final String applicationId, final LaunchOptions options) {
+ return new DummyPendingResult<>(dummyApplicationConnectionResult(Status.INTERRUPTED, applicationMetadata));
+ }
+
+ @Deprecated
+ public PendingResult launchApplication(GoogleApiClient client, String applicationId, boolean relaunchIfRunning) {
+ LaunchOptions var4 = (new com.google.android.gms.cast.LaunchOptions.Builder()).setRelaunchIfRunning(relaunchIfRunning).build();
+ return this.launchApplication(client, applicationId, var4);
+ }
+
+ public PendingResult joinApplication(final GoogleApiClient client, final String applicationId, final String sessionId) {
+ return new DummyPendingResult<>(dummyApplicationConnectionResult(Status.INTERRUPTED, applicationMetadata));
+ }
+
+ public PendingResult joinApplication(final GoogleApiClient client, final String applicationId) {
+ return new DummyPendingResult<>(dummyApplicationConnectionResult(Status.INTERRUPTED, applicationMetadata));
+ }
+
+ public PendingResult joinApplication(final GoogleApiClient client) {
+ return new DummyPendingResult<>(dummyApplicationConnectionResult(Status.INTERRUPTED, applicationMetadata));
+ }
+
+ public PendingResult leaveApplication(final GoogleApiClient client) {
+ return new DummyPendingResult<>(Status.SUCCESS);
+ }
+
+ public PendingResult stopApplication(final GoogleApiClient client) {
+ return new DummyPendingResult<>(Status.SUCCESS);
+ }
+
+ public PendingResult stopApplication(final GoogleApiClient client, final String sessionId) {
+ return new DummyPendingResult<>(Status.SUCCESS);
+ }
+
+ public void setVolume(GoogleApiClient client, double volume) throws IOException, IllegalArgumentException, IllegalStateException {
+ this.volume = volume;
+ }
+
+ public double getVolume(GoogleApiClient client) throws IllegalStateException {
+ return volume;
+ }
+
+ public void setMute(GoogleApiClient client, boolean mute) throws IOException, IllegalStateException {
+ this.mute = mute;
+ }
+
+ public boolean isMute(GoogleApiClient client) throws IllegalStateException {
+ return mute;
+ }
+
+ public ApplicationMetadata getApplicationMetadata(GoogleApiClient client) throws IllegalStateException {
+ return applicationMetadata;
+ }
+
+ public String getApplicationStatus(GoogleApiClient client) throws IllegalStateException {
+ return null;
+ }
+
+ public void setMessageReceivedCallbacks(GoogleApiClient client, String namespace, Cast.MessageReceivedCallback callbacks) throws IOException, IllegalStateException {
+
+ }
+
+ public void removeMessageReceivedCallbacks(GoogleApiClient client, String namespace) throws IOException, IllegalArgumentException {
+
+ }
+ }
+ }
+
+ private static Cast.ApplicationConnectionResult dummyApplicationConnectionResult(final Status status, final ApplicationMetadata applicationMetadata) {
+ return new Cast.ApplicationConnectionResult() {
+ public Status getStatus() {
+ return status;
+ }
+
+ public boolean getWasLaunched() {
+ return false;
+ }
+
+ public String getSessionId() {
+ return null;
+ }
+
+ public String getApplicationStatus() {
+ return null;
+ }
+
+ public ApplicationMetadata getApplicationMetadata() {
+ return applicationMetadata;
+ }
+ };
+ }
+
+ public interface ApplicationConnectionResult extends Result {
+ ApplicationMetadata getApplicationMetadata();
+
+ String getApplicationStatus();
+
+ String getSessionId();
+
+ boolean getWasLaunched();
+ }
+
+ public static final class CastOptions implements HasOptions {
+ final CastDevice castDevice;
+ final Cast.Listener castListener;
+ private final int verboseLogging;
+
+ private CastOptions(Cast.CastOptions.Builder builder) {
+ this.castDevice = builder.castDevice;
+ this.castListener = builder.castListener;
+ this.verboseLogging = builder.verboseLogging;
+ }
+
+ public static Cast.CastOptions.Builder builder(CastDevice castDevice, Cast.Listener castListener) {
+ return new Cast.CastOptions.Builder(castDevice, castListener);
+ }
+
+ public static final class Builder {
+ CastDevice castDevice;
+ Cast.Listener castListener;
+ private int verboseLogging;
+
+ private Builder(CastDevice castDevice, Cast.Listener castListener) {
+ Objects.requireNonNull(castDevice, "CastDevice parameter cannot be null");
+ Objects.requireNonNull(castListener, "CastListener parameter cannot be null");
+ this.castDevice = castDevice;
+ this.castListener = castListener;
+ this.verboseLogging = 0;
+ }
+
+ public Cast.CastOptions.Builder setVerboseLoggingEnabled(boolean enabled) {
+ if (enabled) {
+ this.verboseLogging |= 1;
+ } else {
+ this.verboseLogging &= -2;
+ }
+
+ return this;
+ }
+
+ public Cast.CastOptions build() {
+ return new Cast.CastOptions(this);
+ }
+ }
+ }
+
+ public interface MessageReceivedCallback {
+ void onMessageReceived(CastDevice var1, String var2, String var3);
+ }
+
+ public static class Listener {
+ public Listener() {
+ }
+
+ public void onApplicationStatusChanged() {
+ }
+
+ public void onApplicationMetadataChanged(ApplicationMetadata applicationMetadata) {
+ }
+
+ public void onApplicationDisconnected(int statusCode) {
+ }
+
+ public void zzab(int var1) {
+ }
+
+ public void zzac(int var1) {
+ }
+
+ public void onVolumeChanged() {
+ }
+ }
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/CastDevice.java b/play-services-cast/src/main/java/com/google/android/gms/cast/CastDevice.java
new file mode 100644
index 0000000..d1d9326
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/CastDevice.java
@@ -0,0 +1,173 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import android.os.*;
+import com.google.android.gms.common.images.WebImage;
+import org.microg.gms.common.Objects;
+import org.microg.safeparcel.AutoSafeParcelable;
+
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class CastDevice extends AutoSafeParcelable {
+ public static final android.os.Parcelable.Creator CREATOR = new AutoSafeParcelable.AutoCreator<>(CastDevice.class);
+
+ private final int versionCode;
+ private String deviceId;
+ String hostAddress;
+ private Inet4Address inetaddress;
+ private String friendlyName;
+ private String modelName;
+ private String deviceVersion;
+ private int servicePort;
+ private List icons;
+ private int capabilities;
+ private int status;
+
+ CastDevice(int versionCode, String deviceId, String hostAddress, String friendlyName, String modelName, String deviceVersion, int servicePort,
+ List icons, int capabilities, int status) {
+ this.versionCode = versionCode;
+ this.deviceId = deviceId;
+ this.hostAddress = hostAddress;
+ if (this.hostAddress != null)
+ try {
+ InetAddress inetaddress = InetAddress.getByName(this.hostAddress);
+ if (inetaddress instanceof Inet4Address)
+ this.inetaddress = (Inet4Address) inetaddress;
+ } catch (UnknownHostException unknownhostexception) {
+ this.inetaddress = null;
+ }
+ this.friendlyName = friendlyName;
+ this.modelName = modelName;
+ this.deviceVersion = deviceVersion;
+ this.servicePort = servicePort;
+ this.icons = icons;
+ this.capabilities = capabilities;
+ this.status = status;
+ }
+
+ private CastDevice() {
+ this(3, null, null, null, null, null, -1, new ArrayList(), 0, -1);
+ }
+
+ int getVersionCode() {
+ return versionCode;
+ }
+
+ public String getDeviceId() {
+ return deviceId;
+ }
+
+ public Inet4Address getIpAddress() {
+ return inetaddress;
+ }
+
+ public String getFriendlyName() {
+ return friendlyName;
+ }
+
+ public String getModelName() {
+ return modelName;
+ }
+
+ public String getDeviceVersion() {
+ return deviceVersion;
+ }
+
+ public int getServicePort() {
+ return servicePort;
+ }
+
+ public List getIcons() {
+ return Collections.unmodifiableList(icons);
+ }
+
+ public WebImage getIcon(int preferredWidth, int preferredHeight) {
+ if (icons.isEmpty())
+ return null;
+ if (preferredWidth <= 0 || preferredHeight <= 0)
+ return (WebImage) icons.get(0);
+ WebImage webimage = null;
+ WebImage webimage1 = null;
+ for (final WebImage webimage2 : icons) {
+ int i = webimage2.getWidth();
+ int j = webimage2.getHeight();
+ if (i >= preferredWidth && j >= preferredHeight) {
+ if (webimage == null || webimage.getWidth() > i && webimage.getHeight() > j)
+ webimage = webimage2;
+ } else if (i < preferredWidth && j < preferredHeight && (webimage1 == null || webimage1.getWidth() < i && webimage1.getHeight() < j))
+ webimage1 = webimage2;
+ }
+ if (webimage != null)
+ return webimage;
+ else if (webimage1 != null)
+ return webimage1;
+ else
+ return icons.get(0);
+ }
+
+ public boolean hasIcons() {
+ return !icons.isEmpty();
+ }
+
+ public int getCapabilities() {
+ return capabilities;
+ }
+
+ public int getStatus() {
+ return status;
+ }
+
+ public String toString() {
+ return String.format("\"%s\" (%s)", friendlyName, deviceId);
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof CastDevice))
+ return false;
+ CastDevice castdevice = (CastDevice) obj;
+ if (getDeviceId() == null)
+ return castdevice.getDeviceId() == null;
+ else
+ return Objects.equals(deviceId, castdevice.deviceId) && Objects.equals(inetaddress, castdevice.inetaddress) && Objects.equals(modelName, castdevice.modelName) && Objects.equals(friendlyName, castdevice.friendlyName) && Objects.equals(deviceVersion, castdevice.deviceVersion) && servicePort == castdevice.servicePort && Objects.equals(icons, castdevice.icons) && capabilities == castdevice.capabilities && status == castdevice.status;
+ }
+
+ public boolean isSameDevice(CastDevice castDevice) {
+ if (castDevice == null)
+ return false;
+ if (getDeviceId() == null)
+ return castDevice.getDeviceId() == null;
+ else
+ return Objects.equals(getDeviceId(), castDevice.getDeviceId());
+ }
+
+ public int hashCode() {
+ return deviceId != null ? deviceId.hashCode() : 0;
+ }
+
+ public void putInBundle(Bundle bundle) {
+ if (bundle != null)
+ bundle.putParcelable("com.google.android.gms.cast.EXTRA_CAST_DEVICE", this);
+ }
+
+ public static CastDevice getFromBundle(Bundle extras) {
+ if (extras == null) {
+ return null;
+ } else {
+ extras.setClassLoader(CastDevice.class.getClassLoader());
+ return (CastDevice) extras.getParcelable("com.google.android.gms.cast.EXTRA_CAST_DEVICE");
+ }
+ }
+
+ public boolean isOnLocalNetwork() {
+ return !deviceId.startsWith("__cast_nearby__");
+ }
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/CastMediaControlIntent.java b/play-services-cast/src/main/java/com/google/android/gms/cast/CastMediaControlIntent.java
new file mode 100644
index 0000000..d8e85c6
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/CastMediaControlIntent.java
@@ -0,0 +1,119 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import android.text.TextUtils;
+import java.util.*;
+
+public final class CastMediaControlIntent
+{
+
+ public static String categoryForRemotePlayback(String applicationId)
+ throws IllegalArgumentException
+ {
+ if(TextUtils.isEmpty(applicationId))
+ throw new IllegalArgumentException("applicationId cannot be null or empty");
+ else
+ return zza("com.google.android.gms.cast.CATEGORY_CAST_REMOTE_PLAYBACK", applicationId, null);
+ }
+
+ public static String categoryForRemotePlayback()
+ {
+ return zza("com.google.android.gms.cast.CATEGORY_CAST_REMOTE_PLAYBACK", null, null);
+ }
+
+ public static String categoryForCast(String applicationId)
+ throws IllegalArgumentException
+ {
+ if(applicationId == null)
+ throw new IllegalArgumentException("applicationId cannot be null");
+ else
+ return zza("com.google.android.gms.cast.CATEGORY_CAST", applicationId, null);
+ }
+
+ public static String categoryForCast(Collection namespaces)
+ throws IllegalArgumentException
+ {
+ if(namespaces == null)
+ throw new IllegalArgumentException("namespaces cannot be null");
+ else
+ return zza("com.google.android.gms.cast.CATEGORY_CAST", null, namespaces);
+ }
+
+ public static String categoryForCast(String applicationId, Collection namespaces)
+ {
+ if(applicationId == null)
+ throw new IllegalArgumentException("applicationId cannot be null");
+ if(namespaces == null)
+ throw new IllegalArgumentException("namespaces cannot be null");
+ else
+ return zza("com.google.android.gms.cast.CATEGORY_CAST", applicationId, namespaces);
+ }
+
+ private static String zza(String s, String s1, Collection collection)
+ throws IllegalArgumentException
+ {
+ StringBuffer stringbuffer = new StringBuffer(s);
+ if(s1 != null)
+ {
+ String s2 = s1.toUpperCase();
+ if(!s2.matches("[A-F0-9]+"))
+ throw new IllegalArgumentException((new StringBuilder()).append("Invalid application ID: ").append(s1).toString());
+ stringbuffer.append("/").append(s2);
+ }
+ if(collection != null)
+ {
+ if(collection.isEmpty())
+ throw new IllegalArgumentException("Must specify at least one namespace");
+ for(Iterator iterator = collection.iterator(); iterator.hasNext();)
+ {
+ String s3 = (String)iterator.next();
+ if(TextUtils.isEmpty(s3) || s3.trim().equals(""))
+ throw new IllegalArgumentException("Namespaces must not be null or empty");
+ }
+
+ if(s1 == null)
+ stringbuffer.append("/");
+ stringbuffer.append("/").append(TextUtils.join(",", collection));
+ }
+ return stringbuffer.toString();
+ }
+
+ public static String languageTagForLocale(Locale locale)
+ {
+ final StringBuilder ret = new StringBuilder(20);
+ ret.append(locale.getLanguage());
+
+ final String var2 = locale.getCountry();
+ if(!TextUtils.isEmpty(var2)) {
+ ret.append('-').append(var2);
+ }
+
+ final String var3 = locale.getVariant();
+ if(!TextUtils.isEmpty(var3)) {
+ ret.append('-').append(var3);
+ }
+
+ return ret.toString();
+ }
+
+ private CastMediaControlIntent()
+ {
+ }
+
+ public static final String CATEGORY_CAST = "com.google.android.gms.cast.CATEGORY_CAST";
+ public static final String DEFAULT_MEDIA_RECEIVER_APPLICATION_ID = "CC1AD845";
+ public static final String ACTION_SYNC_STATUS = "com.google.android.gms.cast.ACTION_SYNC_STATUS";
+ public static final String EXTRA_CUSTOM_DATA = "com.google.android.gms.cast.EXTRA_CUSTOM_DATA";
+ public static final String EXTRA_CAST_APPLICATION_ID = "com.google.android.gms.cast.EXTRA_CAST_APPLICATION_ID";
+ public static final String EXTRA_CAST_RELAUNCH_APPLICATION = "com.google.android.gms.cast.EXTRA_CAST_RELAUNCH_APPLICATION";
+ public static final String EXTRA_CAST_LANGUAGE_CODE = "com.google.android.gms.cast.EXTRA_CAST_LANGUAGE_CODE";
+ public static final String EXTRA_CAST_STOP_APPLICATION_WHEN_SESSION_ENDS = "com.google.android.gms.cast.EXTRA_CAST_STOP_APPLICATION_WHEN_SESSION_ENDS";
+ public static final String EXTRA_DEBUG_LOGGING_ENABLED = "com.google.android.gms.cast.EXTRA_DEBUG_LOGGING_ENABLED";
+ public static final String EXTRA_ERROR_CODE = "com.google.android.gms.cast.EXTRA_ERROR_CODE";
+ public static final int ERROR_CODE_REQUEST_FAILED = 1;
+ public static final int ERROR_CODE_SESSION_START_FAILED = 2;
+ public static final int ERROR_CODE_TEMPORARILY_DISCONNECTED = 3;
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/CastStatusCodes.java b/play-services-cast/src/main/java/com/google/android/gms/cast/CastStatusCodes.java
new file mode 100644
index 0000000..dd39f07
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/CastStatusCodes.java
@@ -0,0 +1,31 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+
+public final class CastStatusCodes
+{
+
+ private CastStatusCodes()
+ {
+ }
+
+ public static final int SUCCESS = 0;
+ public static final int NETWORK_ERROR = 7;
+ public static final int TIMEOUT = 15;
+ public static final int INTERRUPTED = 14;
+ public static final int AUTHENTICATION_FAILED = 2000;
+ public static final int INVALID_REQUEST = 2001;
+ public static final int CANCELED = 2002;
+ public static final int NOT_ALLOWED = 2003;
+ public static final int APPLICATION_NOT_FOUND = 2004;
+ public static final int APPLICATION_NOT_RUNNING = 2005;
+ public static final int MESSAGE_TOO_LARGE = 2006;
+ public static final int MESSAGE_SEND_BUFFER_TOO_FULL = 2007;
+ public static final int FAILED = 2100;
+ public static final int REPLACED = 2103;
+ public static final int INTERNAL_ERROR = 8;
+ public static final int UNKNOWN_ERROR = 13;
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/LaunchOptions.java b/play-services-cast/src/main/java/com/google/android/gms/cast/LaunchOptions.java
new file mode 100644
index 0000000..751e70e
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/LaunchOptions.java
@@ -0,0 +1,112 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import org.microg.gms.common.Objects;
+import org.microg.safeparcel.AutoSafeParcelable;
+
+import java.util.Locale;
+
+// Referenced classes of package com.google.android.gms.cast:
+// zzc
+
+public class LaunchOptions extends AutoSafeParcelable
+{
+ public static final android.os.Parcelable.Creator CREATOR = new AutoSafeParcelable.AutoCreator<>(LaunchOptions.class);
+
+ private final int versionCode;
+ private boolean relaunchIfRunning;
+ private String language;
+
+ public static final class Builder
+ {
+
+ public Builder setRelaunchIfRunning(boolean relaunchIfRunning)
+ {
+ launchOptions.setRelaunchIfRunning(relaunchIfRunning);
+ return this;
+ }
+
+ public Builder setLocale(Locale locale)
+ {
+ launchOptions.setLanguage(CastMediaControlIntent.languageTagForLocale(locale));
+ return this;
+ }
+
+ public LaunchOptions build()
+ {
+ return launchOptions;
+ }
+
+ private LaunchOptions launchOptions;
+
+ public Builder()
+ {
+ launchOptions = new LaunchOptions();
+ }
+ }
+
+ LaunchOptions(int versionCode, boolean relaunchIfRunning, String language)
+ {
+ this.versionCode = versionCode;
+ this.relaunchIfRunning = relaunchIfRunning;
+ this.language = language;
+ }
+
+ public LaunchOptions()
+ {
+ this(1, false, CastMediaControlIntent.languageTagForLocale(Locale.getDefault()));
+ }
+
+ int getVersionCode()
+ {
+ return versionCode;
+ }
+
+ public void setRelaunchIfRunning(boolean relaunchIfRunning)
+ {
+ this.relaunchIfRunning = relaunchIfRunning;
+ }
+
+ public boolean getRelaunchIfRunning()
+ {
+ return relaunchIfRunning;
+ }
+
+ public void setLanguage(String language)
+ {
+ this.language = language;
+ }
+
+ public String getLanguage()
+ {
+ return language;
+ }
+
+ public String toString()
+ {
+ return String.format("LaunchOptions(relaunchIfRunning=%b, language=%s)", relaunchIfRunning, language);
+ }
+
+ public boolean equals(Object obj)
+ {
+ if(obj == this)
+ return true;
+ if(!(obj instanceof LaunchOptions))
+ {
+ return false;
+ } else
+ {
+ LaunchOptions launchoptions = (LaunchOptions)obj;
+ return relaunchIfRunning == launchoptions.relaunchIfRunning && Objects.equals(language, launchoptions.language);
+ }
+ }
+
+ public int hashCode()
+ {
+ return Objects.hash(relaunchIfRunning, language);
+ }
+
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/MediaInfo.java b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaInfo.java
new file mode 100644
index 0000000..8783fe0
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaInfo.java
@@ -0,0 +1,364 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import android.text.TextUtils;
+import org.json.*;
+import org.microg.gms.common.Objects;
+
+import java.util.ArrayList;
+import java.util.List;
+
+// Referenced classes of package com.google.android.gms.cast:
+// MediaMetadata, MediaTrack, TextTrackStyle
+
+public final class MediaInfo
+{
+ public static class Builder
+ {
+
+ public Builder setStreamType(int streamType)
+ throws IllegalArgumentException
+ {
+ mediaInfo.setStreamType(streamType);
+ return this;
+ }
+
+ public Builder setContentType(String contentType)
+ throws IllegalArgumentException
+ {
+ mediaInfo.setContentType(contentType);
+ return this;
+ }
+
+ public Builder setMetadata(MediaMetadata metadata)
+ {
+ mediaInfo.zza(metadata);
+ return this;
+ }
+
+ public Builder setStreamDuration(long duration)
+ throws IllegalArgumentException
+ {
+ mediaInfo.zzm(duration);
+ return this;
+ }
+
+ public Builder setCustomData(JSONObject customData)
+ {
+ mediaInfo.setCustomData(customData);
+ return this;
+ }
+
+ public Builder setMediaTracks(List mediaTracks)
+ {
+ mediaInfo.zzg(mediaTracks);
+ return this;
+ }
+
+ public Builder setTextTrackStyle(TextTrackStyle textTrackStyle)
+ {
+ mediaInfo.setTextTrackStyle(textTrackStyle);
+ return this;
+ }
+
+ public MediaInfo build()
+ throws IllegalArgumentException
+ {
+ mediaInfo.zzhi();
+ return mediaInfo;
+ }
+
+ private final MediaInfo mediaInfo;
+
+ public Builder(String contentId)
+ throws IllegalArgumentException
+ {
+ if(TextUtils.isEmpty(contentId))
+ {
+ throw new IllegalArgumentException("Content ID cannot be empty");
+ } else
+ {
+ mediaInfo = new MediaInfo(contentId);
+ return;
+ }
+ }
+ }
+
+
+ MediaInfo(String contentId)
+ throws IllegalArgumentException
+ {
+ if(TextUtils.isEmpty(contentId))
+ {
+ throw new IllegalArgumentException("content ID cannot be null or empty");
+ } else
+ {
+ this.contentId = contentId;
+ streamType = -1;
+ duration = -1L;
+ return;
+ }
+ }
+
+ MediaInfo(JSONObject json)
+ throws JSONException
+ {
+ contentId = json.getString("contentId");
+ String s = json.getString("streamType");
+ if("NONE".equals(s))
+ streamType = 0;
+ else
+ if("BUFFERED".equals(s))
+ streamType = 1;
+ else
+ if("LIVE".equals(s))
+ streamType = 2;
+ else
+ streamType = -1;
+ contentType = json.getString("contentType");
+ if(json.has("metadata"))
+ {
+ JSONObject jsonobject = json.getJSONObject("metadata");
+ int i = jsonobject.getInt("metadataType");
+ mediaMetadata = new MediaMetadata(i);
+ mediaMetadata.zzd(jsonobject);
+ }
+ duration = -1L;
+ if(json.has("duration") && !json.isNull("duration"))
+ {
+ double d = json.optDouble("duration", 0.0D);
+ if(!Double.isNaN(d) && !Double.isInfinite(d))
+ duration = secondsToMillis(d);
+ }
+ if(json.has("tracks"))
+ {
+ mediaTracks = new ArrayList<>();
+ JSONArray jsonarray = json.getJSONArray("tracks");
+ for(int j = 0; j < jsonarray.length(); j++)
+ {
+ JSONObject jsonobject2 = jsonarray.getJSONObject(j);
+ MediaTrack mediatrack = new MediaTrack(jsonobject2);
+ mediaTracks.add(mediatrack);
+ }
+
+ } else
+ {
+ mediaTracks = null;
+ }
+ if(json.has("textTrackStyle"))
+ {
+ JSONObject jsonobject1 = json.getJSONObject("textTrackStyle");
+ TextTrackStyle texttrackstyle = new TextTrackStyle();
+ texttrackstyle.zzd(jsonobject1);
+ textTrackStyle = texttrackstyle;
+ } else
+ {
+ textTrackStyle = null;
+ }
+ customData = json.optJSONObject("customData");
+ }
+
+ public String getContentId()
+ {
+ return contentId;
+ }
+
+ void setStreamType(int streamType)
+ throws IllegalArgumentException
+ {
+ if(streamType < -1 || streamType > 2)
+ {
+ throw new IllegalArgumentException("invalid stream type");
+ } else
+ {
+ this.streamType = streamType;
+ return;
+ }
+ }
+
+ public int getStreamType()
+ {
+ return streamType;
+ }
+
+ void setContentType(String contentType)
+ throws IllegalArgumentException
+ {
+ if(TextUtils.isEmpty(contentType))
+ {
+ throw new IllegalArgumentException("content type cannot be null or empty");
+ } else
+ {
+ this.contentType = contentType;
+ return;
+ }
+ }
+
+ public String getContentType()
+ {
+ return contentType;
+ }
+
+ void zza(MediaMetadata mediametadata)
+ {
+ mediaMetadata = mediametadata;
+ }
+
+ public MediaMetadata getMetadata()
+ {
+ return mediaMetadata;
+ }
+
+ void zzm(long l)
+ throws IllegalArgumentException
+ {
+ if(l < 0L && l != -1L)
+ {
+ throw new IllegalArgumentException("Invalid stream duration");
+ } else
+ {
+ duration = l;
+ return;
+ }
+ }
+
+ public long getStreamDuration()
+ {
+ return duration;
+ }
+
+ void zzg(List list)
+ {
+ mediaTracks = list;
+ }
+
+ public List getMediaTracks()
+ {
+ return mediaTracks;
+ }
+
+ public void setTextTrackStyle(TextTrackStyle textTrackStyle)
+ {
+ this.textTrackStyle = textTrackStyle;
+ }
+
+ public TextTrackStyle getTextTrackStyle()
+ {
+ return textTrackStyle;
+ }
+
+ void setCustomData(JSONObject customData)
+ {
+ this.customData = customData;
+ }
+
+ public JSONObject getCustomData()
+ {
+ return customData;
+ }
+
+ void zzhi()
+ throws IllegalArgumentException
+ {
+ if(TextUtils.isEmpty(contentId))
+ throw new IllegalArgumentException("content ID cannot be null or empty");
+ if(TextUtils.isEmpty(contentType))
+ throw new IllegalArgumentException("content type cannot be null or empty");
+ if(streamType == -1)
+ throw new IllegalArgumentException("a valid stream type must be specified");
+ else
+ return;
+ }
+
+ public JSONObject toJson()
+ {
+ JSONObject jsonobject = new JSONObject();
+ try
+ {
+ jsonobject.put("contentId", contentId);
+ String s;
+ switch(streamType)
+ {
+ case 1: // '\001'
+ s = "BUFFERED";
+ break;
+
+ case 2: // '\002'
+ s = "LIVE";
+ break;
+
+ case 0: // '\0'
+ default:
+ s = "NONE";
+ break;
+ }
+ jsonobject.put("streamType", s);
+ if(contentType != null)
+ jsonobject.put("contentType", contentType);
+ if(mediaMetadata != null)
+ jsonobject.put("metadata", mediaMetadata.toJson());
+ if(duration <= -1L)
+ jsonobject.put("duration", JSONObject.NULL);
+ else
+ jsonobject.put("duration", millisToSeconds(duration));
+ if(mediaTracks != null)
+ {
+ JSONArray jsonarray = new JSONArray();
+ for(MediaTrack mediaTrack : mediaTracks)
+ jsonarray.put(mediaTrack.toJson());
+ jsonobject.put("tracks", jsonarray);
+ }
+ if(textTrackStyle != null)
+ jsonobject.put("textTrackStyle", textTrackStyle.toJson());
+ if(customData != null)
+ jsonobject.put("customData", customData);
+ }
+ catch(JSONException jsonexception) { }
+ return jsonobject;
+ }
+
+ public boolean equals(Object other)
+ {
+ if(this == other)
+ return true;
+ if(!(other instanceof MediaInfo))
+ return false;
+ MediaInfo mediainfo = (MediaInfo)other;
+ if((customData == null) != (mediainfo.customData == null))
+ return false;
+ if(customData != null && mediainfo.customData != null && !Objects.jsonEquals(customData, mediainfo.customData))
+ return false;
+ else
+ return Objects.equals(contentId, mediainfo.contentId) && streamType == mediainfo.streamType && Objects.equals(contentType, mediainfo.contentType) && Objects.equals(mediaMetadata, mediainfo.mediaMetadata) && duration == mediainfo.duration;
+ }
+
+ public int hashCode()
+ {
+ return Objects.hash(contentId, streamType, contentType, mediaMetadata, duration, String.valueOf(customData));
+ }
+
+ static long secondsToMillis(double seconds) {
+ return (long)(seconds * 1000.0D);
+ }
+
+ static double millisToSeconds(long millis) {
+ return (double)millis / 1000.0D;
+ }
+
+ public static final int STREAM_TYPE_NONE = 0;
+ public static final int STREAM_TYPE_BUFFERED = 1;
+ public static final int STREAM_TYPE_LIVE = 2;
+ public static final int STREAM_TYPE_INVALID = -1;
+ public static final long UNKNOWN_DURATION = -1L;
+ private final String contentId;
+ private int streamType;
+ private String contentType;
+ private MediaMetadata mediaMetadata;
+ private long duration;
+ private List mediaTracks;
+ private TextTrackStyle textTrackStyle;
+ private JSONObject customData;
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/MediaMetadata.java b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaMetadata.java
new file mode 100644
index 0000000..6dcafc7
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaMetadata.java
@@ -0,0 +1,534 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.google.android.gms.cast;
+
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.util.Log;
+import com.google.android.gms.common.images.WebImage;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class MediaMetadata {
+ public static final int MEDIA_TYPE_GENERIC = 0;
+ public static final int MEDIA_TYPE_MOVIE = 1;
+ public static final int MEDIA_TYPE_TV_SHOW = 2;
+ public static final int MEDIA_TYPE_MUSIC_TRACK = 3;
+ public static final int MEDIA_TYPE_PHOTO = 4;
+ public static final int MEDIA_TYPE_USER = 100;
+
+ public static final String KEY_CREATION_DATE = "com.google.android.gms.cast.metadata.CREATION_DATE";
+ public static final String KEY_RELEASE_DATE = "com.google.android.gms.cast.metadata.RELEASE_DATE";
+ public static final String KEY_BROADCAST_DATE = "com.google.android.gms.cast.metadata.BROADCAST_DATE";
+ public static final String KEY_TITLE = "com.google.android.gms.cast.metadata.TITLE";
+ public static final String KEY_SUBTITLE = "com.google.android.gms.cast.metadata.SUBTITLE";
+ public static final String KEY_ARTIST = "com.google.android.gms.cast.metadata.ARTIST";
+ public static final String KEY_ALBUM_ARTIST = "com.google.android.gms.cast.metadata.ALBUM_ARTIST";
+ public static final String KEY_ALBUM_TITLE = "com.google.android.gms.cast.metadata.ALBUM_TITLE";
+ public static final String KEY_COMPOSER = "com.google.android.gms.cast.metadata.COMPOSER";
+ public static final String KEY_DISC_NUMBER = "com.google.android.gms.cast.metadata.DISC_NUMBER";
+ public static final String KEY_TRACK_NUMBER = "com.google.android.gms.cast.metadata.TRACK_NUMBER";
+ public static final String KEY_SEASON_NUMBER = "com.google.android.gms.cast.metadata.SEASON_NUMBER";
+ public static final String KEY_EPISODE_NUMBER = "com.google.android.gms.cast.metadata.EPISODE_NUMBER";
+ public static final String KEY_SERIES_TITLE = "com.google.android.gms.cast.metadata.SERIES_TITLE";
+ public static final String KEY_STUDIO = "com.google.android.gms.cast.metadata.STUDIO";
+ public static final String KEY_WIDTH = "com.google.android.gms.cast.metadata.WIDTH";
+ public static final String KEY_HEIGHT = "com.google.android.gms.cast.metadata.HEIGHT";
+ public static final String KEY_LOCATION_NAME = "com.google.android.gms.cast.metadata.LOCATION_NAME";
+ public static final String KEY_LOCATION_LATITUDE = "com.google.android.gms.cast.metadata.LOCATION_LATITUDE";
+ public static final String KEY_LOCATION_LONGITUDE = "com.google.android.gms.cast.metadata.LOCATION_LONGITUDE";
+
+ private static final String[] zzIZ = new String[]{null, "String", "int", "double", "ISO-8601 date String"};
+
+ private static final MediaMetadata.zza zzJa = (new MediaMetadata.zza()).zzb("com.google.android.gms.cast.metadata.CREATION_DATE", "creationDateTime", 4).zzb("com.google.android.gms.cast.metadata.RELEASE_DATE", "releaseDate", 4).zzb("com.google.android.gms.cast.metadata.BROADCAST_DATE", "originalAirdate", 4).zzb("com.google.android.gms.cast.metadata.TITLE", "title", 1).zzb("com.google.android.gms.cast.metadata.SUBTITLE", "subtitle", 1).zzb("com.google.android.gms.cast.metadata.ARTIST", "artist", 1).zzb("com.google.android.gms.cast.metadata.ALBUM_ARTIST", "albumArtist", 1).zzb("com.google.android.gms.cast.metadata.ALBUM_TITLE", "albumName", 1).zzb("com.google.android.gms.cast.metadata.COMPOSER", "composer", 1).zzb("com.google.android.gms.cast.metadata.DISC_NUMBER", "discNumber", 2).zzb("com.google.android.gms.cast.metadata.TRACK_NUMBER", "trackNumber", 2).zzb("com.google.android.gms.cast.metadata.SEASON_NUMBER", "season", 2).zzb("com.google.android.gms.cast.metadata.EPISODE_NUMBER", "episode", 2).zzb("com.google.android.gms.cast.metadata.SERIES_TITLE", "seriesTitle", 1).zzb("com.google.android.gms.cast.metadata.STUDIO", "studio", 1).zzb("com.google.android.gms.cast.metadata.WIDTH", "width", 2).zzb("com.google.android.gms.cast.metadata.HEIGHT", "height", 2).zzb("com.google.android.gms.cast.metadata.LOCATION_NAME", "location", 1).zzb("com.google.android.gms.cast.metadata.LOCATION_LATITUDE", "latitude", 3).zzb("com.google.android.gms.cast.metadata.LOCATION_LONGITUDE", "longitude", 3);
+
+ private final List images;
+ private final Bundle bundle;
+ private int mediaType;
+
+ public MediaMetadata() {
+ this(0);
+ }
+
+ public MediaMetadata(int mediaType) {
+ this.images = new ArrayList<>();
+ this.bundle = new Bundle();
+ this.mediaType = mediaType;
+ }
+
+ public int getMediaType() {
+ return this.mediaType;
+ }
+
+ public void clear() {
+ this.bundle.clear();
+ this.images.clear();
+ }
+
+ public boolean containsKey(String key) {
+ return this.bundle.containsKey(key);
+ }
+
+ public Set keySet() {
+ return this.bundle.keySet();
+ }
+
+ public void putString(String key, String value) {
+ this.zzf(key, 1);
+ this.bundle.putString(key, value);
+ }
+
+ public String getString(String key) {
+ this.zzf(key, 1);
+ return this.bundle.getString(key);
+ }
+
+ public void putInt(String key, int value) {
+ this.zzf(key, 2);
+ this.bundle.putInt(key, value);
+ }
+
+ public int getInt(String key) {
+ this.zzf(key, 2);
+ return this.bundle.getInt(key);
+ }
+
+ public void putDouble(String key, double value) {
+ this.zzf(key, 3);
+ this.bundle.putDouble(key, value);
+ }
+
+ public double getDouble(String key) {
+ this.zzf(key, 3);
+ return this.bundle.getDouble(key);
+ }
+
+ public void putDate(String key, Calendar value) {
+ this.zzf(key, 4);
+ this.bundle.putString(key, serializeCalendar(value));
+ }
+
+ public Calendar getDate(String key) {
+ this.zzf(key, 4);
+ String var2 = this.bundle.getString(key);
+ return var2 != null?parseCalendar(var2):null;
+ }
+
+ public String getDateAsString(String key) {
+ this.zzf(key, 4);
+ return this.bundle.getString(key);
+ }
+
+ private void zzf(String var1, int var2) throws IllegalArgumentException {
+ if(TextUtils.isEmpty(var1)) {
+ throw new IllegalArgumentException("null and empty keys are not allowed");
+ } else {
+ int var3 = zzJa.zzaG(var1);
+ if(var3 != var2 && var3 != 0) {
+ throw new IllegalArgumentException("Value for " + var1 + " must be a " + zzIZ[var2]);
+ }
+ }
+ }
+
+ public JSONObject toJson() {
+ JSONObject var1 = new JSONObject();
+
+ try {
+ var1.put("metadataType", this.mediaType);
+ } catch (JSONException var3) {
+ ;
+ }
+
+ WebImage.writeToJson(var1, this.images);
+ switch(this.mediaType) {
+ case 0:
+ this.zza(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.ARTIST", "com.google.android.gms.cast.metadata.SUBTITLE", "com.google.android.gms.cast.metadata.RELEASE_DATE"});
+ break;
+ case 1:
+ this.zza(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.STUDIO", "com.google.android.gms.cast.metadata.SUBTITLE", "com.google.android.gms.cast.metadata.RELEASE_DATE"});
+ break;
+ case 2:
+ this.zza(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.SERIES_TITLE", "com.google.android.gms.cast.metadata.SEASON_NUMBER", "com.google.android.gms.cast.metadata.EPISODE_NUMBER", "com.google.android.gms.cast.metadata.BROADCAST_DATE"});
+ break;
+ case 3:
+ this.zza(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.ARTIST", "com.google.android.gms.cast.metadata.ALBUM_TITLE", "com.google.android.gms.cast.metadata.ALBUM_ARTIST", "com.google.android.gms.cast.metadata.COMPOSER", "com.google.android.gms.cast.metadata.TRACK_NUMBER", "com.google.android.gms.cast.metadata.DISC_NUMBER", "com.google.android.gms.cast.metadata.RELEASE_DATE"});
+ break;
+ case 4:
+ this.zza(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.ARTIST", "com.google.android.gms.cast.metadata.LOCATION_NAME", "com.google.android.gms.cast.metadata.LOCATION_LATITUDE", "com.google.android.gms.cast.metadata.LOCATION_LONGITUDE", "com.google.android.gms.cast.metadata.WIDTH", "com.google.android.gms.cast.metadata.HEIGHT", "com.google.android.gms.cast.metadata.CREATION_DATE"});
+ break;
+ default:
+ this.zza(var1, new String[0]);
+ }
+
+ return var1;
+ }
+
+ public void zzd(JSONObject var1) {
+ this.clear();
+ this.mediaType = 0;
+
+ try {
+ this.mediaType = var1.getInt("metadataType");
+ } catch (JSONException var3) {
+ ;
+ }
+
+ WebImage.parseFromJson(this.images, var1);
+ switch(this.mediaType) {
+ case 0:
+ this.zzb(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.ARTIST", "com.google.android.gms.cast.metadata.SUBTITLE", "com.google.android.gms.cast.metadata.RELEASE_DATE"});
+ break;
+ case 1:
+ this.zzb(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.STUDIO", "com.google.android.gms.cast.metadata.SUBTITLE", "com.google.android.gms.cast.metadata.RELEASE_DATE"});
+ break;
+ case 2:
+ this.zzb(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.SERIES_TITLE", "com.google.android.gms.cast.metadata.SEASON_NUMBER", "com.google.android.gms.cast.metadata.EPISODE_NUMBER", "com.google.android.gms.cast.metadata.BROADCAST_DATE"});
+ break;
+ case 3:
+ this.zzb(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.ALBUM_TITLE", "com.google.android.gms.cast.metadata.ARTIST", "com.google.android.gms.cast.metadata.ALBUM_ARTIST", "com.google.android.gms.cast.metadata.COMPOSER", "com.google.android.gms.cast.metadata.TRACK_NUMBER", "com.google.android.gms.cast.metadata.DISC_NUMBER", "com.google.android.gms.cast.metadata.RELEASE_DATE"});
+ break;
+ case 4:
+ this.zzb(var1, new String[]{"com.google.android.gms.cast.metadata.TITLE", "com.google.android.gms.cast.metadata.ARTIST", "com.google.android.gms.cast.metadata.LOCATION_NAME", "com.google.android.gms.cast.metadata.LOCATION_LATITUDE", "com.google.android.gms.cast.metadata.LOCATION_LONGITUDE", "com.google.android.gms.cast.metadata.WIDTH", "com.google.android.gms.cast.metadata.HEIGHT", "com.google.android.gms.cast.metadata.CREATION_DATE"});
+ break;
+ default:
+ this.zzb(var1, new String[0]);
+ }
+
+ }
+
+ private void zza(JSONObject var1, String... var2) {
+ try {
+ String[] var3 = var2;
+ int var4 = var2.length;
+
+ for(int var5 = 0; var5 < var4; ++var5) {
+ String var6 = var3[var5];
+ if(this.bundle.containsKey(var6)) {
+ int var7 = zzJa.zzaG(var6);
+ switch(var7) {
+ case 1:
+ case 4:
+ var1.put(zzJa.zzaE(var6), this.bundle.getString(var6));
+ break;
+ case 2:
+ var1.put(zzJa.zzaE(var6), this.bundle.getInt(var6));
+ break;
+ case 3:
+ var1.put(zzJa.zzaE(var6), this.bundle.getDouble(var6));
+ }
+ }
+ }
+
+ Iterator var9 = this.bundle.keySet().iterator();
+
+ while(var9.hasNext()) {
+ String var10 = (String)var9.next();
+ if(!var10.startsWith("com.google.")) {
+ Object var11 = this.bundle.get(var10);
+ if(var11 instanceof String) {
+ var1.put(var10, var11);
+ } else if(var11 instanceof Integer) {
+ var1.put(var10, var11);
+ } else if(var11 instanceof Double) {
+ var1.put(var10, var11);
+ }
+ }
+ }
+ } catch (JSONException var8) {
+ ;
+ }
+
+ }
+
+ private void zzb(JSONObject var1, String... var2) {
+ HashSet var3 = new HashSet(Arrays.asList(var2));
+
+ try {
+ Iterator var4 = var1.keys();
+
+ while(var4.hasNext()) {
+ String var5 = (String)var4.next();
+ if(!"metadataType".equals(var5)) {
+ String var6 = zzJa.zzaF(var5);
+ Object var7;
+ if(var6 != null) {
+ if(var3.contains(var6)) {
+ try {
+ var7 = var1.get(var5);
+ if(var7 != null) {
+ switch(zzJa.zzaG(var6)) {
+ case 1:
+ if(var7 instanceof String) {
+ this.bundle.putString(var6, (String) var7);
+ }
+ break;
+ case 2:
+ if(var7 instanceof Integer) {
+ this.bundle.putInt(var6, ((Integer) var7).intValue());
+ }
+ break;
+ case 3:
+ if(var7 instanceof Double) {
+ this.bundle.putDouble(var6, ((Double) var7).doubleValue());
+ }
+ break;
+ case 4:
+ if(var7 instanceof String) {
+ Calendar var8 = parseCalendar((String) var7);
+ if(var8 != null) {
+ this.bundle.putString(var6, (String) var7);
+ }
+ }
+ }
+ }
+ } catch (JSONException var9) {
+ ;
+ }
+ }
+ } else {
+ var7 = var1.get(var5);
+ if(var7 instanceof String) {
+ this.bundle.putString(var5, (String) var7);
+ } else if(var7 instanceof Integer) {
+ this.bundle.putInt(var5, ((Integer) var7).intValue());
+ } else if(var7 instanceof Double) {
+ this.bundle.putDouble(var5, ((Double) var7).doubleValue());
+ }
+ }
+ }
+ }
+ } catch (JSONException var10) {
+ ;
+ }
+
+ }
+
+ public boolean equals(Object other) {
+ if(this == other) {
+ return true;
+ } else if(!(other instanceof MediaMetadata)) {
+ return false;
+ } else {
+ MediaMetadata var2 = (MediaMetadata)other;
+ return this.zza(this.bundle, var2.bundle) && this.images.equals(var2.images);
+ }
+ }
+
+ public int hashCode() {
+ int var1 = 17;
+ Set var2 = this.bundle.keySet();
+
+ String var4;
+ for(Iterator var3 = var2.iterator(); var3.hasNext(); var1 = 31 * var1 + this.bundle.get(var4).hashCode()) {
+ var4 = (String)var3.next();
+ }
+
+ var1 = 31 * var1 + this.images.hashCode();
+ return var1;
+ }
+
+ public List getImages() {
+ return this.images;
+ }
+
+ public boolean hasImages() {
+ return this.images != null && !this.images.isEmpty();
+ }
+
+ public void clearImages() {
+ this.images.clear();
+ }
+
+ public void addImage(WebImage image) {
+ this.images.add(image);
+ }
+
+ private boolean zza(Bundle var1, Bundle var2) {
+ if(var1.size() != var2.size()) {
+ return false;
+ } else {
+ Set var3 = var1.keySet();
+ Iterator var6 = var3.iterator();
+
+ Object var5;
+ String var7;
+ label38:
+ do {
+ Object var4;
+ do {
+ if(!var6.hasNext()) {
+ return true;
+ }
+
+ var7 = (String)var6.next();
+ var4 = var1.get(var7);
+ var5 = var2.get(var7);
+ if(var4 instanceof Bundle && var5 instanceof Bundle && !this.zza((Bundle)var4, (Bundle)var5)) {
+ return false;
+ }
+
+ if(var4 == null) {
+ continue label38;
+ }
+ } while(var4.equals(var5));
+
+ return false;
+ } while(var5 == null && var2.containsKey(var7));
+
+ return false;
+ }
+ }
+
+ private static class zza {
+ private final Map zzJd = new HashMap();
+ private final Map zzJe = new HashMap();
+ private final Map zzJf = new HashMap();
+
+ public zza() {
+ }
+
+ public MediaMetadata.zza zzb(String var1, String var2, int var3) {
+ this.zzJd.put(var1, var2);
+ this.zzJe.put(var2, var1);
+ this.zzJf.put(var1, Integer.valueOf(var3));
+ return this;
+ }
+
+ public String zzaE(String var1) {
+ return (String)this.zzJd.get(var1);
+ }
+
+ public String zzaF(String var1) {
+ return (String)this.zzJe.get(var1);
+ }
+
+ public int zzaG(String var1) {
+ Integer var2 = (Integer)this.zzJf.get(var1);
+ return var2 != null?var2.intValue():0;
+ }
+ }
+
+ static String serializeCalendar(Calendar var0) {
+ if(var0 == null) {
+ Log.d("MetadataUtils", "Calendar object cannot be null");
+ return null;
+ } else {
+ String dateFormat = "yyyyMMdd\'T\'HHmmssZ";
+ if(var0.get(Calendar.HOUR_OF_DAY) == 0 && var0.get(Calendar.MINUTE) == 0 && var0.get(Calendar.SECOND) == 0) {
+ dateFormat = "yyyyMMdd";
+ }
+
+ SimpleDateFormat var2 = new SimpleDateFormat(dateFormat);
+ var2.setTimeZone(var0.getTimeZone());
+ String var3 = var2.format(var0.getTime());
+ if(var3.endsWith("+0000")) {
+ var3 = var3.replace("+0000", "Z");
+ }
+
+ return var3;
+ }
+ }
+
+ static Calendar parseCalendar(String date) {
+ if(TextUtils.isEmpty(date)) {
+ Log.d("MetadataUtils", "Input string is empty or null");
+ return null;
+ } else {
+ String var1 = parseDatePart(date);
+ if(TextUtils.isEmpty(var1)) {
+ Log.d("MetadataUtils", "Invalid date format");
+ return null;
+ } else {
+ String var2 = parseTimePart(date);
+ String dateFormat = "yyyyMMdd";
+ if(!TextUtils.isEmpty(var2)) {
+ var1 = var1 + "T" + var2;
+ if(var2.length() == "HHmmss".length()) {
+ dateFormat = "yyyyMMdd\'T\'HHmmss";
+ } else {
+ dateFormat = "yyyyMMdd\'T\'HHmmssZ";
+ }
+ }
+
+ Calendar var4 = GregorianCalendar.getInstance();
+
+ Date var5;
+ try {
+ var5 = (new SimpleDateFormat(dateFormat)).parse(var1);
+ } catch (ParseException var7) {
+ Log.d("MetadataUtils", String.format("Error parsing string: %s", var7.getMessage()));
+ return null;
+ }
+
+ var4.setTime(var5);
+ return var4;
+ }
+ }
+ }
+
+ private static String parseDatePart(String var0) {
+ if(TextUtils.isEmpty(var0)) {
+ Log.d("MetadataUtils", "Input string is empty or null");
+ return null;
+ } else {
+ try {
+ return var0.substring(0, "yyyyMMdd".length());
+ } catch (IndexOutOfBoundsException var2) {
+ Log.i("MetadataUtils", String.format("Error extracting the date: %s", var2.getMessage()));
+ return null;
+ }
+ }
+ }
+
+ private static String parseTimePart(String var0) {
+ if(TextUtils.isEmpty(var0)) {
+ Log.d("MetadataUtils", "string is empty or null");
+ return null;
+ } else {
+ int var1 = var0.indexOf(84);
+ if(var1++ != "yyyyMMdd".length()) {
+ Log.d("MetadataUtils", "T delimeter is not found");
+ return null;
+ } else {
+ String var2;
+ try {
+ var2 = var0.substring(var1);
+ } catch (IndexOutOfBoundsException var4) {
+ Log.d("MetadataUtils", String.format("Error extracting the time substring: %s", var4.getMessage()));
+ return null;
+ }
+
+ if(var2.length() == "HHmmss".length()) {
+ return var2;
+ } else {
+ char var3 = var2.charAt("HHmmss".length());
+ switch(var3) {
+ case '+':
+ case '-':
+ if(whichTimePart(var2)) {
+ return var2.replaceAll("([\\+\\-]\\d\\d):(\\d\\d)", "$1$2");
+ }
+ default:
+ return null;
+ case 'Z':
+ return var2.length() == "HHmmssZ".length() ?var2.substring(0, var2.length() - 1) + "+0000":null;
+ }
+ }
+ }
+ }
+ }
+
+ private static boolean whichTimePart(String var0) {
+ int var1 = var0.length();
+ int var2 = "HHmmss".length();
+ return var1 == var2 + "+hh".length() || var1 == var2 + "+hhmm".length() || var1 == var2 + "+hh:mm".length();
+ }
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/MediaStatus.java b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaStatus.java
new file mode 100644
index 0000000..41baa81
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaStatus.java
@@ -0,0 +1,258 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import org.json.*;
+
+// Referenced classes of package com.google.android.gms.cast:
+// MediaInfo
+
+public final class MediaStatus
+{
+ MediaStatus(MediaInfo mediaInfo) {
+ this.mediaInfo = mediaInfo;
+ }
+
+ public MediaStatus(JSONObject json)
+ throws JSONException
+ {
+ parseJson(json, 0);
+ }
+
+ public long getMediaSessionId()
+ {
+ return mediaSessionId;
+ }
+
+ public int getPlayerState()
+ {
+ return playerState;
+ }
+
+ public int getIdleReason()
+ {
+ return idleReason;
+ }
+
+ public double getPlaybackRate()
+ {
+ return playbackRate;
+ }
+
+ public MediaInfo getMediaInfo()
+ {
+ return mediaInfo;
+ }
+
+ public long getStreamPosition()
+ {
+ return streamPosition;
+ }
+
+ public boolean isMediaCommandSupported(long mediaCommand)
+ {
+ return (supportedMediaCommands & mediaCommand) != 0L;
+ }
+
+ public double getStreamVolume()
+ {
+ return streamVolume;
+ }
+
+ public boolean isMute()
+ {
+ return mute;
+ }
+
+ public long[] getActiveTrackIds()
+ {
+ return activeTrackIds;
+ }
+
+ public JSONObject getCustomData()
+ {
+ return customData;
+ }
+
+ private int parseJson(JSONObject jsonobject, int i)
+ throws JSONException
+ {
+ int j = 0;
+ long l = jsonobject.getLong("mediaSessionId");
+ if(l != mediaSessionId)
+ {
+ mediaSessionId = l;
+ j |= 1;
+ }
+ if(jsonobject.has("playerState"))
+ {
+ int k = 0;
+ String s = jsonobject.getString("playerState");
+ if(s.equals("IDLE"))
+ k = 1;
+ else
+ if(s.equals("PLAYING"))
+ k = 2;
+ else
+ if(s.equals("PAUSED"))
+ k = 3;
+ else
+ if(s.equals("BUFFERING"))
+ k = 4;
+ if(k != playerState)
+ {
+ playerState = k;
+ j |= 2;
+ }
+ if(k == 1 && jsonobject.has("idleReason"))
+ {
+ int i1 = 0;
+ String s1 = jsonobject.getString("idleReason");
+ if(s1.equals("CANCELLED"))
+ i1 = 2;
+ else
+ if(s1.equals("INTERRUPTED"))
+ i1 = 3;
+ else
+ if(s1.equals("FINISHED"))
+ i1 = 1;
+ else
+ if(s1.equals("ERROR"))
+ i1 = 4;
+ if(i1 != idleReason)
+ {
+ idleReason = i1;
+ j |= 2;
+ }
+ }
+ }
+ if(jsonobject.has("playbackRate"))
+ {
+ double d = jsonobject.getDouble("playbackRate");
+ if(playbackRate != d)
+ {
+ playbackRate = d;
+ j |= 2;
+ }
+ }
+ if(jsonobject.has("currentTime") && (i & 2) == 0)
+ {
+ long l1 = MediaInfo.secondsToMillis(jsonobject.getDouble("currentTime"));
+ if(l1 != streamPosition)
+ {
+ streamPosition = l1;
+ j |= 2;
+ }
+ }
+ if(jsonobject.has("supportedMediaCommands"))
+ {
+ long l2 = jsonobject.getLong("supportedMediaCommands");
+ if(l2 != supportedMediaCommands)
+ {
+ supportedMediaCommands = l2;
+ j |= 2;
+ }
+ }
+ if(jsonobject.has("volume") && (i & 1) == 0)
+ {
+ JSONObject jsonobject1 = jsonobject.getJSONObject("volume");
+ double d1 = jsonobject1.getDouble("level");
+ if(d1 != streamVolume)
+ {
+ streamVolume = d1;
+ j |= 2;
+ }
+ boolean flag1 = jsonobject1.getBoolean("muted");
+ if(flag1 != mute)
+ {
+ mute = flag1;
+ j |= 2;
+ }
+ }
+ boolean flag = false;
+ long al[] = null;
+ if(jsonobject.has("activeTrackIds"))
+ {
+ JSONArray jsonarray = jsonobject.getJSONArray("activeTrackIds");
+ int j1 = jsonarray.length();
+ al = new long[j1];
+ for(int k1 = 0; k1 < j1; k1++)
+ al[k1] = jsonarray.getLong(k1);
+
+ if(activeTrackIds == null)
+ flag = true;
+ else
+ if(activeTrackIds.length != j1)
+ {
+ flag = true;
+ } else
+ {
+ int i2 = 0;
+ do
+ {
+ if(i2 >= j1)
+ break;
+ if(activeTrackIds[i2] != al[i2])
+ {
+ flag = true;
+ break;
+ }
+ i2++;
+ } while(true);
+ }
+ if(flag)
+ activeTrackIds = al;
+ } else
+ if(activeTrackIds != null)
+ flag = true;
+ if(flag)
+ {
+ activeTrackIds = al;
+ j |= 2;
+ }
+ if(jsonobject.has("customData"))
+ {
+ customData = jsonobject.getJSONObject("customData");
+ j |= 2;
+ }
+ if(jsonobject.has("media"))
+ {
+ JSONObject jsonobject2 = jsonobject.getJSONObject("media");
+ mediaInfo = new MediaInfo(jsonobject2);
+ j |= 2;
+ if(jsonobject2.has("metadata"))
+ j |= 4;
+ }
+ return j;
+ }
+
+ public static final long COMMAND_PAUSE = 1L;
+ public static final long COMMAND_SEEK = 2L;
+ public static final long COMMAND_SET_VOLUME = 4L;
+ public static final long COMMAND_TOGGLE_MUTE = 8L;
+ public static final long COMMAND_SKIP_FORWARD = 16L;
+ public static final long COMMAND_SKIP_BACKWARD = 32L;
+ public static final int PLAYER_STATE_UNKNOWN = 0;
+ public static final int PLAYER_STATE_IDLE = 1;
+ public static final int PLAYER_STATE_PLAYING = 2;
+ public static final int PLAYER_STATE_PAUSED = 3;
+ public static final int PLAYER_STATE_BUFFERING = 4;
+ public static final int IDLE_REASON_NONE = 0;
+ public static final int IDLE_REASON_FINISHED = 1;
+ public static final int IDLE_REASON_CANCELED = 2;
+ public static final int IDLE_REASON_INTERRUPTED = 3;
+ public static final int IDLE_REASON_ERROR = 4;
+ private long mediaSessionId;
+ private MediaInfo mediaInfo;
+ private double playbackRate;
+ private int playerState;
+ private int idleReason;
+ private long streamPosition;
+ private long supportedMediaCommands;
+ private double streamVolume;
+ private boolean mute;
+ private long activeTrackIds[];
+ private JSONObject customData;
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/MediaTrack.java b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaTrack.java
new file mode 100644
index 0000000..1759165
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/MediaTrack.java
@@ -0,0 +1,330 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import android.text.TextUtils;
+import java.util.Locale;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.microg.gms.common.Objects;
+
+public final class MediaTrack
+{
+ public static class Builder
+ {
+
+ public Builder setContentId(String contentId)
+ {
+ zzJr.setContentId(contentId);
+ return this;
+ }
+
+ public Builder setContentType(String contentType)
+ {
+ zzJr.setContentType(contentType);
+ return this;
+ }
+
+ public Builder setName(String trackName)
+ {
+ zzJr.setName(trackName);
+ return this;
+ }
+
+ public Builder setLanguage(String language)
+ {
+ zzJr.setLanguage(language);
+ return this;
+ }
+
+ public Builder setLanguage(Locale locale)
+ {
+ zzJr.setLanguage(CastMediaControlIntent.languageTagForLocale(locale));
+ return this;
+ }
+
+ public Builder setSubtype(int subtype)
+ throws IllegalArgumentException
+ {
+ zzJr.zzaf(subtype);
+ return this;
+ }
+
+ public Builder setCustomData(JSONObject customData)
+ {
+ zzJr.setCustomData(customData);
+ return this;
+ }
+
+ public MediaTrack build()
+ {
+ return zzJr;
+ }
+
+ private final MediaTrack zzJr;
+
+ public Builder(long trackId, int trackType)
+ throws IllegalArgumentException
+ {
+ zzJr = new MediaTrack(trackId, trackType);
+ }
+ }
+
+
+ MediaTrack(JSONObject json)
+ throws JSONException
+ {
+ zzd(json);
+ }
+
+ MediaTrack(long id, int type)
+ throws IllegalArgumentException
+ {
+ clear();
+ this.id = id;
+ if(type <= 0 || type > 3)
+ {
+ throw new IllegalArgumentException((new StringBuilder()).append("invalid type ").append(type).toString());
+ } else
+ {
+ this.type = type;
+ return;
+ }
+ }
+
+ public long getId()
+ {
+ return id;
+ }
+
+ public int getType()
+ {
+ return type;
+ }
+
+ public String getContentId()
+ {
+ return contentId;
+ }
+
+ public void setContentId(String contentId)
+ {
+ this.contentId = contentId;
+ }
+
+ public String getContentType()
+ {
+ return contentType;
+ }
+
+ public void setContentType(String contentType)
+ {
+ this.contentType = contentType;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public String getLanguage()
+ {
+ return language;
+ }
+
+ void setLanguage(String language)
+ {
+ this.language = language;
+ }
+
+ public int getSubtype()
+ {
+ return subType;
+ }
+
+ void zzaf(int i)
+ throws IllegalArgumentException
+ {
+ if(i <= -1 || i > 5)
+ throw new IllegalArgumentException((new StringBuilder()).append("invalid subtype ").append(i).toString());
+ if(i != 0 && type != 1)
+ {
+ throw new IllegalArgumentException("subtypes are only valid for text tracks");
+ } else
+ {
+ subType = i;
+ return;
+ }
+ }
+
+ public JSONObject getCustomData()
+ {
+ return customData;
+ }
+
+ void setCustomData(JSONObject customData)
+ {
+ this.customData = customData;
+ }
+
+ private void clear()
+ {
+ id = 0L;
+ type = 0;
+ contentId = null;
+ name = null;
+ language = null;
+ subType = -1;
+ customData = null;
+ }
+
+ private void zzd(JSONObject jsonobject)
+ throws JSONException
+ {
+ clear();
+ id = jsonobject.getLong("trackId");
+ String s = jsonobject.getString("type");
+ if("TEXT".equals(s))
+ type = 1;
+ else
+ if("AUDIO".equals(s))
+ type = 2;
+ else
+ if("VIDEO".equals(s))
+ type = 3;
+ else
+ throw new JSONException((new StringBuilder()).append("invalid type: ").append(s).toString());
+ contentId = jsonobject.optString("trackContentId", null);
+ contentType = jsonobject.optString("trackContentType", null);
+ name = jsonobject.optString("name", null);
+ language = jsonobject.optString("language", null);
+ if(jsonobject.has("subtype"))
+ {
+ String s1 = jsonobject.getString("subtype");
+ if("SUBTITLES".equals(s1))
+ subType = 1;
+ else
+ if("CAPTIONS".equals(s1))
+ subType = 2;
+ else
+ if("DESCRIPTIONS".equals(s1))
+ subType = 3;
+ else
+ if("CHAPTERS".equals(s1))
+ subType = 4;
+ else
+ if("METADATA".equals(s1))
+ subType = 5;
+ else
+ throw new JSONException((new StringBuilder()).append("invalid subtype: ").append(s1).toString());
+ } else
+ {
+ subType = 0;
+ }
+ customData = jsonobject.optJSONObject("customData");
+ }
+
+ public JSONObject toJson()
+ {
+ JSONObject jsonobject = new JSONObject();
+ try
+ {
+ jsonobject.put("trackId", id);
+ switch(type)
+ {
+ case 1: // '\001'
+ jsonobject.put("type", "TEXT");
+ break;
+
+ case 2: // '\002'
+ jsonobject.put("type", "AUDIO");
+ break;
+
+ case 3: // '\003'
+ jsonobject.put("type", "VIDEO");
+ break;
+ }
+ if(contentId != null)
+ jsonobject.put("trackContentId", contentId);
+ if(contentType != null)
+ jsonobject.put("trackContentType", contentType);
+ if(name != null)
+ jsonobject.put("name", name);
+ if(!TextUtils.isEmpty(language))
+ jsonobject.put("language", language);
+ switch(subType)
+ {
+ case 1: // '\001'
+ jsonobject.put("subtype", "SUBTITLES");
+ break;
+
+ case 2: // '\002'
+ jsonobject.put("subtype", "CAPTIONS");
+ break;
+
+ case 3: // '\003'
+ jsonobject.put("subtype", "DESCRIPTIONS");
+ break;
+
+ case 4: // '\004'
+ jsonobject.put("subtype", "CHAPTERS");
+ break;
+
+ case 5: // '\005'
+ jsonobject.put("subtype", "METADATA");
+ break;
+ }
+ if(customData != null)
+ jsonobject.put("customData", customData);
+ }
+ catch(JSONException jsonexception) { }
+ return jsonobject;
+ }
+
+ public boolean equals(Object other)
+ {
+ if(this == other)
+ return true;
+ if(!(other instanceof MediaTrack))
+ return false;
+ MediaTrack mediatrack = (MediaTrack)other;
+ if((customData == null) != (mediatrack.customData == null))
+ return false;
+ if(customData != null && mediatrack.customData != null && !Objects.jsonEquals(customData, mediatrack.customData))
+ return false;
+ else
+ return id == mediatrack.id && type == mediatrack.type && Objects.equals(contentId, mediatrack.contentId) && Objects.equals(contentType, mediatrack.contentType) && Objects.equals(name, mediatrack.name) && Objects.equals(language, mediatrack.language) && subType == mediatrack.subType;
+ }
+
+ public int hashCode()
+ {
+ return Objects.hash(id, type, contentId, contentType, name, language, subType, customData);
+ }
+
+ public static final int TYPE_UNKNOWN = 0;
+ public static final int TYPE_TEXT = 1;
+ public static final int TYPE_AUDIO = 2;
+ public static final int TYPE_VIDEO = 3;
+ public static final int SUBTYPE_UNKNOWN = -1;
+ public static final int SUBTYPE_NONE = 0;
+ public static final int SUBTYPE_SUBTITLES = 1;
+ public static final int SUBTYPE_CAPTIONS = 2;
+ public static final int SUBTYPE_DESCRIPTIONS = 3;
+ public static final int SUBTYPE_CHAPTERS = 4;
+ public static final int SUBTYPE_METADATA = 5;
+ private long id;
+ private int type;
+ private String contentId;
+ private String contentType;
+ private String name;
+ private String language;
+ private int subType;
+ private JSONObject customData;
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/RemoteMediaPlayer.java b/play-services-cast/src/main/java/com/google/android/gms/cast/RemoteMediaPlayer.java
new file mode 100644
index 0000000..48e4b36
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/RemoteMediaPlayer.java
@@ -0,0 +1,228 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by Fernflower decompiler)
+//
+
+package com.google.android.gms.cast;
+
+import com.google.android.gms.cast.Cast.MessageReceivedCallback;
+import com.google.android.gms.common.api.GoogleApiClient;
+import com.google.android.gms.common.api.PendingResult;
+import com.google.android.gms.common.api.Result;
+import com.google.android.gms.common.api.ResultCallback;
+import com.google.android.gms.common.api.Status;
+
+import java.util.concurrent.TimeUnit;
+
+import org.json.JSONObject;
+import org.microg.gms.common.api.DummyPendingResult;
+
+public class RemoteMediaPlayer implements MessageReceivedCallback {
+
+ public static final int RESUME_STATE_UNCHANGED = 0;
+ public static final int RESUME_STATE_PLAY = 1;
+ public static final int RESUME_STATE_PAUSE = 2;
+ public static final int STATUS_SUCCEEDED = 0;
+ public static final int STATUS_FAILED = 2100;
+ public static final int STATUS_CANCELED = 2101;
+ public static final int STATUS_TIMED_OUT = 2102;
+ public static final int STATUS_REPLACED = 2103;
+
+ private final Object lock = new Object();
+
+ private RemoteMediaPlayer.OnMetadataUpdatedListener onMetadataUpdatedListener;
+ private RemoteMediaPlayer.OnStatusUpdatedListener onStatusUpdatedListener;
+ private String namespace = "bla";
+ private MediaStatus mediaStatus = new MediaStatus(new MediaInfo("bla"));
+ private long streamDuration;
+ private long approximateStreamPosition;
+
+ public RemoteMediaPlayer() {
+
+ }
+
+ public PendingResult load(GoogleApiClient apiClient, MediaInfo mediaInfo) {
+ return this.load(apiClient, mediaInfo, true, 0L, (long[])null, (JSONObject)null);
+ }
+
+ public PendingResult load(GoogleApiClient apiClient, MediaInfo mediaInfo, boolean autoplay) {
+ return this.load(apiClient, mediaInfo, autoplay, 0L, (long[])null, (JSONObject)null);
+ }
+
+ public PendingResult load(GoogleApiClient apiClient, MediaInfo mediaInfo, boolean autoplay, long playPosition) {
+ return this.load(apiClient, mediaInfo, autoplay, playPosition, (long[])null, (JSONObject)null);
+ }
+
+ public PendingResult load(GoogleApiClient apiClient, MediaInfo mediaInfo, boolean autoplay, long playPosition, JSONObject customData) {
+ return this.load(apiClient, mediaInfo, autoplay, playPosition, (long[])null, customData);
+ }
+
+ public PendingResult load(final GoogleApiClient apiClient, final MediaInfo mediaInfo, final boolean autoplay, final long playPosition, final long[] activeTrackIds, final JSONObject customData) {
+ return new DummyResult();
+ }
+
+ public PendingResult pause(GoogleApiClient apiClient) {
+ return this.pause(apiClient, (JSONObject)null);
+ }
+
+ public PendingResult pause(final GoogleApiClient apiClient, final JSONObject customData) {
+ return new DummyResult();
+ }
+
+ public PendingResult stop(GoogleApiClient apiClient) {
+ return this.stop(apiClient, (JSONObject)null);
+ }
+
+ public PendingResult stop(final GoogleApiClient apiClient, final JSONObject customData) {
+ return new DummyResult();
+ }
+
+ public PendingResult play(GoogleApiClient apiClient) {
+ return this.play(apiClient, (JSONObject)null);
+ }
+
+ public PendingResult play(final GoogleApiClient apiClient, final JSONObject customData) {
+ return new DummyResult();
+ }
+
+ public PendingResult seek(GoogleApiClient apiClient, long position) {
+ return this.seek(apiClient, position, 0, (JSONObject)null);
+ }
+
+ public PendingResult seek(GoogleApiClient apiClient, long position, int resumeState) {
+ return this.seek(apiClient, position, resumeState, (JSONObject)null);
+ }
+
+ public PendingResult seek(final GoogleApiClient apiClient, final long position, final int resumeState, final JSONObject customData) {
+ return new DummyResult();
+ }
+
+ public PendingResult setStreamVolume(GoogleApiClient apiClient, double volume) throws IllegalArgumentException {
+ return this.setStreamVolume(apiClient, volume, (JSONObject)null);
+ }
+
+ public PendingResult setStreamVolume(final GoogleApiClient apiClient, final double volume, final JSONObject customData) throws IllegalArgumentException {
+ if(!Double.isInfinite(volume) && !Double.isNaN(volume)) {
+ return new DummyResult();
+ } else {
+ throw new IllegalArgumentException("Volume cannot be " + volume);
+ }
+ }
+
+ public PendingResult setStreamMute(GoogleApiClient apiClient, boolean muteState) {
+ return this.setStreamMute(apiClient, muteState, (JSONObject)null);
+ }
+
+ public PendingResult setStreamMute(final GoogleApiClient apiClient, final boolean muteState, final JSONObject customData) {
+ return new DummyResult();
+ }
+
+ public PendingResult requestStatus(final GoogleApiClient apiClient) {
+ return new DummyResult();
+ }
+
+ public PendingResult setActiveMediaTracks(final GoogleApiClient apiClient, final long[] trackIds) {
+ if(trackIds == null) {
+ throw new IllegalArgumentException("trackIds cannot be null");
+ } else {
+ return new DummyResult();
+ }
+ }
+
+ public PendingResult setTextTrackStyle(final GoogleApiClient apiClient, final TextTrackStyle trackStyle) {
+ if(trackStyle == null) {
+ throw new IllegalArgumentException("trackStyle cannot be null");
+ } else {
+ return new DummyResult();
+ }
+ }
+
+ public long getApproximateStreamPosition() {
+ synchronized(this.lock) {
+ return this.approximateStreamPosition;
+ }
+ }
+
+ public long getStreamDuration() {
+ synchronized(this.lock) {
+ return this.streamDuration;
+ }
+ }
+
+ public MediaStatus getMediaStatus() {
+ synchronized(this.lock) {
+ return this.mediaStatus;
+ }
+ }
+
+ public MediaInfo getMediaInfo() {
+ synchronized(this.lock) {
+ return this.mediaStatus.getMediaInfo();
+ }
+ }
+
+ public String getNamespace() {
+ return this.namespace;
+ }
+
+ public void setOnStatusUpdatedListener(RemoteMediaPlayer.OnStatusUpdatedListener listener) {
+ this.onStatusUpdatedListener = listener;
+ }
+
+ private void onStatusUpdated() {
+ if(this.onStatusUpdatedListener != null) {
+ this.onStatusUpdatedListener.onStatusUpdated();
+ }
+
+ }
+
+ public void setOnMetadataUpdatedListener(RemoteMediaPlayer.OnMetadataUpdatedListener listener) {
+ this.onMetadataUpdatedListener = listener;
+ }
+
+ private void onMetadataUpdated() {
+ if(this.onMetadataUpdatedListener != null) {
+ this.onMetadataUpdatedListener.onMetadataUpdated();
+ }
+
+ }
+
+ public void onMessageReceived(CastDevice castDevice, String namespace, String message) {
+
+ }
+
+ private static final class DummyResult extends DummyPendingResult {
+ public DummyResult() {
+ super(new StatusResult(Status.INTERRUPTED)); // always say it's interrupted
+ }
+ }
+
+ private static final class StatusResult implements RemoteMediaPlayer.MediaChannelResult {
+ private final Status status;
+ private final JSONObject customData = new JSONObject();
+
+ StatusResult(Status var1) {
+ this.status = var1;
+ }
+
+ public Status getStatus() {
+ return this.status;
+ }
+
+ public JSONObject getCustomData() {
+ return this.customData;
+ }
+ }
+
+ public interface MediaChannelResult extends Result {
+ JSONObject getCustomData();
+ }
+
+ public interface OnMetadataUpdatedListener {
+ void onMetadataUpdated();
+ }
+
+ public interface OnStatusUpdatedListener {
+ void onStatusUpdated();
+ }
+}
diff --git a/play-services-cast/src/main/java/com/google/android/gms/cast/TextTrackStyle.java b/play-services-cast/src/main/java/com/google/android/gms/cast/TextTrackStyle.java
new file mode 100644
index 0000000..c146e1b
--- /dev/null
+++ b/play-services-cast/src/main/java/com/google/android/gms/cast/TextTrackStyle.java
@@ -0,0 +1,522 @@
+// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.geocities.com/kpdus/jad.html
+// Decompiler options: packimports(3)
+
+package com.google.android.gms.cast;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.os.Build;
+import android.view.accessibility.CaptioningManager;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.microg.gms.common.Objects;
+
+public final class TextTrackStyle
+{
+
+ public TextTrackStyle()
+ {
+ clear();
+ }
+
+ public void setFontScale(float fontScale)
+ {
+ this.fontScale = fontScale;
+ }
+
+ public float getFontScale()
+ {
+ return fontScale;
+ }
+
+ public void setForegroundColor(int foregroundColor)
+ {
+ this.foregroundColor = foregroundColor;
+ }
+
+ public int getForegroundColor()
+ {
+ return foregroundColor;
+ }
+
+ public void setBackgroundColor(int backgroundColor)
+ {
+ this.backgroundColor = backgroundColor;
+ }
+
+ public int getBackgroundColor()
+ {
+ return backgroundColor;
+ }
+
+ public void setEdgeType(int edgeType)
+ {
+ if(edgeType < 0 || edgeType > 4)
+ {
+ throw new IllegalArgumentException("invalid edgeType");
+ } else
+ {
+ this.edgeType = edgeType;
+ return;
+ }
+ }
+
+ public int getEdgeType()
+ {
+ return edgeType;
+ }
+
+ public void setEdgeColor(int edgeColor)
+ {
+ this.edgeColor = edgeColor;
+ }
+
+ public int getEdgeColor()
+ {
+ return edgeColor;
+ }
+
+ public void setWindowType(int windowType)
+ {
+ if(windowType < 0 || windowType > 2)
+ {
+ throw new IllegalArgumentException("invalid windowType");
+ } else
+ {
+ this.windowType = windowType;
+ return;
+ }
+ }
+
+ public int getWindowType()
+ {
+ return windowType;
+ }
+
+ public void setWindowColor(int windowColor)
+ {
+ this.windowColor = windowColor;
+ }
+
+ public int getWindowColor()
+ {
+ return windowColor;
+ }
+
+ public void setWindowCornerRadius(int windowCornerRadius)
+ {
+ if(windowCornerRadius < 0)
+ {
+ throw new IllegalArgumentException("invalid windowCornerRadius");
+ } else
+ {
+ this.windowCornerRadius = windowCornerRadius;
+ return;
+ }
+ }
+
+ public int getWindowCornerRadius()
+ {
+ return windowCornerRadius;
+ }
+
+ public void setFontFamily(String fontFamily)
+ {
+ this.fontFamily = fontFamily;
+ }
+
+ public String getFontFamily()
+ {
+ return fontFamily;
+ }
+
+ public void setFontGenericFamily(int fontGenericFamily)
+ {
+ if(fontGenericFamily < 0 || fontGenericFamily > 6)
+ {
+ throw new IllegalArgumentException("invalid fontGenericFamily");
+ } else
+ {
+ this.fontGenericFamily = fontGenericFamily;
+ return;
+ }
+ }
+
+ public int getFontGenericFamily()
+ {
+ return fontGenericFamily;
+ }
+
+ public void setFontStyle(int fontStyle)
+ {
+ if(fontStyle < 0 || fontStyle > 3)
+ {
+ throw new IllegalArgumentException("invalid fontStyle");
+ } else
+ {
+ this.fontStyle = fontStyle;
+ return;
+ }
+ }
+
+ public int getFontStyle()
+ {
+ return fontStyle;
+ }
+
+ public void setCustomData(JSONObject customData)
+ {
+ this.customData = customData;
+ }
+
+ public JSONObject getCustomData()
+ {
+ return customData;
+ }
+
+ private void clear()
+ {
+ fontScale = 1.0F;
+ foregroundColor = 0;
+ backgroundColor = 0;
+ edgeType = -1;
+ edgeColor = 0;
+ windowType = -1;
+ windowColor = 0;
+ windowCornerRadius = 0;
+ fontFamily = null;
+ fontGenericFamily = -1;
+ fontStyle = -1;
+ customData = null;
+ }
+
+ @TargetApi(Build.VERSION_CODES.KITKAT)
+ public static TextTrackStyle fromSystemSettings(Context context)
+ {
+ TextTrackStyle texttrackstyle = new TextTrackStyle();
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
+ return texttrackstyle;
+ CaptioningManager captioningmanager = (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
+ texttrackstyle.setFontScale(captioningmanager.getFontScale());
+ android.view.accessibility.CaptioningManager.CaptionStyle captionstyle = captioningmanager.getUserStyle();
+ texttrackstyle.setBackgroundColor(captionstyle.backgroundColor);
+ texttrackstyle.setForegroundColor(captionstyle.foregroundColor);
+ switch(captionstyle.edgeType)
+ {
+ case 1: // '\001'
+ texttrackstyle.setEdgeType(1);
+ break;
+
+ case 2: // '\002'
+ texttrackstyle.setEdgeType(2);
+ break;
+
+ case 0: // '\0'
+ default:
+ texttrackstyle.setEdgeType(0);
+ break;
+ }
+ texttrackstyle.setEdgeColor(captionstyle.edgeColor);
+ Typeface typeface = captionstyle.getTypeface();
+ if(typeface != null)
+ {
+ if(Typeface.MONOSPACE.equals(typeface))
+ texttrackstyle.setFontGenericFamily(1);
+ else
+ if(Typeface.SANS_SERIF.equals(typeface))
+ texttrackstyle.setFontGenericFamily(0);
+ else
+ if(Typeface.SERIF.equals(typeface))
+ texttrackstyle.setFontGenericFamily(2);
+ else
+ texttrackstyle.setFontGenericFamily(0);
+ boolean flag = typeface.isBold();
+ boolean flag1 = typeface.isItalic();
+ if(flag && flag1)
+ texttrackstyle.setFontStyle(3);
+ else
+ if(flag)
+ texttrackstyle.setFontStyle(1);
+ else
+ if(flag1)
+ texttrackstyle.setFontStyle(2);
+ else
+ texttrackstyle.setFontStyle(0);
+ }
+ return texttrackstyle;
+ }
+
+ public void zzd(JSONObject jsonobject)
+ throws JSONException
+ {
+ clear();
+ fontScale = (float)jsonobject.optDouble("fontScale", 1.0D);
+ foregroundColor = toColor(jsonobject.optString("foregroundColor"));
+ backgroundColor = toColor(jsonobject.optString("backgroundColor"));
+ if(jsonobject.has("edgeType"))
+ {
+ String s = jsonobject.getString("edgeType");
+ if("NONE".equals(s))
+ edgeType = 0;
+ else
+ if("OUTLINE".equals(s))
+ edgeType = 1;
+ else
+ if("DROP_SHADOW".equals(s))
+ edgeType = 2;
+ else
+ if("RAISED".equals(s))
+ edgeType = 3;
+ else
+ if("DEPRESSED".equals(s))
+ edgeType = 4;
+ }
+ edgeColor = toColor(jsonobject.optString("edgeColor"));
+ if(jsonobject.has("windowType"))
+ {
+ String s1 = jsonobject.getString("windowType");
+ if("NONE".equals(s1))
+ windowType = 0;
+ else
+ if("NORMAL".equals(s1))
+ windowType = 1;
+ else
+ if("ROUNDED_CORNERS".equals(s1))
+ windowType = 2;
+ }
+ windowColor = toColor(jsonobject.optString("windowColor"));
+ if(windowType == 2)
+ windowCornerRadius = jsonobject.optInt("windowRoundedCornerRadius", 0);
+ fontFamily = jsonobject.optString("fontFamily", null);
+ if(jsonobject.has("fontGenericFamily"))
+ {
+ String s2 = jsonobject.getString("fontGenericFamily");
+ if("SANS_SERIF".equals(s2))
+ fontGenericFamily = 0;
+ else
+ if("MONOSPACED_SANS_SERIF".equals(s2))
+ fontGenericFamily = 1;
+ else
+ if("SERIF".equals(s2))
+ fontGenericFamily = 2;
+ else
+ if("MONOSPACED_SERIF".equals(s2))
+ fontGenericFamily = 3;
+ else
+ if("CASUAL".equals(s2))
+ fontGenericFamily = 4;
+ else
+ if("CURSIVE".equals(s2))
+ fontGenericFamily = 5;
+ else
+ if("SMALL_CAPITALS".equals(s2))
+ fontGenericFamily = 6;
+ }
+ if(jsonobject.has("fontStyle"))
+ {
+ String s3 = jsonobject.getString("fontStyle");
+ if("NORMAL".equals(s3))
+ fontStyle = 0;
+ else
+ if("BOLD".equals(s3))
+ fontStyle = 1;
+ else
+ if("ITALIC".equals(s3))
+ fontStyle = 2;
+ else
+ if("BOLD_ITALIC".equals(s3))
+ fontStyle = 3;
+ }
+ customData = jsonobject.optJSONObject("customData");
+ }
+
+ public JSONObject toJson()
+ {
+ JSONObject jsonobject = new JSONObject();
+ try
+ {
+ jsonobject.put("fontScale", fontScale);
+ if(foregroundColor != 0)
+ jsonobject.put("foregroundColor", zzy(foregroundColor));
+ if(backgroundColor != 0)
+ jsonobject.put("backgroundColor", zzy(backgroundColor));
+ switch(edgeType)
+ {
+ case 0: // '\0'
+ jsonobject.put("edgeType", "NONE");
+ break;
+
+ case 1: // '\001'
+ jsonobject.put("edgeType", "OUTLINE");
+ break;
+
+ case 2: // '\002'
+ jsonobject.put("edgeType", "DROP_SHADOW");
+ break;
+
+ case 3: // '\003'
+ jsonobject.put("edgeType", "RAISED");
+ break;
+
+ case 4: // '\004'
+ jsonobject.put("edgeType", "DEPRESSED");
+ break;
+ }
+ if(edgeColor != 0)
+ jsonobject.put("edgeColor", zzy(edgeColor));
+ switch(windowType)
+ {
+ case 0: // '\0'
+ jsonobject.put("windowType", "NONE");
+ break;
+
+ case 1: // '\001'
+ jsonobject.put("windowType", "NORMAL");
+ break;
+
+ case 2: // '\002'
+ jsonobject.put("windowType", "ROUNDED_CORNERS");
+ break;
+ }
+ if(windowColor != 0)
+ jsonobject.put("windowColor", zzy(windowColor));
+ if(windowType == 2)
+ jsonobject.put("windowRoundedCornerRadius", windowCornerRadius);
+ if(fontFamily != null)
+ jsonobject.put("fontFamily", fontFamily);
+ switch(fontGenericFamily)
+ {
+ case 0: // '\0'
+ jsonobject.put("fontGenericFamily", "SANS_SERIF");
+ break;
+
+ case 1: // '\001'
+ jsonobject.put("fontGenericFamily", "MONOSPACED_SANS_SERIF");
+ break;
+
+ case 2: // '\002'
+ jsonobject.put("fontGenericFamily", "SERIF");
+ break;
+
+ case 3: // '\003'
+ jsonobject.put("fontGenericFamily", "MONOSPACED_SERIF");
+ break;
+
+ case 4: // '\004'
+ jsonobject.put("fontGenericFamily", "CASUAL");
+ break;
+
+ case 5: // '\005'
+ jsonobject.put("fontGenericFamily", "CURSIVE");
+ break;
+
+ case 6: // '\006'
+ jsonobject.put("fontGenericFamily", "SMALL_CAPITALS");
+ break;
+ }
+ switch(fontStyle)
+ {
+ case 0: // '\0'
+ jsonobject.put("fontStyle", "NORMAL");
+ break;
+
+ case 1: // '\001'
+ jsonobject.put("fontStyle", "BOLD");
+ break;
+
+ case 2: // '\002'
+ jsonobject.put("fontStyle", "ITALIC");
+ break;
+
+ case 3: // '\003'
+ jsonobject.put("fontStyle", "BOLD_ITALIC");
+ break;
+ }
+ if(customData != null)
+ jsonobject.put("customData", customData);
+ }
+ catch(JSONException jsonexception) { }
+ return jsonobject;
+ }
+
+ private String zzy(int i)
+ {
+ return String.format("#%02X%02X%02X%02X", Color.red(i), Color.green(i), Color.blue(i), Color.alpha(i));
+ }
+
+ private int toColor(String color) {
+ if(color != null && color.length() == 9 && color.charAt(0) == 35) {
+ try {
+ int var2 = Integer.parseInt(color.substring(1, 3), 16);
+ int var3 = Integer.parseInt(color.substring(3, 5), 16);
+ int var4 = Integer.parseInt(color.substring(5, 7), 16);
+ int var5 = Integer.parseInt(color.substring(7, 9), 16);
+ return Color.argb(var5, var2, var3, var4);
+ } catch (NumberFormatException var6) {
+ // ignore
+ }
+ }
+ return 0;
+ }
+
+ public boolean equals(Object other)
+ {
+ if(this == other)
+ return true;
+ if(!(other instanceof TextTrackStyle))
+ return false;
+ TextTrackStyle texttrackstyle = (TextTrackStyle)other;
+ if((customData == null) != (texttrackstyle.customData == null))
+ return false;
+ if(customData != null && texttrackstyle.customData != null && !Objects.jsonEquals(customData, texttrackstyle.customData))
+ return false;
+ else
+ return fontScale == texttrackstyle.fontScale && foregroundColor == texttrackstyle.foregroundColor && backgroundColor == texttrackstyle.backgroundColor && edgeType == texttrackstyle.edgeType && edgeColor == texttrackstyle.edgeColor && windowType == texttrackstyle.windowType && windowCornerRadius == texttrackstyle.windowCornerRadius && Objects.equals(fontFamily, texttrackstyle.fontFamily) && fontGenericFamily == texttrackstyle.fontGenericFamily && fontStyle == texttrackstyle.fontStyle;
+ }
+
+ public int hashCode()
+ {
+ return Objects.hash(fontScale, foregroundColor, backgroundColor, edgeType, edgeColor, windowType, windowColor, windowCornerRadius, fontFamily, fontGenericFamily, fontStyle, customData);
+ }
+
+ public static final float DEFAULT_FONT_SCALE = 1F;
+ public static final int COLOR_UNSPECIFIED = 0;
+ public static final int EDGE_TYPE_UNSPECIFIED = -1;
+ public static final int EDGE_TYPE_NONE = 0;
+ public static final int EDGE_TYPE_OUTLINE = 1;
+ public static final int EDGE_TYPE_DROP_SHADOW = 2;
+ public static final int EDGE_TYPE_RAISED = 3;
+ public static final int EDGE_TYPE_DEPRESSED = 4;
+ public static final int WINDOW_TYPE_UNSPECIFIED = -1;
+ public static final int WINDOW_TYPE_NONE = 0;
+ public static final int WINDOW_TYPE_NORMAL = 1;
+ public static final int WINDOW_TYPE_ROUNDED = 2;
+ public static final int FONT_FAMILY_UNSPECIFIED = -1;
+ public static final int FONT_FAMILY_SANS_SERIF = 0;
+ public static final int FONT_FAMILY_MONOSPACED_SANS_SERIF = 1;
+ public static final int FONT_FAMILY_SERIF = 2;
+ public static final int FONT_FAMILY_MONOSPACED_SERIF = 3;
+ public static final int FONT_FAMILY_CASUAL = 4;
+ public static final int FONT_FAMILY_CURSIVE = 5;
+ public static final int FONT_FAMILY_SMALL_CAPITALS = 6;
+ public static final int FONT_STYLE_UNSPECIFIED = -1;
+ public static final int FONT_STYLE_NORMAL = 0;
+ public static final int FONT_STYLE_BOLD = 1;
+ public static final int FONT_STYLE_ITALIC = 2;
+ public static final int FONT_STYLE_BOLD_ITALIC = 3;
+ private float fontScale;
+ private int foregroundColor;
+ private int backgroundColor;
+ private int edgeType;
+ private int edgeColor;
+ private int windowType;
+ private int windowColor;
+ private int windowCornerRadius;
+ private String fontFamily;
+ private int fontGenericFamily;
+ private int fontStyle;
+ private JSONObject customData;
+}
diff --git a/play-services/build.gradle b/play-services/build.gradle
index 2bed934..ca46a1a 100644
--- a/play-services/build.gradle
+++ b/play-services/build.gradle
@@ -15,6 +15,7 @@ dependencies {
compile project(':play-services-base')
compile project(':play-services-location')
compile project(':play-services-wearable')
+ compile project(':play-services-cast')
}
android {
diff --git a/settings.gradle b/settings.gradle
index 9ec62cf..86f5e93 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -5,5 +5,6 @@ include ':play-services-api'
include ':play-services-base'
include ':play-services-location'
include ':play-services-wearable'
+include ':play-services-cast'
include ':play-services'