lbry-android/src/main/java/io/lbry/browser/LbrynetService.java

227 lines
8.1 KiB
Java

package io.lbry.browser;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStream;
import org.kivy.android.PythonService;
import org.renpy.android.AssetExtract;
import org.renpy.android.ResourceManager;
/**
* This service class is based on the auto-generated P4A service class
* which changes the service start type to START_STICKY and lets it run
* properly as a background service.
*
* @author akinwale
* @version 0.1
*/
public class LbrynetService extends PythonService {
private static final int SERVICE_NOTIFICATION_GROUP_ID = -1;
public static final String ACTION_STOP_SERVICE = "io.lbry.browser.ACTION_STOP_SERVICE";
public static final String GROUP_SERVICE = "io.lbry.browser.GROUP_SERVICE";
public static final String NOTIFICATION_CHANNEL_ID = "io.lbry.browser.DAEMON_NOTIFICATION_CHANNEL";
public static String TAG = "LbrynetService";
public static LbrynetService serviceInstance;
private BroadcastReceiver stopServiceReceiver;
@Override
public boolean canDisplayNotification() {
return true;
}
@Override
public void onCreate() {
super.onCreate();
// Register the stop service receiver
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_STOP_SERVICE);
stopServiceReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
LbrynetService.this.stopSelf();
}
};
registerReceiver(stopServiceReceiver, intentFilter);
}
@Override
protected void doStartForeground(Bundle extras) {
String serviceTitle = extras.getString("serviceTitle");
String serviceDescription = "The LBRY service is running in the background.";
Context context = getApplicationContext();
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
NOTIFICATION_CHANNEL_ID, "LBRY Browser", NotificationManager.IMPORTANCE_LOW);
channel.setDescription("LBRY service notification channel");
channel.setShowBadge(false);
notificationManager.createNotificationChannel(channel);
}
Intent contextIntent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, contextIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent stopIntent = new Intent(ACTION_STOP_SERVICE);
PendingIntent stopPendingIntent = PendingIntent.getBroadcast(context, 0, stopIntent, 0);
// Create the notification group
NotificationCompat.Builder groupBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
groupBuilder.setContentTitle("LBRY Browser")
.setColor(ContextCompat.getColor(context, R.color.lbrygreen))
.setSmallIcon(R.drawable.ic_lbry)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setGroup(GROUP_SERVICE)
.setGroupSummary(true);
notificationManager.notify(SERVICE_NOTIFICATION_GROUP_ID, groupBuilder.build());
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
Notification notification = builder.setColor(ContextCompat.getColor(context, R.color.lbrygreen))
.setContentIntent(pendingIntent)
.setContentTitle(serviceTitle)
.setContentText(serviceDescription)
.setGroup(GROUP_SERVICE)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_lbry)
.setOngoing(true)
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "Stop", stopPendingIntent)
.build();
startForeground(1, notification);
}
@Override
public int startType() {
return START_STICKY;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Assign service instance
serviceInstance = this;
// Extract files
File app_root_file = new File(getAppRoot());
unpackData("private", app_root_file);
if (intent == null) {
intent = ServiceHelper.buildIntent(
getApplicationContext(), "", LbrynetService.class, "lbrynetservice");
}
// Register broadcast receiver
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
if (stopServiceReceiver != null) {
unregisterReceiver(stopServiceReceiver);
stopServiceReceiver = null;
}
serviceInstance = null;
}
public String getAppRoot() {
String app_root = getApplicationContext().getFilesDir().getAbsolutePath() + "/app";
return app_root;
}
public void recursiveDelete(File f) {
if (f.isDirectory()) {
for (File r : f.listFiles()) {
recursiveDelete(r);
}
}
f.delete();
}
public void unpackData(final String resource, File target) {
Log.v(TAG, "UNPACKING!!! " + resource + " " + target.getName());
// The version of data in memory and on disk.
ResourceManager resourceManager = new ResourceManager(getApplicationContext());
String data_version = resourceManager.getString(resource + "_version");
String disk_version = null;
Log.v(TAG, "Data version is " + data_version);
// If no version, no unpacking is necessary.
if (data_version == null) {
return;
}
// Check the current disk version, if any.
String filesDir = target.getAbsolutePath();
String disk_version_fn = filesDir + "/" + resource + ".version";
try {
byte buf[] = new byte[64];
InputStream is = new FileInputStream(disk_version_fn);
int len = is.read(buf);
disk_version = new String(buf, 0, len);
is.close();
} catch (Exception e) {
disk_version = "";
}
// If the disk data is out of date, extract it and write the
// version file.
// if (! data_version.equals(disk_version)) {
if (! data_version.equals(disk_version)) {
Log.v(TAG, "Extracting " + resource + " assets.");
recursiveDelete(target);
target.mkdirs();
AssetExtract ae = new AssetExtract(getApplicationContext());
if (!ae.extractTar(resource + ".mp3", target.getAbsolutePath())) {
//toastError("Could not extract " + resource + " data.");
Log.e(TAG, "Could not extract " + resource + " data.");
}
try {
// Write .nomedia.
new File(target, ".nomedia").createNewFile();
// Write version file.
FileOutputStream os = new FileOutputStream(disk_version_fn);
os.write(data_version.getBytes());
os.close();
} catch (Exception e) {
Log.w("python", e);
}
}
}
}