2023-01-23 09:31:32 +01:00
|
|
|
package app.fedilab.android.activities;
|
2023-01-26 18:05:41 +01:00
|
|
|
/* Copyright 2023 Thomas Schneider
|
2023-01-23 09:31:32 +01:00
|
|
|
*
|
2023-01-26 18:05:41 +01:00
|
|
|
* This file is a part of Fedilab
|
2023-01-23 09:31:32 +01:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
2023-01-24 15:09:21 +01:00
|
|
|
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
2023-01-23 09:31:32 +01:00
|
|
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
|
|
* Public License for more details.
|
|
|
|
*
|
2023-01-24 15:09:21 +01:00
|
|
|
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
2023-01-23 09:31:32 +01:00
|
|
|
* see <http://www.gnu.org/licenses>. */
|
|
|
|
|
2023-01-26 18:05:41 +01:00
|
|
|
|
2023-01-23 09:31:32 +01:00
|
|
|
import android.content.BroadcastReceiver;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.IntentFilter;
|
2023-12-12 15:47:15 +01:00
|
|
|
import android.os.Build;
|
2023-01-23 09:31:32 +01:00
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.Looper;
|
|
|
|
import android.view.View;
|
|
|
|
|
2023-12-12 16:07:48 +01:00
|
|
|
import androidx.core.content.ContextCompat;
|
2023-12-12 17:27:05 +01:00
|
|
|
|
2023-01-23 09:31:32 +01:00
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.net.NetworkInterface;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.Enumeration;
|
|
|
|
import java.util.List;
|
|
|
|
|
2023-12-12 17:27:05 +01:00
|
|
|
import app.fedilab.android.BuildConfig;
|
2023-01-23 09:31:32 +01:00
|
|
|
import app.fedilab.android.R;
|
|
|
|
import app.fedilab.android.databinding.ActivityMainPeertubeBinding;
|
2023-01-25 15:14:42 +01:00
|
|
|
import app.fedilab.android.mastodon.activities.BaseActivity;
|
2023-01-23 09:31:32 +01:00
|
|
|
import app.fedilab.android.peertube.client.data.VideoData;
|
|
|
|
import app.fedilab.android.peertube.helper.Helper;
|
|
|
|
import su.litvak.chromecast.api.v2.ChromeCast;
|
|
|
|
import su.litvak.chromecast.api.v2.ChromeCasts;
|
|
|
|
import su.litvak.chromecast.api.v2.ChromeCastsListener;
|
|
|
|
import su.litvak.chromecast.api.v2.MediaStatus;
|
|
|
|
|
2023-01-25 15:14:42 +01:00
|
|
|
public abstract class PeertubeBaseMainActivity extends BaseActivity implements ChromeCastsListener {
|
2023-01-23 09:31:32 +01:00
|
|
|
|
|
|
|
public static List<ChromeCast> chromeCasts;
|
|
|
|
public static ChromeCast chromeCast;
|
|
|
|
public static boolean chromecastActivated = false;
|
|
|
|
protected ActivityMainPeertubeBinding binding;
|
|
|
|
private BroadcastReceiver manage_chromecast;
|
|
|
|
private VideoData.Video castedTube;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
binding = ActivityMainPeertubeBinding.inflate(getLayoutInflater());
|
|
|
|
View view = binding.getRoot();
|
|
|
|
setContentView(view);
|
|
|
|
ChromeCastsListener chromeCastsListener = this;
|
|
|
|
ChromeCasts.registerListener(chromeCastsListener);
|
|
|
|
|
|
|
|
|
|
|
|
binding.castClose.setOnClickListener(v -> {
|
|
|
|
Intent intentBC = new Intent(Helper.RECEIVE_CAST_SETTINGS);
|
|
|
|
Bundle b = new Bundle();
|
|
|
|
b.putInt("displayed", 0);
|
|
|
|
intentBC.putExtras(b);
|
2023-12-12 17:27:05 +01:00
|
|
|
intentBC.setPackage(BuildConfig.APPLICATION_ID);
|
|
|
|
sendBroadcast(intentBC);
|
2023-01-23 09:31:32 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
binding.castTogglePlay.setOnClickListener(v -> {
|
|
|
|
if (chromeCast != null) {
|
|
|
|
new Thread(() -> {
|
|
|
|
try {
|
|
|
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
|
|
|
Runnable myRunnable = () -> binding.castTogglePlay.setVisibility(View.GONE);
|
|
|
|
mainHandler.post(myRunnable);
|
|
|
|
int icon = -1;
|
|
|
|
if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PLAYING) {
|
|
|
|
chromeCast.pause();
|
|
|
|
icon = R.drawable.ic_baseline_play_arrow_32;
|
|
|
|
} else if (chromeCast.getMediaStatus().playerState == MediaStatus.PlayerState.PAUSED) {
|
|
|
|
chromeCast.play();
|
|
|
|
icon = R.drawable.ic_baseline_pause_32;
|
|
|
|
}
|
|
|
|
if (icon != -1) {
|
|
|
|
int finalIcon = icon;
|
|
|
|
myRunnable = () -> binding.castTogglePlay.setImageResource(finalIcon);
|
|
|
|
mainHandler.post(myRunnable);
|
|
|
|
}
|
|
|
|
myRunnable = () -> binding.castTogglePlay.setVisibility(View.VISIBLE);
|
|
|
|
mainHandler.post(myRunnable);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}).start();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
manage_chromecast = new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
|
|
|
Bundle b = intent.getExtras();
|
|
|
|
assert b != null;
|
|
|
|
int state = b.getInt("state_asked", -1);
|
|
|
|
int displayed = b.getInt("displayed", -1);
|
2023-01-24 18:08:58 +01:00
|
|
|
castedTube = (VideoData.Video) b.getSerializable("castedTube");
|
2023-01-23 09:31:32 +01:00
|
|
|
|
|
|
|
if (state == 1) {
|
|
|
|
discoverCast();
|
|
|
|
} else if (state == 0) {
|
|
|
|
new Thread(() -> {
|
|
|
|
try {
|
|
|
|
if (chromeCast != null) {
|
|
|
|
chromeCast.stopApp();
|
|
|
|
chromeCast.disconnect();
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}).start();
|
|
|
|
}
|
|
|
|
if (displayed == 1) {
|
|
|
|
chromecastActivated = true;
|
|
|
|
if (castedTube != null) {
|
|
|
|
binding.castInfo.setVisibility(View.VISIBLE);
|
|
|
|
Helper.loadGiF(PeertubeBaseMainActivity.this, castedTube.getThumbnailPath(), binding.castView);
|
|
|
|
binding.castTitle.setText(castedTube.getTitle());
|
|
|
|
binding.castDescription.setText(castedTube.getDescription());
|
|
|
|
}
|
|
|
|
} else if (displayed == 0) {
|
|
|
|
chromecastActivated = false;
|
|
|
|
binding.castInfo.setVisibility(View.GONE);
|
|
|
|
new Thread(() -> {
|
|
|
|
try {
|
|
|
|
if (chromeCast != null) {
|
|
|
|
chromeCast.stopApp();
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}).start();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2023-12-12 16:07:48 +01:00
|
|
|
ContextCompat.registerReceiver(PeertubeBaseMainActivity.this, manage_chromecast, new IntentFilter(Helper.RECEIVE_CAST_SETTINGS), ContextCompat.RECEIVER_NOT_EXPORTED);
|
2023-01-23 09:31:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void newChromeCastDiscovered(ChromeCast chromeCast) {
|
|
|
|
if (chromeCasts == null) {
|
|
|
|
chromeCasts = new ArrayList<>();
|
|
|
|
chromeCasts.add(chromeCast);
|
|
|
|
} else {
|
|
|
|
boolean canBeAdded = true;
|
|
|
|
for (ChromeCast cast : chromeCasts) {
|
|
|
|
if (cast.getName().compareTo(chromeCast.getName()) == 0) {
|
|
|
|
canBeAdded = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (canBeAdded) {
|
|
|
|
chromeCasts.add(chromeCast);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
if (chromeCast.isAppRunning(Helper.CAST_ID) && chromeCast.getMediaStatus() != null && chromeCast.getMediaStatus().playerState != null) {
|
|
|
|
if (binding.castInfo.getVisibility() == View.GONE) {
|
|
|
|
binding.castInfo.setVisibility(View.VISIBLE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void chromeCastRemoved(ChromeCast chromeCast) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
|
|
|
super.onDestroy();
|
|
|
|
ChromeCasts.unregisterListener(this);
|
|
|
|
if (manage_chromecast != null) {
|
2023-12-17 17:41:17 +01:00
|
|
|
try {
|
|
|
|
unregisterReceiver(manage_chromecast);
|
|
|
|
} catch (IllegalArgumentException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2023-01-23 09:31:32 +01:00
|
|
|
new Thread(() -> {
|
|
|
|
if (chromeCasts != null && chromeCasts.size() > 0) {
|
|
|
|
for (ChromeCast cast : chromeCasts) {
|
|
|
|
try {
|
|
|
|
cast.stopApp();
|
|
|
|
cast.disconnect();
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}).start();
|
|
|
|
}
|
|
|
|
if (chromeCasts != null) {
|
|
|
|
chromeCasts = null;
|
|
|
|
}
|
|
|
|
if (chromeCast != null) {
|
|
|
|
chromeCast = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Method for discovering cast devices
|
|
|
|
public void discoverCast() {
|
|
|
|
|
|
|
|
new Thread(() -> {
|
|
|
|
if (chromeCasts != null) {
|
|
|
|
for (ChromeCast cast : chromeCasts) {
|
|
|
|
try {
|
|
|
|
cast.disconnect();
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
chromeCasts = null;
|
|
|
|
}
|
|
|
|
chromeCasts = new ArrayList<>();
|
|
|
|
try {
|
|
|
|
List<NetworkInterface> interfaces;
|
|
|
|
interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
|
|
|
|
for (NetworkInterface ni : interfaces) {
|
|
|
|
if ((!ni.isLoopback()) && ni.isUp() && (ni.getName().equals("wlan0"))) {
|
|
|
|
Enumeration<InetAddress> inetAddressEnumeration = ni.getInetAddresses();
|
|
|
|
while (inetAddressEnumeration.hasMoreElements()) {
|
|
|
|
InetAddress inetAddress = inetAddressEnumeration.nextElement();
|
|
|
|
ChromeCasts.restartDiscovery(inetAddress);
|
|
|
|
int tryFind = 0;
|
|
|
|
while (ChromeCasts.get().isEmpty() && tryFind < 5) {
|
|
|
|
try {
|
|
|
|
//noinspection BusyWait
|
|
|
|
Thread.sleep(1000);
|
|
|
|
tryFind++;
|
|
|
|
} catch (InterruptedException ignored) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ChromeCasts.stopDiscovery();
|
|
|
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
|
|
|
Runnable myRunnable = this::invalidateOptionsMenu;
|
|
|
|
mainHandler.post(myRunnable);
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}).start();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|