Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit a80b2636 authored by Marvin W.'s avatar Marvin W. 🐿️ Committed by GitHub
Browse files

Merge pull request #555 from armills/cast-mvp

MVP Cast API
parents 0480bbbb c7e9b299
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ gen/
bin/
build/
.gradle/
.idea/
user.gradle
local.properties
.directory
+18 −0
Original line number Diff line number Diff line
@@ -23,15 +23,27 @@ def useMapbox() {
}

dependencies {
    implementation 'com.android.support:multidex:1.0.3'
    implementation "com.android.support:support-v4:$supportLibraryVersion"
    implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
    implementation "com.android.support:mediarouter-v7:$supportLibraryVersion"
    implementation "com.squareup.wire:wire-runtime:1.6.1"
    implementation "com.takisoft.fix:preference-v7:$supportLibraryVersion.0"
    implementation "de.hdodenhof:circleimageview:1.3.0"
    implementation "org.conscrypt:conscrypt-android:2.0.0"
    // 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"

    // Specified manually due to
    // https://github.com/vitalidze/chromecast-java-api-v2/issues/91
    api "org.slf4j:slf4j-api:1.7.25"
    api "uk.uuid.slf4j:slf4j-android:1.7.25-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')
@@ -76,6 +88,8 @@ android {
        minSdkVersion androidMinSdk()
        targetSdkVersion androidTargetSdk()

        multiDexEnabled true

        ndk {
            abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
        }
@@ -102,6 +116,10 @@ android {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    packagingOptions {
        exclude 'META-INF/ASL2.0'
    }
}

if (file('user.gradle').exists()) {
+25 −3
Original line number Diff line number Diff line
@@ -92,13 +92,22 @@
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST" tools:ignore="ProtectedPermissions"/>

    <uses-sdk tools:overrideLibrary="com.takisoft.fix.support.v7.preference,android.support.graphics.drawable.animated,android.arch.lifecycle,android.arch.lifecycle.livedata.core,android.arch.lifecycle.viewmodel,android.arch.core"/>
    <uses-sdk tools:overrideLibrary="
        com.takisoft.fix.support.v7.preference,
        android.support.graphics.drawable.animated,
        android.arch.lifecycle,
        android.arch.lifecycle.livedata.core,
        android.arch.lifecycle.viewmodel,
        android.arch.core,
        android.support.v7.mediarouter,
        android.support.v7.palette" />

    <application
        android:allowBackup="false"
        android:extractNativeLibs="false"
        android:icon="@mipmap/ic_core_service_app"
        android:label="@string/gms_app_name">
        android:label="@string/gms_app_name"
        android:name="android.support.multidex.MultiDexApplication">
        <meta-data
            android:name="fake-signature"
            android:value="@string/fake_signature"/>
@@ -392,6 +401,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"
@@ -611,6 +628,12 @@
            </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>

        <service android:name="org.microg.gms.DummyService">
            <intent-filter>
                <action android:name="com.google.android.gms.plus.service.START"/>
@@ -619,7 +642,6 @@
                <action android:name="com.google.android.gms.appstate.service.START"/>
                <action android:name="com.google.android.gms.ads.service.START"/>
                <action android:name="com.google.android.gms.accounts.ACCOUNT_SERVICE"/>
                <action android:name="com.google.android.gms.cast.service.BIND_CAST_DEVICE_CONTROLLER_SERVICE"/>
                <action android:name="com.google.android.gms.identity.service.BIND"/>
                <action android:name="com.google.android.gms.wearable.BIND"/>
                <action android:name="com.google.android.gms.auth.service.START"/>
+154 −0
Original line number Diff line number Diff line
/*
 * 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.IBinder;
import android.os.RemoteException;
import android.support.v7.media.MediaControlIntent;
import android.support.v7.media.MediaRouteSelector;
import android.support.v7.media.MediaRouter;
import android.util.Log;

import com.google.android.gms.cast.CastMediaControlIntent;
import com.google.android.gms.cast.framework.CastOptions;
import com.google.android.gms.cast.framework.IAppVisibilityListener;
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.cast.framework.ISessionProvider;
import com.google.android.gms.dynamic.IObjectWrapper;
import com.google.android.gms.dynamic.ObjectWrapper;

import java.util.Map;
import java.util.HashMap;

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<String, ISessionProvider> sessionProviders = new HashMap<String, ISessionProvider>();
    public ISessionProvider defaultSessionProvider;

    private MediaRouteSelector mergedSelector;

    public CastContextImpl(IObjectWrapper context, CastOptions options, IMediaRouter router, Map<String, IBinder> sessionProviders) throws RemoteException {
        this.context = (Context) ObjectWrapper.unwrap(context);
        this.options = options;
        this.router = router;
        for (Map.Entry<String, IBinder> entry : sessionProviders.entrySet()) {
            this.sessionProviders.put(entry.getKey(), ISessionProvider.Stub.asInterface(entry.getValue()));
        }

        String receiverApplicationId = options.getReceiverApplicationId();
        String defaultCategory = CastMediaControlIntent.categoryForCast(receiverApplicationId);

        this.defaultSessionProvider = this.sessionProviders.get(defaultCategory);

        // TODO: This should incorporate passed options
        this.mergedSelector = new MediaRouteSelector.Builder()
            .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
            .addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
            .addControlCategory(defaultCategory)
            .build();
    }

    @Override
    public Bundle getMergedSelectorAsBundle() throws RemoteException {
        return this.mergedSelector.asBundle();
    }

    @Override
    public void addVisibilityChangeListener(IAppVisibilityListener listener) {
        Log.d(TAG, "unimplemented Method: addVisibilityChangeListener");
    }

    @Override
    public void removeVisibilityChangeListener(IAppVisibilityListener listener) {
        Log.d(TAG, "unimplemented Method: removeVisibilityChangeListener");
    }

    @Override
    public boolean isApplicationVisible() throws RemoteException {
        Log.d(TAG, "unimplemented Method: isApplicationVisible");
        return true;
    }

    @Override
    public SessionManagerImpl getSessionManagerImpl() {
        if (this.sessionManager == null) {
            this.sessionManager = new SessionManagerImpl(this);
        }
        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 setReceiverApplicationId(String receiverApplicationId, Map sessionProvidersByCategory) throws RemoteException {
        Log.d(TAG, "unimplemented Method: setReceiverApplicationId");
    }

    public Context getContext() {
        return this.context;
    }

    public IMediaRouter getRouter() {
        return this.router;
    }

    public MediaRouteSelector getMergedSelector() {
        return this.mergedSelector;
    }

    public CastOptions getOptions() {
        return this.options;
    }

    @Override
    public IObjectWrapper getWrappedThis() throws RemoteException {
        return ObjectWrapper.wrap(this);
    }
}
+11 −8
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package com.google.android.gms.cast.framework.internal;

import android.content.Context;
import android.os.RemoteException;
import android.support.v7.media.MediaRouter;
import android.util.Log;

import com.google.android.gms.cast.framework.CastOptions;
@@ -27,6 +29,10 @@ import com.google.android.gms.cast.framework.IReconnectionService;
import com.google.android.gms.cast.framework.ISession;
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;
@@ -38,21 +44,18 @@ public class CastDynamiteModuleImpl extends ICastDynamiteModule.Stub {
    private static final String TAG = CastDynamiteModuleImpl.class.getSimpleName();

    @Override
    public ICastContext newCastContextImpl(IObjectWrapper context, CastOptions options, IMediaRouter router, Map map) throws RemoteException {
        Log.d(TAG, "unimplemented Method: newCastContextImpl");
        return null;
    public ICastContext newCastContextImpl(IObjectWrapper context, CastOptions options, IMediaRouter router, Map sessionProviders) throws RemoteException {
        return new CastContextImpl(context, options, router, sessionProviders);
    }

    @Override
    public ISession newSessionImpl(String s1, String s2, ISessionProxy proxy) throws RemoteException {
        Log.d(TAG, "unimplemented Method: newSessionImpl");
        return null;
    public ISession newSessionImpl(String category, String sessionId, ISessionProxy proxy) throws RemoteException {
        return new SessionImpl(category, sessionId, proxy);
    }

    @Override
    public ICastSession newCastSessionImpl(CastOptions options, IObjectWrapper session, ICastConnectionController controller) throws RemoteException {
        Log.d(TAG, "unimplemented Method: newCastSessionImpl");
        return null;
        return new CastSessionImpl(options, session, controller);
    }

    @Override
Loading