Repo Created
This commit is contained in:
parent
eb305e2886
commit
a8c22c65db
4784 changed files with 329907 additions and 2 deletions
49
play-services-cast/build.gradle
Normal file
49
play-services-cast/build.gradle
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
|
||||
android {
|
||||
namespace "com.google.android.gms.cast"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
aidlPackagedList "com/google/android/gms/cast/ApplicationMetadata.aidl"
|
||||
aidlPackagedList "com/google/android/gms/cast/LaunchOptions.aidl"
|
||||
|
||||
buildFeatures {
|
||||
aidl = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
apply from: '../gradle/publish-android.gradle'
|
||||
|
||||
description = 'microG implementation of play-services-cast'
|
||||
|
||||
dependencies {
|
||||
// Dependencies from play-services-cast:21.2.0
|
||||
api "androidx.core:core:1.0.0"
|
||||
api "androidx.mediarouter:mediarouter:1.2.2"
|
||||
api project(':play-services-base')
|
||||
api project(':play-services-basement')
|
||||
//api project(':play-services-flags')
|
||||
api project(':play-services-tasks')
|
||||
|
||||
annotationProcessor project(':safe-parcel-processor')
|
||||
}
|
||||
61
play-services-cast/core/build.gradle
Normal file
61
play-services-cast/core/build.gradle
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
|
||||
dependencies {
|
||||
implementation project(':play-services-cast')
|
||||
implementation project(':play-services-base-core')
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion"
|
||||
|
||||
// TODO: Switch to upstream once raw requests are merged
|
||||
// https://github.com/vitalidze/chromecast-java-api-v2/pull/99
|
||||
// implementation "su.litvak.chromecast:api-v2:0.10.4"
|
||||
implementation "info.armills.chromecast-java-api-v2:api-v2-raw-request:0.10.4-raw-request-1"
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "org.microg.gms.cast.core"
|
||||
|
||||
compileSdkVersion androidCompileSdk
|
||||
buildToolsVersion "$androidBuildVersionTools"
|
||||
|
||||
defaultConfig {
|
||||
versionName version
|
||||
minSdkVersion androidMinSdk
|
||||
targetSdkVersion androidTargetSdk
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
dataBinding = true
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'MissingTranslation'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = 1.8
|
||||
}
|
||||
}
|
||||
|
||||
apply from: '../../gradle/publish-android.gradle'
|
||||
|
||||
description = 'microG service implementation for play-services-cast'
|
||||
22
play-services-cast/core/src/main/AndroidManifest.xml
Normal file
22
play-services-cast/core/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
~ SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application>
|
||||
<service android:name="com.google.android.gms.cast.media.CastMediaRouteProviderService">
|
||||
<intent-filter>
|
||||
<action android:name="android.media.MediaRouteProviderService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service android:name="org.microg.gms.cast.CastDeviceControllerService">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.gms.cast.service.BIND_CAST_DEVICE_CONTROLLER_SERVICE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast.media;
|
||||
|
||||
import org.microg.gms.cast.CastMediaRouteProvider;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.mediarouter.media.MediaRouteProvider;
|
||||
import androidx.mediarouter.media.MediaRouteProviderService;
|
||||
|
||||
public class CastMediaRouteProviderService extends MediaRouteProviderService {
|
||||
private static final String TAG = CastMediaRouteProviderService.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public MediaRouteProvider onCreateMediaRouteProvider() {
|
||||
return new CastMediaRouteProvider(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.cast.ApplicationMetadata;
|
||||
import com.google.android.gms.cast.ApplicationStatus;
|
||||
import com.google.android.gms.cast.CastDevice;
|
||||
import com.google.android.gms.cast.CastDeviceStatus;
|
||||
import com.google.android.gms.cast.JoinOptions;
|
||||
import com.google.android.gms.cast.LaunchOptions;
|
||||
import com.google.android.gms.cast.internal.ICastDeviceController;
|
||||
import com.google.android.gms.cast.internal.ICastDeviceControllerListener;
|
||||
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
import com.google.android.gms.common.internal.BinderWrapper;
|
||||
import com.google.android.gms.common.internal.GetServiceRequest;
|
||||
|
||||
import su.litvak.chromecast.api.v2.Application;
|
||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
||||
import su.litvak.chromecast.api.v2.Namespace;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastConnectionEventListener;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastSpontaneousEventListener;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastRawMessageListener;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastConnectionEvent;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastSpontaneousEvent;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastRawMessage;
|
||||
import su.litvak.chromecast.api.v2.AppEvent;
|
||||
|
||||
public class CastDeviceControllerImpl extends ICastDeviceController.Stub implements
|
||||
ChromeCastConnectionEventListener,
|
||||
ChromeCastSpontaneousEventListener,
|
||||
ChromeCastRawMessageListener,
|
||||
ICastDeviceControllerListener
|
||||
{
|
||||
private static final String TAG = "GmsCastDeviceController";
|
||||
|
||||
private Context context;
|
||||
private String packageName;
|
||||
private CastDevice castDevice;
|
||||
boolean notificationEnabled;
|
||||
long castFlags;
|
||||
ICastDeviceControllerListener listener;
|
||||
|
||||
ChromeCast chromecast;
|
||||
|
||||
String sessionId = null;
|
||||
|
||||
public CastDeviceControllerImpl(Context context, String packageName, Bundle extras) {
|
||||
this.context = context;
|
||||
this.packageName = packageName;
|
||||
|
||||
extras.setClassLoader(BinderWrapper.class.getClassLoader());
|
||||
this.castDevice = CastDevice.getFromBundle(extras);
|
||||
this.notificationEnabled = extras.getBoolean("com.google.android.gms.cast.EXTRA_CAST_FRAMEWORK_NOTIFICATION_ENABLED");
|
||||
this.castFlags = extras.getLong("com.google.android.gms.cast.EXTRA_CAST_FLAGS");
|
||||
BinderWrapper listenerWrapper = (BinderWrapper)extras.get("listener");
|
||||
if (listenerWrapper != null) {
|
||||
this.listener = ICastDeviceControllerListener.Stub.asInterface(listenerWrapper.binder);
|
||||
}
|
||||
|
||||
this.chromecast = new ChromeCast(this.castDevice.getAddress());
|
||||
this.chromecast.registerListener(this);
|
||||
this.chromecast.registerRawMessageListener(this);
|
||||
this.chromecast.registerConnectionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionEventReceived(ChromeCastConnectionEvent event) {
|
||||
if (!event.isConnected()) {
|
||||
this.onDisconnected(CommonStatusCodes.SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
protected ApplicationMetadata createMetadataFromApplication(Application app) {
|
||||
if (app == null) {
|
||||
return null;
|
||||
}
|
||||
ApplicationMetadata metadata = new ApplicationMetadata();
|
||||
metadata.applicationId = app.id;
|
||||
metadata.name = app.name;
|
||||
Log.d(TAG, "unimplemented: ApplicationMetadata.images");
|
||||
Log.d(TAG, "unimplemented: ApplicationMetadata.senderAppLaunchUri");
|
||||
metadata.images = new ArrayList<WebImage>();
|
||||
metadata.namespaces = new ArrayList<String>();
|
||||
for(Namespace namespace : app.namespaces) {
|
||||
metadata.namespaces.add(namespace.name);
|
||||
}
|
||||
metadata.senderAppIdentifier = this.context.getPackageName();
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spontaneousEventReceived(ChromeCastSpontaneousEvent event) {
|
||||
switch (event.getType()) {
|
||||
case MEDIA_STATUS:
|
||||
break;
|
||||
case STATUS:
|
||||
su.litvak.chromecast.api.v2.Status status = (su.litvak.chromecast.api.v2.Status)event.getData();
|
||||
Application app = status.getRunningApp();
|
||||
ApplicationMetadata metadata = this.createMetadataFromApplication(app);
|
||||
if (app != null) {
|
||||
this.onApplicationStatusChanged(new ApplicationStatus(app.statusText));
|
||||
}
|
||||
int activeInputState = status.activeInput ? 1 : 0;
|
||||
int standbyState = status.standBy ? 1 : 0;
|
||||
this.onDeviceStatusChanged(new CastDeviceStatus(status.volume.level, status.volume.muted, activeInputState, metadata, standbyState));
|
||||
break;
|
||||
case APPEVENT:
|
||||
break;
|
||||
case CLOSE:
|
||||
this.onApplicationDisconnected(CommonStatusCodes.SUCCESS);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rawMessageReceived(ChromeCastRawMessage message, Long requestId) {
|
||||
switch (message.getPayloadType()) {
|
||||
case STRING:
|
||||
String response = message.getPayloadUtf8();
|
||||
if (requestId == null) {
|
||||
this.onTextMessageReceived(message.getNamespace(), response);
|
||||
} else {
|
||||
this.onSendMessageSuccess(response, requestId);
|
||||
this.onTextMessageReceived(message.getNamespace(), response);
|
||||
}
|
||||
break;
|
||||
case BINARY:
|
||||
byte[] payload = message.getPayloadBinary();
|
||||
this.onBinaryMessageReceived(message.getNamespace(), payload);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
try {
|
||||
this.chromecast.disconnect();
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error disconnecting chromecast: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String namespace, String message, long requestId) {
|
||||
try {
|
||||
this.chromecast.sendRawRequest(namespace, message, requestId);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Error sending cast message: " + e.getMessage());
|
||||
this.onSendMessageFailure("", requestId, CommonStatusCodes.NETWORK_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopApplication(String sessionId) {
|
||||
try {
|
||||
this.chromecast.stopSession(sessionId);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Error sending cast message: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
this.sessionId = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNamespace(String namespace) {
|
||||
Log.d(TAG, "unimplemented Method: registerNamespace");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterNamespace(String namespace) {
|
||||
Log.d(TAG, "unimplemented Method: unregisterNamespace");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launchApplication(String applicationId, LaunchOptions launchOptions) {
|
||||
Application app = null;
|
||||
try {
|
||||
app = this.chromecast.launchApp(applicationId);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Error launching cast application: " + e.getMessage());
|
||||
this.onApplicationConnectionFailure(CommonStatusCodes.NETWORK_ERROR);
|
||||
return;
|
||||
}
|
||||
this.sessionId = app.sessionId;
|
||||
|
||||
ApplicationMetadata metadata = this.createMetadataFromApplication(app);
|
||||
this.onApplicationConnectionSuccess(metadata, app.statusText, app.sessionId, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void joinApplication(String applicationId, String sessionId, JoinOptions joinOptions) {
|
||||
Log.d(TAG, "unimplemented Method: joinApplication");
|
||||
this.launchApplication(applicationId, new LaunchOptions());
|
||||
}
|
||||
|
||||
public void onDisconnected(int reason) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onDisconnected(reason);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onDisconnected: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onApplicationConnectionSuccess(ApplicationMetadata applicationMetadata, String applicationStatus, String sessionId, boolean wasLaunched) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onApplicationConnectionSuccess(applicationMetadata, applicationStatus, sessionId, wasLaunched);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onApplicationConnectionSuccess: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onApplicationConnectionFailure(int statusCode) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onApplicationConnectionFailure(statusCode);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onApplicationConnectionFailure: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onTextMessageReceived(String namespace, String message) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onTextMessageReceived(namespace, message);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onTextMessageReceived: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onBinaryMessageReceived(String namespace, byte[] data) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onBinaryMessageReceived(namespace, data);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onBinaryMessageReceived: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onApplicationDisconnected(int paramInt) {
|
||||
Log.d(TAG, "unimplemented Method: onApplicationDisconnected");
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onApplicationDisconnected(paramInt);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onApplicationDisconnected: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onSendMessageFailure(String response, long requestId, int statusCode) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onSendMessageFailure(response, requestId, statusCode);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onSendMessageFailure: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onSendMessageSuccess(String response, long requestId) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onSendMessageSuccess(response, requestId);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onSendMessageSuccess: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onApplicationStatusChanged(ApplicationStatus applicationStatus) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onApplicationStatusChanged(applicationStatus);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onApplicationStatusChanged: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onDeviceStatusChanged(CastDeviceStatus deviceStatus) {
|
||||
if (this.listener != null) {
|
||||
try {
|
||||
this.listener.onDeviceStatusChanged(deviceStatus);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "Error calling onDeviceStatusChanged: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Parcel;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.cast.CastDevice;
|
||||
import com.google.android.gms.cast.internal.ICastDeviceControllerListener;
|
||||
import com.google.android.gms.common.internal.GetServiceRequest;
|
||||
import com.google.android.gms.common.internal.BinderWrapper;
|
||||
import com.google.android.gms.common.internal.IGmsCallbacks;
|
||||
|
||||
import org.microg.gms.BaseService;
|
||||
import org.microg.gms.common.GmsService;
|
||||
|
||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
||||
import su.litvak.chromecast.api.v2.ChromeCasts;
|
||||
import su.litvak.chromecast.api.v2.Status;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastsListener;
|
||||
|
||||
public class CastDeviceControllerService extends BaseService {
|
||||
private static final String TAG = CastDeviceControllerService.class.getSimpleName();
|
||||
|
||||
public CastDeviceControllerService() {
|
||||
super("GmsCastDeviceControllerSvc", GmsService.CAST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
|
||||
callback.onPostInitComplete(0, new CastDeviceControllerImpl(this, request.packageName, request.extras), null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.mediarouter.media.MediaRouteProvider;
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
import com.google.android.gms.cast.CastDevice;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.io.IOException;
|
||||
import java.lang.Thread;
|
||||
import java.lang.Runnable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import su.litvak.chromecast.api.v2.ChromeCast;
|
||||
import su.litvak.chromecast.api.v2.ChromeCasts;
|
||||
import su.litvak.chromecast.api.v2.Status;
|
||||
import su.litvak.chromecast.api.v2.ChromeCastsListener;
|
||||
|
||||
public class CastMediaRouteController extends MediaRouteProvider.RouteController {
|
||||
private static final String TAG = CastMediaRouteController.class.getSimpleName();
|
||||
|
||||
private CastMediaRouteProvider provider;
|
||||
private String routeId;
|
||||
private ChromeCast chromecast;
|
||||
|
||||
public CastMediaRouteController(CastMediaRouteProvider provider, String routeId, String address) {
|
||||
super();
|
||||
|
||||
this.provider = provider;
|
||||
this.routeId = routeId;
|
||||
this.chromecast = new ChromeCast(address);
|
||||
}
|
||||
|
||||
public boolean onControlRequest(Intent intent, MediaRouter.ControlRequestCallback callback) {
|
||||
Log.d(TAG, "unimplemented Method: onControlRequest: " + this.routeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onRelease() {
|
||||
Log.d(TAG, "unimplemented Method: onRelease: " + this.routeId);
|
||||
}
|
||||
|
||||
public void onSelect() {
|
||||
Log.d(TAG, "unimplemented Method: onSelect: " + this.routeId);
|
||||
}
|
||||
|
||||
public void onSetVolume(int volume) {
|
||||
Log.d(TAG, "unimplemented Method: onSetVolume: " + this.routeId);
|
||||
}
|
||||
|
||||
public void onUnselect() {
|
||||
Log.d(TAG, "unimplemented Method: onUnselect: " + this.routeId);
|
||||
}
|
||||
|
||||
public void onUnselect(int reason) {
|
||||
Log.d(TAG, "unimplemented Method: onUnselect: " + this.routeId);
|
||||
}
|
||||
|
||||
public void onUpdateVolume(int delta) {
|
||||
Log.d(TAG, "unimplemented Method: onUpdateVolume: " + this.routeId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,359 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.net.nsd.NsdManager;
|
||||
import android.net.nsd.NsdServiceInfo;
|
||||
import android.os.Bundle;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.mediarouter.media.MediaControlIntent;
|
||||
import androidx.mediarouter.media.MediaRouteDescriptor;
|
||||
import androidx.mediarouter.media.MediaRouteDiscoveryRequest;
|
||||
import androidx.mediarouter.media.MediaRouteProvider;
|
||||
import androidx.mediarouter.media.MediaRouteProviderDescriptor;
|
||||
import androidx.mediarouter.media.MediaRouter;
|
||||
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
import com.google.android.gms.cast.CastDevice;
|
||||
import com.google.android.gms.cast.CastMediaControlIntent;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.Thread;
|
||||
import java.lang.Runnable;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CastMediaRouteProvider extends MediaRouteProvider {
|
||||
private static final String TAG = CastMediaRouteProvider.class.getSimpleName();
|
||||
|
||||
private Map<String, CastDevice> castDevices = new HashMap<String, CastDevice>();
|
||||
private Map<String, String> serviceCastIds = new HashMap<String, String>();
|
||||
|
||||
private NsdManager mNsdManager;
|
||||
private NsdManager.DiscoveryListener mDiscoveryListener;
|
||||
|
||||
private List<String> customCategories = new ArrayList<String>();
|
||||
|
||||
private enum State {
|
||||
NOT_DISCOVERING,
|
||||
DISCOVERY_REQUESTED,
|
||||
DISCOVERING,
|
||||
DISCOVERY_STOP_REQUESTED,
|
||||
}
|
||||
private State state = State.NOT_DISCOVERING;
|
||||
|
||||
private static final ArrayList<IntentFilter> BASE_CONTROL_FILTERS = new ArrayList<IntentFilter>();
|
||||
static {
|
||||
IntentFilter filter;
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(CastMediaControlIntent.CATEGORY_CAST);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_PLAY);
|
||||
filter.addDataScheme("http");
|
||||
filter.addDataScheme("https");
|
||||
String[] types = {
|
||||
"image/jpeg",
|
||||
"image/pjpeg",
|
||||
"image/jpg",
|
||||
"image/webp",
|
||||
"image/png",
|
||||
"image/gif",
|
||||
"image/bmp",
|
||||
"image/vnd.microsoft.icon",
|
||||
"image/x-icon",
|
||||
"image/x-xbitmap",
|
||||
"audio/wav",
|
||||
"audio/x-wav",
|
||||
"audio/mp3",
|
||||
"audio/x-mp3",
|
||||
"audio/x-m4a",
|
||||
"audio/mpeg",
|
||||
"audio/webm",
|
||||
"audio/ogg",
|
||||
"audio/x-matroska",
|
||||
"video/mp4",
|
||||
"video/x-m4v",
|
||||
"video/mp2t",
|
||||
"video/webm",
|
||||
"video/ogg",
|
||||
"video/x-matroska",
|
||||
"application/x-mpegurl",
|
||||
"application/vnd.apple.mpegurl",
|
||||
"application/dash+xml",
|
||||
"application/vnd.ms-sstr+xml",
|
||||
};
|
||||
for (String type : types) {
|
||||
try {
|
||||
filter.addDataType(type);
|
||||
} catch (IntentFilter.MalformedMimeTypeException ex) {
|
||||
Log.e(TAG, "Error adding filter type " + type);
|
||||
}
|
||||
}
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_PAUSE);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_RESUME);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_STOP);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_SEEK);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_GET_STATUS);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_START_SESSION);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_GET_SESSION_STATUS);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
|
||||
filter.addAction(MediaControlIntent.ACTION_END_SESSION);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(CastMediaControlIntent.CATEGORY_CAST_REMOTE_PLAYBACK);
|
||||
filter.addAction(CastMediaControlIntent.ACTION_SYNC_STATUS);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addCategory(CastMediaControlIntent.CATEGORY_CAST_REMOTE_PLAYBACK);
|
||||
filter.addAction(CastMediaControlIntent.ACTION_SYNC_STATUS);
|
||||
BASE_CONTROL_FILTERS.add(filter);
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public CastMediaRouteProvider(Context context) {
|
||||
super(context);
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT < 16) {
|
||||
Log.i(TAG, "Cast discovery disabled. Android SDK version 16 or higher required.");
|
||||
return;
|
||||
}
|
||||
|
||||
mNsdManager = (NsdManager)context.getApplicationContext().getSystemService(Context.NSD_SERVICE);
|
||||
|
||||
mDiscoveryListener = new NsdManager.DiscoveryListener() {
|
||||
|
||||
@Override
|
||||
public void onDiscoveryStarted(String regType) {
|
||||
CastMediaRouteProvider.this.state = State.DISCOVERING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceFound(NsdServiceInfo service) {
|
||||
mNsdManager.resolveService(service, new NsdManager.ResolveListener() {
|
||||
@Override
|
||||
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
|
||||
if (errorCode == NsdManager.FAILURE_ALREADY_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
Log.e(TAG, "DiscoveryListener Resolve failed. Error code " + errorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceResolved(NsdServiceInfo serviceInfo) {
|
||||
String name = serviceInfo.getServiceName();
|
||||
InetAddress host = serviceInfo.getHost();
|
||||
int port = serviceInfo.getPort();
|
||||
Map<String, byte[]> attributes = serviceInfo.getAttributes();
|
||||
if (attributes == null) {
|
||||
Log.e(TAG, "Error getting service attributes from DNS-SD response");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String id = new String(attributes.get("id"), "UTF-8");
|
||||
String deviceVersion = new String(attributes.get("ve"), "UTF-8");
|
||||
String friendlyName = new String(attributes.get("fn"), "UTF-8");
|
||||
String modelName = new String(attributes.get("md"), "UTF-8");
|
||||
String iconPath = new String(attributes.get("ic"), "UTF-8");
|
||||
int status = Integer.parseInt(new String(attributes.get("st"), "UTF-8"));
|
||||
|
||||
onChromeCastDiscovered(id, name, host, port, deviceVersion, friendlyName, modelName, iconPath, status);
|
||||
} catch (UnsupportedEncodingException | NullPointerException ex) {
|
||||
Log.e(TAG, "Error getting cast details from DNS-SD response", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceLost(NsdServiceInfo serviceInfo) {
|
||||
String name = serviceInfo.getServiceName();
|
||||
onChromeCastLost(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDiscoveryStopped(String serviceType) {
|
||||
CastMediaRouteProvider.this.state = State.NOT_DISCOVERING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
|
||||
CastMediaRouteProvider.this.state = State.NOT_DISCOVERING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
|
||||
CastMediaRouteProvider.this.state = State.DISCOVERING;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void onChromeCastDiscovered(
|
||||
String id, String name, InetAddress host, int port, String
|
||||
deviceVersion, String friendlyName, String modelName, String
|
||||
iconPath, int status) {
|
||||
if (!this.castDevices.containsKey(id)) {
|
||||
// TODO: Capabilities
|
||||
int capabilities = CastDevice.CAPABILITY_VIDEO_OUT | CastDevice.CAPABILITY_AUDIO_OUT;
|
||||
|
||||
CastDevice castDevice = new CastDevice(id, name, host, port, deviceVersion, friendlyName, modelName, iconPath, status, capabilities);
|
||||
this.castDevices.put(id, castDevice);
|
||||
this.serviceCastIds.put(name, id);
|
||||
}
|
||||
|
||||
publishRoutesInMainThread();
|
||||
}
|
||||
|
||||
private void onChromeCastLost(String name) {
|
||||
String id = this.serviceCastIds.remove(name);
|
||||
if (id != null) {
|
||||
this.castDevices.remove(id);
|
||||
}
|
||||
|
||||
publishRoutesInMainThread();
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@Override
|
||||
public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
|
||||
if (android.os.Build.VERSION.SDK_INT < 16) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (request != null && request.isValid() && request.isActiveScan()) {
|
||||
if (request.getSelector() != null) {
|
||||
for (String category : request.getSelector().getControlCategories()) {
|
||||
if (CastMediaControlIntent.isCategoryForCast(category)) {
|
||||
this.customCategories.add(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.state == State.NOT_DISCOVERING) {
|
||||
mNsdManager.discoverServices("_googlecast._tcp.", NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
|
||||
this.state = State.DISCOVERY_REQUESTED;
|
||||
}
|
||||
} else {
|
||||
if (this.state == State.DISCOVERING) {
|
||||
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
|
||||
this.state = State.DISCOVERY_STOP_REQUESTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RouteController onCreateRouteController(String routeId) {
|
||||
CastDevice castDevice = this.castDevices.get(routeId);
|
||||
if (castDevice == null) {
|
||||
return null;
|
||||
}
|
||||
return new CastMediaRouteController(this, routeId, castDevice.getAddress());
|
||||
}
|
||||
|
||||
private void publishRoutesInMainThread() {
|
||||
Handler mainHandler = new Handler(this.getContext().getMainLooper());
|
||||
mainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
publishRoutes();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void publishRoutes() {
|
||||
MediaRouteProviderDescriptor.Builder builder = new MediaRouteProviderDescriptor.Builder();
|
||||
for (CastDevice castDevice : this.castDevices.values()) {
|
||||
ArrayList<IntentFilter> controlFilters = new ArrayList<IntentFilter>(BASE_CONTROL_FILTERS);
|
||||
// Include any app-specific control filters that have been requested.
|
||||
// TODO: Do we need to check with the device?
|
||||
for (String category : this.customCategories) {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addCategory(category);
|
||||
controlFilters.add(filter);
|
||||
}
|
||||
|
||||
Bundle extras = new Bundle();
|
||||
castDevice.putInBundle(extras);
|
||||
MediaRouteDescriptor route = new MediaRouteDescriptor.Builder(
|
||||
castDevice.getDeviceId(),
|
||||
castDevice.getFriendlyName())
|
||||
.setDescription(castDevice.getModelName())
|
||||
.addControlFilters(controlFilters)
|
||||
.setDeviceType(MediaRouter.RouteInfo.DEVICE_TYPE_TV)
|
||||
.setPlaybackType(MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE)
|
||||
.setVolumeHandling(MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED)
|
||||
.setVolumeMax(20)
|
||||
.setVolume(0)
|
||||
.setEnabled(true)
|
||||
.setExtras(extras)
|
||||
.setConnectionState(MediaRouter.RouteInfo.CONNECTION_STATE_DISCONNECTED)
|
||||
.build();
|
||||
builder.addRoute(route);
|
||||
}
|
||||
this.setDescriptor(builder.build());
|
||||
}
|
||||
}
|
||||
18
play-services-cast/src/main/AndroidManifest.xml
Normal file
18
play-services-cast/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2013-2017 microG Project Team
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<manifest />
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.cast;
|
||||
|
||||
parcelable ApplicationMetadata;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.cast;
|
||||
|
||||
parcelable ApplicationStatus;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.cast;
|
||||
|
||||
parcelable CastDeviceStatus;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.cast;
|
||||
|
||||
parcelable JoinOptions;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.cast;
|
||||
|
||||
parcelable LaunchOptions;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021, microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
parcelable RequestItem;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021, microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast.internal;
|
||||
|
||||
interface IBundleCallback {
|
||||
oneway void onBundle(in Bundle bundle);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.google.android.gms.cast.internal;
|
||||
|
||||
import com.google.android.gms.cast.LaunchOptions;
|
||||
import com.google.android.gms.cast.JoinOptions;
|
||||
|
||||
interface ICastDeviceController {
|
||||
oneway void disconnect() = 0;
|
||||
oneway void stopApplication(String sessionId) = 4;
|
||||
oneway void sendMessage(String namespace, String message, long requestId) = 8;
|
||||
oneway void registerNamespace(String namespace) = 10;
|
||||
oneway void unregisterNamespace(String namespace) = 11;
|
||||
oneway void launchApplication(String applicationId, in LaunchOptions launchOptions) = 12;
|
||||
oneway void joinApplication(String applicationId, String sessionId, in JoinOptions joinOptions) = 13;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.google.android.gms.cast.internal;
|
||||
|
||||
import com.google.android.gms.cast.ApplicationMetadata;
|
||||
import com.google.android.gms.cast.ApplicationStatus;
|
||||
import com.google.android.gms.cast.CastDeviceStatus;
|
||||
|
||||
interface ICastDeviceControllerListener {
|
||||
void onDisconnected(int reason) = 0;
|
||||
void onApplicationConnectionSuccess(in ApplicationMetadata applicationMetadata, String applicationStatus, String sessionId, boolean wasLaunched) = 1;
|
||||
void onApplicationConnectionFailure(int statusCode) = 2;
|
||||
// Deprecated: void onStatusReceived(String string1, double double1, boolean boolean1) = 3;
|
||||
void onTextMessageReceived(String namespace, String message) = 4;
|
||||
void onBinaryMessageReceived(String namespace, in byte[] data) = 5;
|
||||
// void onStatusChanged(int status) = 6; // TODO
|
||||
// void onStatusChanged2(int status) = 7; // TODO
|
||||
void onApplicationDisconnected(int paramInt) = 8;
|
||||
void onSendMessageFailure(String response, long requestId, int statusCode) = 9;
|
||||
void onSendMessageSuccess(String response, long requestId) = 10;
|
||||
void onApplicationStatusChanged(in ApplicationStatus applicationStatus) = 11;
|
||||
void onDeviceStatusChanged(in CastDeviceStatus deviceStatus) = 12;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021, microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast.internal;
|
||||
|
||||
import com.google.android.gms.common.api.internal.IStatusCallback;
|
||||
import com.google.android.gms.cast.internal.IBundleCallback;
|
||||
import com.google.android.gms.cast.RequestItem;
|
||||
|
||||
interface ICastService {
|
||||
oneway void broadcastPrecacheMessageLegacy(IStatusCallback callback, in String[] arg2, String precacheData) = 0;
|
||||
oneway void broadcastPrecacheMessage(IStatusCallback callback, in String[] arg2, String precacheData, in List<RequestItem> requestItems) = 1;
|
||||
oneway void getCxLessStatus(IStatusCallback callback) = 3;
|
||||
oneway void getFeatureFlags(IBundleCallback callback, in String[] flags) = 4;
|
||||
oneway void getCastStatusCodeDictionary(IBundleCallback callback, in String[] dictionaries) = 5;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@PublicApi
|
||||
public class ApplicationMetadata extends AutoSafeParcelable {
|
||||
|
||||
@SafeParceled(1)
|
||||
private int versionCode = 1;
|
||||
@SafeParceled(2)
|
||||
public String applicationId;
|
||||
@SafeParceled(3)
|
||||
public String name;
|
||||
@SafeParceled(value = 4, subClass = WebImage.class)
|
||||
public List<WebImage> images;
|
||||
@SafeParceled(value = 5, subClass = String.class)
|
||||
public List<String> namespaces;
|
||||
@SafeParceled(6)
|
||||
public String senderAppIdentifier;
|
||||
@SafeParceled(7)
|
||||
public Uri senderAppLaunchUri;
|
||||
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
public List<WebImage> getImages() {
|
||||
return images;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getSenderAppIdentifier() {
|
||||
return senderAppIdentifier;
|
||||
}
|
||||
|
||||
public boolean isNamespaceSupported(String namespace) {
|
||||
return namespaces.contains(namespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("ApplicationMetadata{");
|
||||
sb.append("applicationId='").append(applicationId).append("'");
|
||||
sb.append(", name='").append(name).append("'");
|
||||
sb.append(", images=").append(images.toString());
|
||||
if (namespaces != null) {
|
||||
sb.append(", namespaces=").append(namespaces.toString());
|
||||
}
|
||||
sb.append(", senderAppIdentifier='").append(senderAppIdentifier).append("'");
|
||||
if (senderAppLaunchUri != null) {
|
||||
sb.append(", senderAppLaunchUri='").append(senderAppLaunchUri.toString()).append("'");
|
||||
}
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static final Creator<ApplicationMetadata> CREATOR = new AutoCreator<ApplicationMetadata>(ApplicationMetadata.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
public class ApplicationStatus extends AutoSafeParcelable {
|
||||
|
||||
public ApplicationStatus() {}
|
||||
|
||||
public ApplicationStatus(String applicationStatus) {
|
||||
this.applicationStatus = applicationStatus;
|
||||
}
|
||||
|
||||
@SafeParceled(1)
|
||||
private int versionCode = 1;
|
||||
@SafeParceled(2)
|
||||
private String applicationStatus;
|
||||
|
||||
public static final Creator<ApplicationStatus> CREATOR = new AutoCreator<ApplicationStatus>(ApplicationStatus.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
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.Status;
|
||||
|
||||
import org.microg.gms.cast.CastApiClientBuilder;
|
||||
import org.microg.gms.cast.CastApiImpl;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@PublicApi
|
||||
public final class Cast {
|
||||
|
||||
/**
|
||||
* A constant indicating that the Google Cast device is not the currently active video input.
|
||||
*/
|
||||
public static final int ACTIVE_INPUT_STATE_NO = 0;
|
||||
|
||||
/**
|
||||
* A constant indicating that it is not known (and/or not possible to know) whether the Google Cast device is
|
||||
* the currently active video input. Active input state can only be reported when the Google Cast device is
|
||||
* connected to a TV or AVR with CEC support.
|
||||
*/
|
||||
public static final int ACTIVE_INPUT_STATE_UNKNOWN = -1;
|
||||
|
||||
/**
|
||||
* A constant indicating that the Google Cast device is the currently active video input.
|
||||
*/
|
||||
public static final int ACTIVE_INPUT_STATE_YES = 1;
|
||||
|
||||
/**
|
||||
* A boolean extra for the connection hint bundle passed to
|
||||
* {@link GoogleApiClient.ConnectionCallbacks#onConnected(Bundle)} that indicates that the connection was
|
||||
* re-established, but the receiver application that was in use at the time of the connection loss is no longer
|
||||
* running on the receiver.
|
||||
*/
|
||||
public static final String EXTRA_APP_NO_LONGER_RUNNING = "com.google.android.gms.cast.EXTRA_APP_NO_LONGER_RUNNING";
|
||||
|
||||
/**
|
||||
* The maximum raw message length (in bytes) that is supported by a Cast channel.
|
||||
*/
|
||||
public static final int MAX_MESSAGE_LENGTH = 65536;
|
||||
|
||||
/**
|
||||
* The maximum length (in characters) of a namespace name.
|
||||
*/
|
||||
public static final int MAX_NAMESPACE_LENGTH = 128;
|
||||
|
||||
/**
|
||||
* A constant indicating that the Google Cast device is not currently in standby.
|
||||
*/
|
||||
public static final int STANDBY_STATE_NO = 0;
|
||||
|
||||
/**
|
||||
* A constant indicating that it is not known (and/or not possible to know) whether the Google Cast device is
|
||||
* currently in standby. Standby state can only be reported when the Google Cast device is connected to a TV or
|
||||
* AVR with CEC support.
|
||||
*/
|
||||
public static final int STANDBY_STATE_UNKNOWN = -1;
|
||||
|
||||
/**
|
||||
* A constant indicating that the Google Cast device is currently in standby.
|
||||
*/
|
||||
public static final int STANDBY_STATE_YES = 1;
|
||||
|
||||
|
||||
/**
|
||||
* Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the Cast features.
|
||||
*/
|
||||
public static final Api<CastOptions> API = new Api<CastOptions>(new CastApiClientBuilder());
|
||||
|
||||
/**
|
||||
* An implementation of the CastApi interface. The interface is used to interact with a cast device.
|
||||
*/
|
||||
public static final Cast.CastApi CastApi = new CastApiImpl();
|
||||
|
||||
private Cast() {
|
||||
}
|
||||
|
||||
public interface ApplicationConnectionResult extends Result {
|
||||
ApplicationMetadata getApplicationMetadata();
|
||||
|
||||
String getApplicationStatus();
|
||||
|
||||
String getSessionId();
|
||||
|
||||
boolean getWasLaunched();
|
||||
}
|
||||
|
||||
public interface CastApi {
|
||||
int getActiveInputState(GoogleApiClient client);
|
||||
|
||||
ApplicationMetadata getApplicationMetadata(GoogleApiClient client);
|
||||
|
||||
String getApplicationStatus(GoogleApiClient client);
|
||||
|
||||
int getStandbyState(GoogleApiClient client);
|
||||
|
||||
double getVolume(GoogleApiClient client);
|
||||
|
||||
boolean isMute(GoogleApiClient client);
|
||||
|
||||
PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client);
|
||||
|
||||
PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client, String applicationId, String sessionId);
|
||||
|
||||
PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client, String applicationId);
|
||||
|
||||
PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId, LaunchOptions launchOptions);
|
||||
|
||||
PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId);
|
||||
|
||||
@Deprecated
|
||||
PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId, boolean relaunchIfRunning);
|
||||
|
||||
PendingResult<Status> leaveApplication(GoogleApiClient client);
|
||||
|
||||
void removeMessageReceivedCallbacks(GoogleApiClient client, String namespace) throws IOException;
|
||||
|
||||
void requestStatus(GoogleApiClient client) throws IOException;
|
||||
|
||||
PendingResult<Status> sendMessage(GoogleApiClient client, String namespace, String message);
|
||||
|
||||
void setMessageReceivedCallbacks(GoogleApiClient client, String namespace, Cast.MessageReceivedCallback callbacks) throws IOException;
|
||||
|
||||
void setMute(GoogleApiClient client, boolean mute) throws IOException;
|
||||
|
||||
void setVolume(GoogleApiClient client, double volume) throws IOException;
|
||||
|
||||
PendingResult<Status> stopApplication(GoogleApiClient client);
|
||||
|
||||
PendingResult<Status> stopApplication(GoogleApiClient client, String sessionId);
|
||||
}
|
||||
|
||||
public static class CastOptions implements Api.ApiOptions.HasOptions {
|
||||
private final CastDevice castDevice;
|
||||
private final Listener castListener;
|
||||
private final boolean verboseLoggingEnabled;
|
||||
|
||||
public CastOptions(CastDevice castDevice, Listener castListener, boolean verboseLoggingEnabled) {
|
||||
this.castDevice = castDevice;
|
||||
this.castListener = castListener;
|
||||
this.verboseLoggingEnabled = verboseLoggingEnabled;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Builder builder(CastDevice castDevice, Listener castListener) {
|
||||
return new Builder(castDevice, castListener);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final CastDevice castDevice;
|
||||
private final Listener castListener;
|
||||
private boolean verboseLoggingEnabled;
|
||||
|
||||
public Builder(CastDevice castDevice, Listener castListener) {
|
||||
this.castDevice = castDevice;
|
||||
this.castListener = castListener;
|
||||
}
|
||||
|
||||
public CastOptions build() {
|
||||
return new CastOptions(castDevice, castListener, verboseLoggingEnabled);
|
||||
}
|
||||
|
||||
public Builder setVerboseLoggingEnabled(boolean verboseLoggingEnabled) {
|
||||
this.verboseLoggingEnabled = verboseLoggingEnabled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Listener {
|
||||
public void onActiveInputStateChanged(int activeInputState) {
|
||||
|
||||
}
|
||||
|
||||
public void onApplicationDisconnected(int statusCode) {
|
||||
|
||||
}
|
||||
|
||||
public void onApplicationMetadataChanged(ApplicationMetadata applicationMetadata) {
|
||||
|
||||
}
|
||||
|
||||
public void onApplicationStatusChanged() {
|
||||
|
||||
}
|
||||
|
||||
public void onStandbyStateChanged(int standbyState) {
|
||||
|
||||
}
|
||||
|
||||
public void onVolumeChanged() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public interface MessageReceivedCallback {
|
||||
void onMessageReceived(CastDevice castDevice, String namespace, String message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.google.android.gms.common.images.WebImage;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@PublicApi
|
||||
public class CastDevice extends AutoSafeParcelable {
|
||||
private static final String EXTRA_CAST_DEVICE = "com.google.android.gms.cast.EXTRA_CAST_DEVICE";
|
||||
|
||||
public CastDevice () {
|
||||
}
|
||||
|
||||
public CastDevice (
|
||||
String id, String name, InetAddress host, int port, String
|
||||
deviceVersion, String friendlyName, String modelName, String
|
||||
iconPath, int status, int capabilities) {
|
||||
this.deviceId = id;
|
||||
this.address = host.getHostAddress();
|
||||
this.servicePort = port;
|
||||
this.deviceVersion = deviceVersion;
|
||||
this.friendlyName = friendlyName;
|
||||
this.icons = new ArrayList<WebImage>();
|
||||
this.icons.add(new WebImage(Uri.parse(String.format("http://%s:8008%s", this.address, iconPath))));
|
||||
this.modelName = modelName;
|
||||
this.capabilities = capabilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Video-output device capability.
|
||||
*/
|
||||
public static final int CAPABILITY_VIDEO_OUT = 1;
|
||||
|
||||
/**
|
||||
* Video-input device capability.
|
||||
*/
|
||||
public static final int CAPABILITY_VIDEO_IN = 2;
|
||||
|
||||
/**
|
||||
* Audio-output device capability.
|
||||
*/
|
||||
public static final int CAPABILITY_AUDIO_OUT = 4;
|
||||
|
||||
/**
|
||||
* Audio-input device capability.
|
||||
*/
|
||||
public static final int CAPABILITY_AUDIO_IN = 8;
|
||||
|
||||
@SafeParceled(1)
|
||||
private int versionCode = 3;
|
||||
|
||||
@SafeParceled(2)
|
||||
private String deviceId;
|
||||
|
||||
@SafeParceled(3)
|
||||
private String address;
|
||||
|
||||
@SafeParceled(4)
|
||||
private String friendlyName;
|
||||
|
||||
@SafeParceled(5)
|
||||
private String modelName;
|
||||
|
||||
@SafeParceled(6)
|
||||
private String deviceVersion;
|
||||
|
||||
@SafeParceled(7)
|
||||
private int servicePort;
|
||||
|
||||
@SafeParceled(value = 8, subClass = WebImage.class)
|
||||
private ArrayList<WebImage> icons;
|
||||
|
||||
@SafeParceled(9)
|
||||
private int capabilities;
|
||||
|
||||
@SafeParceled(10)
|
||||
private int status;
|
||||
|
||||
@SafeParceled(11)
|
||||
private String unknown; // TODO: Need to figure this one out
|
||||
|
||||
public String getDeviceId() {
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
public String getDeviceVersion() {
|
||||
return deviceVersion;
|
||||
}
|
||||
|
||||
public String getFriendlyName() {
|
||||
return friendlyName;
|
||||
}
|
||||
|
||||
public static CastDevice getFromBundle(Bundle extras) {
|
||||
if (extras == null) {
|
||||
return null;
|
||||
}
|
||||
extras.setClassLoader(CastDevice.class.getClassLoader());
|
||||
return extras.getParcelable(EXTRA_CAST_DEVICE);
|
||||
}
|
||||
|
||||
public WebImage getIcon(int preferredWidth, int preferredHeight) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<WebImage> getIcons() {
|
||||
return icons;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public String getModelName() {
|
||||
return modelName;
|
||||
}
|
||||
|
||||
public int getServicePort() {
|
||||
return servicePort;
|
||||
}
|
||||
|
||||
public boolean hasCapabilities(int[] capabilities) {
|
||||
for (int capability : capabilities) {
|
||||
if (!this.hasCapability(capability)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasCapability(int capability) {
|
||||
return (capability & capabilities) == capability;
|
||||
}
|
||||
|
||||
public boolean hasIcons() {
|
||||
return !icons.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isOnLocalNetwork() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSameDevice(CastDevice castDevice) {
|
||||
return TextUtils.equals(castDevice.deviceId, deviceId);
|
||||
}
|
||||
|
||||
public void putInBundle(Bundle bundle) {
|
||||
bundle.putParcelable(EXTRA_CAST_DEVICE, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CastDevice{" +
|
||||
"deviceId=" + this.deviceId +
|
||||
", address=" + address +
|
||||
", friendlyName=" + friendlyName +
|
||||
", modelName=" + modelName +
|
||||
", deviceVersion=" + deviceVersion +
|
||||
", servicePort=" + servicePort +
|
||||
(icons == null ? "" : (", icons=" + icons.toString())) +
|
||||
", capabilities=" + capabilities +
|
||||
", status=" + status +
|
||||
"}";
|
||||
}
|
||||
|
||||
public static Creator<CastDevice> CREATOR = new AutoCreator<CastDevice>(CastDevice.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
public class CastDeviceStatus extends AutoSafeParcelable {
|
||||
|
||||
public CastDeviceStatus() {
|
||||
}
|
||||
|
||||
public CastDeviceStatus(double volume, boolean mute, int activeInputState, ApplicationMetadata applicationMetadata, int standbyState) {
|
||||
this.volume = volume;
|
||||
this.mute = mute;
|
||||
this.activeInputState = activeInputState;
|
||||
this.applicationMetadata = applicationMetadata;
|
||||
this.standbyState = standbyState;
|
||||
}
|
||||
|
||||
@SafeParceled(1)
|
||||
private int versionCode = 1;
|
||||
@SafeParceled(2)
|
||||
private double volume;
|
||||
@SafeParceled(3)
|
||||
private boolean mute;
|
||||
@SafeParceled(4)
|
||||
private int activeInputState;
|
||||
@SafeParceled(5)
|
||||
private ApplicationMetadata applicationMetadata;
|
||||
@SafeParceled(6)
|
||||
private int standbyState;
|
||||
|
||||
public static final Creator<CastDeviceStatus> CREATOR = new AutoCreator<CastDeviceStatus>(CastDeviceStatus.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Intent constants for use with the Cast MediaRouteProvider. This class also contains utility methods for creating
|
||||
* a control category for discovering Cast media routes that support a specific app and/or set of namespaces, to be
|
||||
* used with MediaRouteSelector.
|
||||
*/
|
||||
public final class CastMediaControlIntent {
|
||||
@Deprecated
|
||||
public static final String CATEGORY_CAST = "com.google.android.gms.cast.CATEGORY_CAST";
|
||||
public static final String ACTION_SYNC_STATUS = "com.google.android.gms.cast.ACTION_SYNC_STATUS";
|
||||
|
||||
/**
|
||||
* The application ID for the Cast Default Media Receiver.
|
||||
*/
|
||||
public static final String DEFAULT_MEDIA_RECEIVER_APPLICATION_ID = "CC1AD845";
|
||||
|
||||
/**
|
||||
* An error code indicating that a Cast request has failed.
|
||||
*/
|
||||
public static final int ERROR_CODE_REQUEST_FAILED = 1;
|
||||
|
||||
/**
|
||||
* An error code indicating that the request could not be processed because the session could not be started.
|
||||
*/
|
||||
public static final int ERROR_CODE_SESSION_START_FAILED = 2;
|
||||
|
||||
/**
|
||||
* An error code indicating that the connection to the Cast device has been lost, but the system is actively
|
||||
* trying to re-establish the connection.
|
||||
*/
|
||||
public static final int ERROR_CODE_TEMPORARILY_DISCONNECTED = 3;
|
||||
|
||||
/**
|
||||
* The extra that contains the ID of the application to launch for an
|
||||
* {@link android.support.v7.media.MediaContolIntent#ACTION_START_SESSION} request.
|
||||
* The value is expected to be a String.
|
||||
*/
|
||||
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_CUSTOM_DATA = "com.google.android.gms.cast.EXTRA_CUSTOM_DATA";
|
||||
|
||||
/**
|
||||
* The extra that indicates whether debug logging should be enabled for the Cast session. The value is expected to be a boolean.
|
||||
*/
|
||||
public static final String EXTRA_DEBUG_LOGGING_ENABLED = "com.google.android.gms.cast.EXTRA_DEBUG_LOGGING_ENABLED";
|
||||
|
||||
/**
|
||||
* n error bundle extra for the error code. The value is an integer, and will be one of the {@code ERROR_CODE_*}
|
||||
* constants declared in this class.
|
||||
*/
|
||||
public static final String EXTRA_ERROR_CODE = "com.google.android.gms.cast.EXTRA_ERROR_CODE";
|
||||
|
||||
public static final String CATEGORY_CAST_REMOTE_PLAYBACK = "com.google.android.gms.cast.CATEGORY_CAST_REMOTE_PLAYBACK";
|
||||
|
||||
private CastMediaControlIntent() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom control category for discovering Cast devices that support running the specified app, independent of whether the app is running or not.
|
||||
*
|
||||
* @param applicationId The application ID of the receiver application.
|
||||
*/
|
||||
public static String categoryForCast(String applicationId) {
|
||||
return CATEGORY_CAST + "/" + applicationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given category is a custom control category for cast devices, specific to an application ID.
|
||||
*
|
||||
* @param applicationId The application ID of the receiver application.
|
||||
*/
|
||||
public static boolean isCategoryForCast(String category) {
|
||||
if (category == null) {
|
||||
return false;
|
||||
}
|
||||
return category.startsWith(CATEGORY_CAST + "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom control category for discovering Cast devices meeting both application ID and namespace
|
||||
* restrictions. See {@link #categoryForCast(Collection)} and {@link #categoryForCast(String)} for more details.
|
||||
*/
|
||||
public static String categoryForCast(String applicationId, Collection<String> namespaces) {
|
||||
return CATEGORY_CAST + "" + applicationId + "/" + TextUtils.join(",", namespaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom control category for discovering Cast devices currently running an application which supports the specified namespaces. Apps supporting additional namespaces beyond those specified here are still considered supported.
|
||||
*/
|
||||
public static String categoryForCast(Collection<String> namespaces) {
|
||||
return CATEGORY_CAST + "//" + TextUtils.join(",", namespaces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom control category for discovering Cast devices which support the default Android remote
|
||||
* playback actions using the specified Cast player. If the Default Media Receiver is desired, use
|
||||
* {@link #DEFAULT_MEDIA_RECEIVER_APPLICATION_ID} as the applicationId.
|
||||
*
|
||||
* @param applicationId The application ID of the receiver application.
|
||||
*/
|
||||
public static String categoryForRemotePlayback(String applicationId) {
|
||||
return CATEGORY_CAST_REMOTE_PLAYBACK + "/" + applicationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a custom control category for discovering Cast devices which support the Default Media Receiver.
|
||||
*/
|
||||
public static String categoryForRemotePlayback() {
|
||||
return CATEGORY_CAST_REMOTE_PLAYBACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an RFC-5646 language tag string fo the given locale.
|
||||
*/
|
||||
public static String languageTagForLocale(Locale locale) {
|
||||
StringBuilder sb = new StringBuilder(locale.getLanguage());
|
||||
if (!TextUtils.isEmpty(locale.getCountry())) sb.append('-').append(locale.getCountry());
|
||||
if (!TextUtils.isEmpty(locale.getVariant())) sb.append('-').append(locale.getVariant());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Presentation;
|
||||
import android.content.Context;
|
||||
import android.view.Display;
|
||||
|
||||
@TargetApi(17)
|
||||
public class CastPresentation extends Presentation {
|
||||
public CastPresentation(Context outerContext, Display display) {
|
||||
super(outerContext, display);
|
||||
}
|
||||
|
||||
public CastPresentation(Context outerContext, Display display, int theme) {
|
||||
super(outerContext, display, theme);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.view.Display;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.Result;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
|
||||
import org.microg.gms.cast.CastRemoteDisplayApiClientBuilder;
|
||||
import org.microg.gms.cast.CastRemoteDisplayApiImpl;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
@PublicApi
|
||||
public final class CastRemoteDisplay {
|
||||
/**
|
||||
* Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the CastRemoteDisplay features.
|
||||
*/
|
||||
public static final Api<CastRemoteDisplayOptions> API = new Api<CastRemoteDisplayOptions>(new CastRemoteDisplayApiClientBuilder());
|
||||
|
||||
/**
|
||||
* An implementation of the CastRemoteDisplayAPI interface. The interface is used to interact with a cast device.
|
||||
*/
|
||||
public static final CastRemoteDisplayApi CastApi = new CastRemoteDisplayApiImpl();
|
||||
|
||||
private CastRemoteDisplay() {
|
||||
}
|
||||
|
||||
public static final class CastRemoteDisplayOptions implements Api.ApiOptions.HasOptions {
|
||||
private CastDevice castDevice;
|
||||
private CastRemoteDisplaySessionCallbacks callbacks;
|
||||
|
||||
private CastRemoteDisplayOptions(CastDevice castDevice, CastRemoteDisplaySessionCallbacks callbacks) {
|
||||
this.castDevice = castDevice;
|
||||
this.callbacks = callbacks;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private CastDevice castDevice;
|
||||
private CastRemoteDisplaySessionCallbacks callbacks;
|
||||
|
||||
public Builder(CastDevice castDevice, CastRemoteDisplaySessionCallbacks callbacks) {
|
||||
this.castDevice = castDevice;
|
||||
this.callbacks = callbacks;
|
||||
}
|
||||
|
||||
public CastRemoteDisplayOptions build() {
|
||||
return new CastRemoteDisplayOptions(castDevice, callbacks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface CastRemoteDisplaySessionCallbacks {
|
||||
void onRemoteDisplayEnded(Status status);
|
||||
}
|
||||
|
||||
public interface CastRemoteDisplaySessionResult extends Result {
|
||||
Display getPresentationDisplay();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
|
||||
public interface CastRemoteDisplayApi {
|
||||
PendingResult<CastRemoteDisplay.CastRemoteDisplaySessionResult> startRemoteDisplay(GoogleApiClient apiClient, String applicationId);
|
||||
|
||||
PendingResult<CastRemoteDisplay.CastRemoteDisplaySessionResult> stopRemoteDisplay(GoogleApiClient apiClient);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class CastRemoteDisplayLocalService extends Service {
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
public final class CastStatusCodes {
|
||||
public static final int APPLICATION_NOT_FOUND = 2004;
|
||||
public static final int APPLICATION_NOT_RUNNING = 2005;
|
||||
public static final int AUTHENTICATION_FAILED = 2000;
|
||||
public static final int CANCELED = 2002;
|
||||
public static final int ERROR_SERVICE_CREATION_FAILED = 2200;
|
||||
public static final int ERROR_SERVICE_DISCONNECTED = 2201;
|
||||
public static final int FAILED = 2100;
|
||||
public static final int INTERNAL_ERROR = 8;
|
||||
public static final int INTERRUPTED = 14;
|
||||
public static final int INVALID_REQUEST = 2001;
|
||||
public static final int MESSAGE_SEND_BUFFER_TOO_FULL = 2007;
|
||||
public static final int MESSAGE_TOO_LARGE = 2006;
|
||||
public static final int NETWORK_ERROR = 7;
|
||||
public static final int NOT_ALLOWED = 2003;
|
||||
public static final int REPLACED = 2103;
|
||||
public static final int SUCCESS = 0;
|
||||
public static final int TIMEOUT = 15;
|
||||
public static final int UNKNOWN_ERROR = 13;
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import android.os.Parcel;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Credentials data used to identify the credentials of the sender.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class CredentialsData extends AbstractSafeParcelable {
|
||||
/**
|
||||
* The credentials type indicating it comes from an Android sender.
|
||||
*/
|
||||
public static final String CREDENTIALS_TYPE_ANDROID = "android";
|
||||
/**
|
||||
* The credentials type indicating it comes from the cloud (i.e. assistant).
|
||||
*/
|
||||
public static final String CREDENTIALS_TYPE_CLOUD = "cloud";
|
||||
/**
|
||||
* The credentials type indicating it comes from an iOS sender.
|
||||
*/
|
||||
public static final String CREDENTIALS_TYPE_IOS = "ios";
|
||||
/**
|
||||
* The credentials type indicating it comes from a Web sender.
|
||||
*/
|
||||
public static final String CREDENTIALS_TYPE_WEB = "web";
|
||||
|
||||
@Field(1)
|
||||
final String credentials;
|
||||
@Field(2)
|
||||
final String credentialsType;
|
||||
|
||||
@Constructor
|
||||
CredentialsData(@Param(1) String credentials, @Param(2) String credentialsType) {
|
||||
this.credentials = credentials;
|
||||
this.credentialsType = credentialsType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the application-specific blob which identifies and possibly authenticates the user that's requesting to launch
|
||||
* or join an receiver app. This field may be {@code null}.
|
||||
* <p>
|
||||
* For requests sent from Assistant, it is an OAuth 2 token.
|
||||
* <p>
|
||||
* For requests sent from mobile senders, it is set by sender apps.
|
||||
*/
|
||||
public String getCredentials() {
|
||||
return credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the credentials. This field may be {@code null}.
|
||||
* <p>
|
||||
* This could be one of the {@code CREDENTIALS_TYPE_*} constants or custom-defined.
|
||||
*/
|
||||
public String getCredentialsType() {
|
||||
return credentialsType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
CREATOR.writeToParcel(this, out, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CredentialsData> CREATOR = findCreator(CredentialsData.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
public class JoinOptions extends AutoSafeParcelable {
|
||||
@SafeParceled(1)
|
||||
private int versionCode = 1;
|
||||
@SafeParceled(2)
|
||||
private int connectionType = 0;
|
||||
|
||||
public static Creator<JoinOptions> CREATOR = new AutoCreator<JoinOptions>(JoinOptions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* An object that holds options that affect how a receiver application is launched. See
|
||||
* {@link Cast.CastApi#launchApplication(GoogleApiClient, String, LaunchOptions)}.
|
||||
*/
|
||||
public class LaunchOptions extends AutoSafeParcelable {
|
||||
@Field(1)
|
||||
private int versionCode = 1;
|
||||
@Field(2)
|
||||
private boolean relaunchIfRunning = false;
|
||||
@Field(3)
|
||||
private String language;
|
||||
@Field(4)
|
||||
private boolean androidReceiverCompatible = false;
|
||||
@Field(5)
|
||||
private CredentialsData credentialsData = null;
|
||||
|
||||
/**
|
||||
* The constructor of {@link LaunchOptions}.
|
||||
*/
|
||||
public LaunchOptions() {
|
||||
Locale locale = Locale.getDefault();
|
||||
StringBuilder sb = new StringBuilder(locale.getLanguage());
|
||||
if (!locale.getCountry().isEmpty()) {
|
||||
sb.append("-").append(locale.getCountry());
|
||||
}
|
||||
if (!locale.getVariant().isEmpty()) {
|
||||
sb.append("-").append(locale.getVariant());
|
||||
}
|
||||
language = sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the sender app supports casting to an Android TV app.
|
||||
*/
|
||||
public boolean getAndroidReceiverCompatible() {
|
||||
return androidReceiverCompatible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link CredentialsData}.
|
||||
*/
|
||||
public CredentialsData getCredentialsData() {
|
||||
return credentialsData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language, or {@code null} if none was specified.
|
||||
*/
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "relaunch if running" flag.
|
||||
*/
|
||||
public boolean getRelaunchIfRunning() {
|
||||
return relaunchIfRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language to be used by the receiver application. If not specified, the sender device's default language is used.
|
||||
*
|
||||
* @param language The language
|
||||
*/
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the "relaunch if running" flag. If the flag is set, the receiver application will be relaunched even if it is already running. The flag is not set by default.
|
||||
*/
|
||||
public void setRelaunchIfRunning(boolean relaunchIfRunning) {
|
||||
this.relaunchIfRunning = relaunchIfRunning;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("LaunchOptions")
|
||||
.field("relaunchIfRunning", relaunchIfRunning)
|
||||
.field("language", language)
|
||||
.field("androidReceiverCompatible", androidReceiverCompatible)
|
||||
.end();
|
||||
}
|
||||
|
||||
public static Creator<LaunchOptions> CREATOR = new AutoCreator<LaunchOptions>(LaunchOptions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2021, microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.cast;
|
||||
|
||||
import org.microg.safeparcel.AutoSafeParcelable;
|
||||
import org.microg.safeparcel.SafeParceled;
|
||||
|
||||
public class RequestItem extends AutoSafeParcelable {
|
||||
@Field(2)
|
||||
public String url;
|
||||
@Field(3)
|
||||
public int protocolType;
|
||||
@Field(4)
|
||||
public int initialTime;
|
||||
@Field(5)
|
||||
public String hlsSegmentFormat;
|
||||
|
||||
public static Creator<RequestItem> CREATOR = new AutoCreator<RequestItem>(RequestItem.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: CC-BY-4.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
/**
|
||||
* Contains classes for interacting with Google Cast devices.
|
||||
*/
|
||||
package com.google.android.gms.cast;
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.google.android.gms.cast.Cast;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import org.microg.gms.common.api.ApiClientBuilder;
|
||||
import com.google.android.gms.common.internal.ClientSettings;
|
||||
import com.google.android.gms.common.api.internal.ConnectionCallbacks;
|
||||
import com.google.android.gms.common.api.internal.OnConnectionFailedListener;
|
||||
|
||||
public class CastApiClientBuilder implements ApiClientBuilder<Cast.CastOptions> {
|
||||
@Override
|
||||
public Api.Client build(Cast.CastOptions options, Context context, Looper looper, ClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||
return new CastClientImpl(context, options, callbacks, connectionFailedListener);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import com.google.android.gms.cast.ApplicationMetadata;
|
||||
import com.google.android.gms.cast.Cast;
|
||||
import com.google.android.gms.cast.LaunchOptions;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
// TODO
|
||||
public class CastApiImpl implements Cast.CastApi {
|
||||
@Override
|
||||
public int getActiveInputState(GoogleApiClient client) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplicationMetadata getApplicationMetadata(GoogleApiClient client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getApplicationStatus(GoogleApiClient client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStandbyState(GoogleApiClient client) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getVolume(GoogleApiClient client) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMute(GoogleApiClient client) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client, String applicationId, String sessionId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client, String applicationId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId, LaunchOptions launchOptions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId, boolean relaunchIfRunning) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Status> leaveApplication(GoogleApiClient client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMessageReceivedCallbacks(GoogleApiClient client, String namespace) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestStatus(GoogleApiClient client) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Status> sendMessage(GoogleApiClient client, String namespace, String message) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMessageReceivedCallbacks(GoogleApiClient client, String namespace, Cast.MessageReceivedCallback callbacks) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMute(GoogleApiClient client, boolean mute) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVolume(GoogleApiClient client, double volume) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Status> stopApplication(GoogleApiClient client) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<Status> stopApplication(GoogleApiClient client, String sessionId) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.android.gms.cast.Cast;
|
||||
|
||||
import org.microg.gms.common.DummyApiClient;
|
||||
import com.google.android.gms.common.api.internal.ConnectionCallbacks;
|
||||
import com.google.android.gms.common.api.internal.OnConnectionFailedListener;
|
||||
|
||||
public class CastClientImpl extends DummyApiClient {
|
||||
public CastClientImpl(Context context, Cast.CastOptions options, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
|
||||
import com.google.android.gms.cast.CastRemoteDisplay;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import org.microg.gms.common.DummyApiClient;
|
||||
import org.microg.gms.common.api.ApiClientBuilder;
|
||||
import com.google.android.gms.common.internal.ClientSettings;
|
||||
import com.google.android.gms.common.api.internal.ConnectionCallbacks;
|
||||
import com.google.android.gms.common.api.internal.OnConnectionFailedListener;
|
||||
|
||||
public class CastRemoteDisplayApiClientBuilder implements ApiClientBuilder<CastRemoteDisplay.CastRemoteDisplayOptions> {
|
||||
@Override
|
||||
public Api.Client build(CastRemoteDisplay.CastRemoteDisplayOptions options, Context context, Looper looper, ClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||
return new DummyApiClient();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2013-2017 microG Project Team
|
||||
*
|
||||
* 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 org.microg.gms.cast;
|
||||
|
||||
import com.google.android.gms.cast.CastRemoteDisplay;
|
||||
import com.google.android.gms.cast.CastRemoteDisplayApi;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.PendingResult;
|
||||
|
||||
public class CastRemoteDisplayApiImpl implements CastRemoteDisplayApi {
|
||||
@Override
|
||||
public PendingResult<CastRemoteDisplay.CastRemoteDisplaySessionResult> startRemoteDisplay(GoogleApiClient apiClient, String applicationId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingResult<CastRemoteDisplay.CastRemoteDisplaySessionResult> stopRemoteDisplay(GoogleApiClient apiClient) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue