More interface details for the cast framework

This commit is contained in:
Adam Mills 2018-04-18 16:01:49 -04:00
parent 40d6bf7320
commit fc74261655
No known key found for this signature in database
GPG Key ID: 7733DCD6D0428689
15 changed files with 564 additions and 63 deletions

1
.gitignore vendored
View File

@ -3,6 +3,7 @@ gen/
bin/
build/
.gradle/
.idea/
user.gradle
local.properties
.directory

View File

@ -37,7 +37,7 @@ def androidCompileSdk() { return 27 }
def androidTargetSdk() { return 27 }
def androidMinSdk() { return 9 }
def androidMinSdk() { return 14 }
def versionCode() {
def stdout = new ByteArrayOutputStream()

2
extern/GmsApi vendored

@ -1 +1 @@
Subproject commit db0be6ba010f52b4d12e69aed2482c38a3c2406c
Subproject commit a811b2f64572a10e34a0fd9a0eac189735849f5b

2
extern/GmsLib vendored

@ -1 +1 @@
Subproject commit 90e9b7b79dcaddfce887f87b94f80adeed8791e6
Subproject commit a3b7236b5efa09bcd2bcb65c4946b41c63e3e98f

View File

@ -19,12 +19,14 @@ apply plugin: 'com.android.application'
dependencies {
implementation "com.android.support:support-v4:$supportLibraryVersion"
implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
implementation "com.android.support:mediarouter-v7:$supportLibraryVersion"
implementation "com.takisoft.fix:preference-v7:$supportLibraryVersion.0"
implementation "de.hdodenhof:circleimageview:1.3.0"
implementation "com.squareup.wire:wire-runtime:1.6.1"
implementation project(':microg-ui-tools')
implementation project(':play-services-api')
implementation project(':play-services-cast-api')
implementation project(':play-services-wearable')
implementation project(':unifiednlp-base')
implementation project(':wearable-lib')

View File

@ -395,6 +395,14 @@
</intent-filter>
</activity>
<!-- Cast -->
<service android:name="com.google.android.gms.cast.media.CastMediaRouteProviderService">
<intent-filter>
<action android:name="android.media.MediaRouteProviderService" />
</intent-filter>
</service>
<!-- Chimera spoof -->
<provider
android:name="org.microg.gms.ChimeraSpoofProvider"

View File

@ -0,0 +1,126 @@
/*
* 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.framework.internal;
import android.content.Context;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.v7.media.MediaControlIntent;
import android.support.v7.media.MediaRouteSelector;
import android.util.Log;
import com.google.android.gms.cast.framework.CastOptions;
import com.google.android.gms.cast.framework.ICastContext;
import com.google.android.gms.cast.framework.IDiscoveryManager;
import com.google.android.gms.cast.framework.ISessionManager;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import java.util.Map;
public class CastContextImpl extends ICastContext.Stub {
private static final String TAG = CastContextImpl.class.getSimpleName();
private SessionManagerImpl sessionManager;
private DiscoveryManagerImpl discoveryManager;
private Context context;
private CastOptions options;
private IMediaRouter router;
private Map map;
private MediaRouteSelector mergedSelector;
public CastContextImpl(IObjectWrapper context, CastOptions options, IMediaRouter router, Map map) {
Log.d(TAG, "Creating new cast context");
this.context = (Context) ObjectWrapper.unwrap(context);
this.options = options;
this.router = router;
this.map = map;
// TODO: This should incorporate passed options
this.mergedSelector = new MediaRouteSelector.Builder()
.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
.build();
}
@Override
public Bundle getMergedSelectorAsBundle() throws RemoteException {
return this.mergedSelector.asBundle();
}
@Override
public boolean isApplicationVisible() throws RemoteException {
Log.d(TAG, "unimplemented Method: isApplicationVisible");
return true;
}
@Override
public ISessionManager getSessionManagerImpl() throws RemoteException {
if (this.sessionManager == null) {
this.sessionManager = new SessionManagerImpl();
}
return this.sessionManager;
}
@Override
public IDiscoveryManager getDiscoveryManagerImpl() throws RemoteException {
if (this.discoveryManager == null) {
this.discoveryManager = new DiscoveryManagerImpl(this);
}
return this.discoveryManager;
}
@Override
public void destroy() throws RemoteException {
Log.d(TAG, "unimplemented Method: destroy");
}
@Override
public void onActivityResumed(IObjectWrapper activity) throws RemoteException {
Log.d(TAG, "unimplemented Method: onActivityResumed");
}
@Override
public void onActivityPaused(IObjectWrapper activity) throws RemoteException {
Log.d(TAG, "unimplemented Method: onActivityPaused");
}
@Override
public void unknown(String s1, Map m1) throws RemoteException {
Log.d(TAG, "unimplemented Method: unknown");
}
public Context getContext() {
return this.context;
}
public IMediaRouter getRouter() {
return this.router;
}
public MediaRouteSelector getMergedSelector() {
return this.mergedSelector;
}
@Override
public IObjectWrapper getWrappedThis() throws RemoteException {
return ObjectWrapper.wrap(this);
}
}

View File

@ -16,8 +16,10 @@
package com.google.android.gms.cast.framework.internal;
import android.content.Context;
import android.os.Bundle;
import android.os.RemoteException;
import android.support.v7.media.MediaRouter;
import android.util.Log;
import com.google.android.gms.cast.framework.CastOptions;
@ -26,14 +28,16 @@ import com.google.android.gms.cast.framework.ICastContext;
import com.google.android.gms.cast.framework.ICastSession;
import com.google.android.gms.cast.framework.IReconnectionService;
import com.google.android.gms.cast.framework.ISession;
import com.google.android.gms.cast.framework.ISessionManager;
import com.google.android.gms.cast.framework.ISessionProxy;
import com.google.android.gms.cast.framework.media.CastMediaOptions;
import com.google.android.gms.cast.framework.internal.CastContextImpl;
import com.google.android.gms.cast.framework.internal.CastSessionImpl;
import com.google.android.gms.cast.framework.internal.MediaRouterCallbackImpl;
import com.google.android.gms.cast.framework.internal.SessionImpl;
import com.google.android.gms.cast.framework.media.IMediaNotificationService;
import com.google.android.gms.cast.framework.media.internal.IFetchBitmapTask;
import com.google.android.gms.cast.framework.media.internal.IFetchBitmapTaskProgressPublisher;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import java.util.Map;
@ -42,77 +46,33 @@ public class CastDynamiteModuleImpl extends ICastDynamiteModule.Stub {
@Override
public ICastContext newCastContextImpl(IObjectWrapper context, CastOptions options, IMediaRouter router, Map map) throws RemoteException {
Log.d(TAG, "unimplemented Method: newCastContextImpl");
return new ICastContext.Stub() {
CastContextImpl castContextImpl = new CastContextImpl(context, options, router, map);
@Override
public Bundle getMergedSelectorAsBundle() throws RemoteException {
Log.d(TAG, "unimplemented Method: getMergedSelectorAsBundle");
return new Bundle();
}
// TODO: Find a home for this once the rest of the implementation
// becomes more clear. Uncomment this to enable discovery of devices.
// Note that the scan currently isn't ever disabled as part of the
// lifecycle, so we don't want to ship with this.
/*
Bundle selectorBundle = castContextImpl.getMergedSelector().asBundle();
@Override
public boolean isApplicationVisible() throws RemoteException {
Log.d(TAG, "unimplemented Method: isApplicationVisible");
return true;
}
router.clearCallbacks();
router.registerMediaRouterCallbackImpl(selectorBundle, new MediaRouterCallbackImpl());
router.addCallback(selectorBundle, MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
*/
@Override
public ISessionManager getSessionManager() throws RemoteException {
Log.d(TAG, "unimplemented Method: getSessionManager");
return new ISessionManager.Stub(){
@Override
public IObjectWrapper getWrappedCurrentSession() throws RemoteException {
Log.d(TAG, "unimplemented Method: getWrappedCurrentSession");
return ObjectWrapper.wrap(null);
}
@Override
public void endCurrentSession(boolean b, boolean stopCasting) throws RemoteException {
Log.d(TAG, "unimplemented Method: endCurrentSession");
}
@Override
public IObjectWrapper getWrappedThis() throws RemoteException {
Log.d(TAG, "unimplemented Method: getWrappedThis");
return ObjectWrapper.wrap(this);
}
};
}
@Override
public void destroy() throws RemoteException {
Log.d(TAG, "unimplemented Method: destroy");
}
@Override
public void onActivityResumed(IObjectWrapper activity) throws RemoteException {
Log.d(TAG, "unimplemented Method: onActivityResumed");
}
@Override
public void onActivityPaused(IObjectWrapper activity) throws RemoteException {
Log.d(TAG, "unimplemented Method: onActivityPaused");
}
};
return castContextImpl;
}
@Override
public ISession newSessionImpl(String s1, String s2, ISessionProxy proxy) throws RemoteException {
Log.d(TAG, "unimplemented Method: newSessionImpl");
return new ISession.Stub() {
};
return new SessionImpl();
}
@Override
public ICastSession newCastSessionImpl(CastOptions options, IObjectWrapper session, ICastConnectionController controller) throws RemoteException {
Log.d(TAG, "unimplemented Method: newCastSessionImpl");
return new ICastSession.Stub() {
};
return new CastSessionImpl();
}
@Override

View File

@ -0,0 +1,23 @@
/*
* 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.framework.internal;
import com.google.android.gms.cast.framework.ICastSession;
public class CastSessionImpl extends ICastSession.Stub {
private static final String TAG = CastSessionImpl.class.getSimpleName();
}

View File

@ -0,0 +1,69 @@
/*
* 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.framework.internal;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.cast.framework.IDiscoveryManager;
import com.google.android.gms.cast.framework.IDiscoveryManagerListener;
import com.google.android.gms.cast.framework.internal.CastContextImpl;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import java.util.Set;
import java.util.HashSet;
public class DiscoveryManagerImpl extends IDiscoveryManager.Stub {
private static final String TAG = DiscoveryManagerImpl.class.getSimpleName();
private CastContextImpl castContextImpl;
private Set discoveryManagerListeners = new HashSet();
public DiscoveryManagerImpl(CastContextImpl castContextImpl) {
Log.d(TAG, "Creating new discovery manager");
this.castContextImpl = castContextImpl;
}
@Override
public void startDiscovery() {
Log.d(TAG, "unimplemented Method: startDiscovery");
}
@Override
public void stopDiscovery() {
Log.d(TAG, "unimplemented Method: stopDiscovery");
}
@Override
public void addDiscoveryManagerListener(IDiscoveryManagerListener listener) {
Log.d(TAG, "unimplemented Method: addDiscoveryManagerListener");
this.discoveryManagerListeners.add(listener);
}
@Override
public void removeDiscoveryManagerListener(IDiscoveryManagerListener listener) {
Log.d(TAG, "unimplemented Method: removeDiscoveryManagerListener");
this.discoveryManagerListeners.remove(listener);
}
@Override
public IObjectWrapper getWrappedThis() throws RemoteException {
return ObjectWrapper.wrap(this);
}
}

View File

@ -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.framework.internal;
import android.os.Bundle;
import android.util.Log;
public class MediaRouterCallbackImpl extends IMediaRouterCallback.Stub {
private static final String TAG = MediaRouterCallbackImpl.class.getSimpleName();
@Override
public void onRouteAdded(String routeId, Bundle extras) {
Log.d(TAG, "unimplemented Method: onRouteAdded");
}
@Override
public void onRouteChanged(String routeId, Bundle extras) {
Log.d(TAG, "unimplemented Method: onRouteChanged");
}
@Override
public void onRouteRemoved(String routeId, Bundle extras) {
Log.d(TAG, "unimplemented Method: onRouteRemoved");
}
@Override
public void onRouteSelected(String routeId, Bundle extras) {
Log.d(TAG, "unimplemented Method: onRouteSelected");
}
@Override
public void unknown(String routeId, Bundle extras) {
Log.d(TAG, "unimplemented Method: unknown");
}
@Override
public void onRouteUnselected(String routeId, Bundle extras, int reason) {
Log.d(TAG, "unimplemented Method: onRouteUnselected");
}
}

View File

@ -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.framework.internal;
import android.util.Log;
import com.google.android.gms.cast.framework.ISession;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
public class SessionImpl extends ISession.Stub {
private static final String TAG = SessionImpl.class.getSimpleName();
@Override
public void notifySessionEnded(int error) {
Log.d(TAG, "unimplemented Method: notifySessionEnded");
}
@Override
public boolean isConnected() {
Log.d(TAG, "unimplemented Method: isConnected");
return true;
}
@Override
public boolean isResuming() {
Log.d(TAG, "unimplemented Method: isResuming");
return false;
}
@Override
public IObjectWrapper getWrappedThis() {
return ObjectWrapper.wrap(this);
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.framework.internal;
import android.os.RemoteException;
import android.util.Log;
import com.google.android.gms.cast.framework.ICastStateListener;
import com.google.android.gms.cast.framework.ISessionManager;
import com.google.android.gms.cast.framework.ISessionManagerListener;
import com.google.android.gms.cast.framework.internal.SessionImpl;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;
import java.util.Set;
import java.util.HashSet;
public class SessionManagerImpl extends ISessionManager.Stub {
private static final String TAG = SessionManagerImpl.class.getSimpleName();
private Set sessionManagerListeners = new HashSet();
private Set castStateListeners = new HashSet();
private SessionImpl currentSession;
@Override
public IObjectWrapper getWrappedCurrentSession() throws RemoteException {
Log.d(TAG, "unimplemented Method: getWrappedCurrentSession");
return ObjectWrapper.wrap(this.currentSession);
}
@Override
public void endCurrentSession(boolean b, boolean stopCasting) throws RemoteException {
Log.d(TAG, "unimplemented Method: endCurrentSession");
}
@Override
public void addSessionManagerListener(ISessionManagerListener listener) {
Log.d(TAG, "unimplemented Method: addSessionManagerListener");
this.sessionManagerListeners.add(listener);
}
@Override
public void removeSessionManagerListener(ISessionManagerListener listener) {
Log.d(TAG, "unimplemented Method: removeSessionManagerListener");
this.sessionManagerListeners.remove(listener);
}
@Override
public void addCastStateListener(ICastStateListener listener) {
Log.d(TAG, "unimplemented Method: addCastStateListener");
this.castStateListeners.add(listener);
}
@Override
public void removeCastStateListener(ICastStateListener listener) {
Log.d(TAG, "unimplemented Method: removeCastStateListener");
this.castStateListeners.remove(listener);
}
@Override
public IObjectWrapper getWrappedThis() throws RemoteException {
return ObjectWrapper.wrap(this);
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.support.v7.media.MediaRouteProviderService;
import android.support.v7.media.MediaRouteProvider;
import android.util.Log;
public class CastMediaRouteProviderService extends MediaRouteProviderService {
private static final String TAG = CastMediaRouteProviderService.class.getSimpleName();
@Override
public MediaRouteProvider onCreateMediaRouteProvider() {
return new CastMediaRouteProvider(this);
}
}

View File

@ -0,0 +1,103 @@
/*
* 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.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.media.MediaControlIntent;
import android.support.v7.media.MediaRouteDescriptor;
import android.support.v7.media.MediaRouteDiscoveryRequest;
import android.support.v7.media.MediaRouteProvider;
import android.support.v7.media.MediaRouteProviderDescriptor;
import android.support.v7.media.MediaRouter;
import android.util.Log;
import com.google.android.gms.common.images.WebImage;
import com.google.android.gms.cast.CastDevice;
import java.util.ArrayList;
import java.net.InetAddress;
import java.net.Inet4Address;
public class CastMediaRouteProvider extends MediaRouteProvider {
private static final String TAG = CastMediaRouteProvider.class.getSimpleName();
public CastMediaRouteProvider(Context context) {
super(context);
Log.d(TAG, "unimplemented Method: CastMediaRouteProvider");
// Uncomment this to create the mock device
// publishRoutes();
}
/**
* TODO: Mock control filters for chromecast; Will likely need to be
* adjusted.
*/
private static final ArrayList<IntentFilter> CONTROL_FILTERS;
static {
IntentFilter f2 = new IntentFilter();
f2.addCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK);
f2.addAction(MediaControlIntent.ACTION_PLAY);
CONTROL_FILTERS = new ArrayList<IntentFilter>();
CONTROL_FILTERS.add(f2);
}
@Override
public void onDiscoveryRequestChanged(MediaRouteDiscoveryRequest request) {
Log.d(TAG, "unimplemented Method: onDiscoveryRequestChanged");
}
@Override
public RouteController onCreateRouteController(String routeId) {
Log.d(TAG, "unimplemented Method: onCreateRouteController");
return null;
}
/**
* TODO: Currently this method simply publishes a single cast route for
* testing.
*/
private void publishRoutes() {
Log.d(TAG, "unimplemented Method: publishRoutes");
Bundle extras = new Bundle();
CastDevice castDevice = new CastDevice("abc123");
castDevice.putInBundle(extras);
MediaRouteDescriptor routeDescriptor1 = new MediaRouteDescriptor.Builder(
"abc123",
"Rotue Friendly Name")
.setDescription("Chromecast")
.addControlFilters(CONTROL_FILTERS)
.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();
MediaRouteProviderDescriptor providerDescriptor =
new MediaRouteProviderDescriptor.Builder()
.addRoute(routeDescriptor1)
.build();
this.setDescriptor(providerDescriptor);
}
}