135 lines
4.5 KiB
Java
135 lines
4.5 KiB
Java
package space.rocketnine.xenia;
|
|
|
|
import android.app.Notification;
|
|
import android.app.NotificationChannel;
|
|
import android.app.NotificationManager;
|
|
import android.app.PendingIntent;
|
|
import android.app.Service;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.os.Build;
|
|
import android.os.Handler;
|
|
import android.os.IBinder;
|
|
import android.util.Base64;
|
|
import android.util.Log;
|
|
import android.widget.Toast;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
|
|
import space.rocketnine.gmitohtml.Gmitohtml;
|
|
|
|
public class XeniaService extends Service {
|
|
private final String channelID = "space.rocketnine.xenia";
|
|
public Context context = this;
|
|
private final String channelName = "Xenia";
|
|
private final String channelDescription = "Foreground service";
|
|
private final Handler handler = new Handler();
|
|
private final long timeout = 600; // Seconds
|
|
|
|
private final Runnable shutDown = () -> {
|
|
Intent intent = new Intent(getApplicationContext(), XeniaService.class);
|
|
getApplication().stopService(intent);
|
|
|
|
int pid = android.os.Process.myPid();
|
|
android.os.Process.killProcess(pid);
|
|
};
|
|
|
|
private final Runnable checkTimeout = () -> {
|
|
if ((System.currentTimeMillis() / 1000) - Gmitohtml.lastRequestTime() >= timeout) {
|
|
Toast.makeText(getApplicationContext(), "Shutting Xenia down due to inactivity", Toast.LENGTH_LONG).show();
|
|
|
|
handler.postDelayed(shutDown, 60000);
|
|
return;
|
|
}
|
|
|
|
scheduleCheckTimeout();
|
|
};
|
|
|
|
private void scheduleCheckTimeout() {
|
|
handler.postDelayed(checkTimeout, 60000);
|
|
}
|
|
|
|
private void createNotificationChannel() {
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
CharSequence name = channelName;
|
|
String description = channelDescription;
|
|
int importance = NotificationManager.IMPORTANCE_DEFAULT;
|
|
NotificationChannel channel = new NotificationChannel(channelID, name, importance);
|
|
channel.setDescription(description);
|
|
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
|
notificationManager.createNotificationChannel(channel);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onCreate() {
|
|
Log.d("xenia", "service oncreate");
|
|
|
|
createNotificationChannel();
|
|
|
|
Notification.Builder builder = new Notification.Builder(this);
|
|
if (Build.VERSION.SDK_INT >= 26) {
|
|
builder.setChannelId(channelID);
|
|
}
|
|
builder.setSmallIcon(R.drawable.ic_stat_name);
|
|
builder.setContentText("Xenia is running. Tap to open");
|
|
|
|
Intent notificationIntent = new Intent(this, MainActivity.class);
|
|
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
|
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
|
|
|
|
builder.setContentIntent(pendingIntent);
|
|
|
|
startForeground(1337, builder.build());
|
|
}
|
|
|
|
@Override
|
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
Log.d("xenia", "service starting");
|
|
|
|
SharedPreferences prefs = getSharedPreferences("xenia", Context.MODE_PRIVATE);
|
|
Set<String> sites = prefs.getStringSet("certs", new HashSet<String>());
|
|
for (String site : sites) {
|
|
try {
|
|
String certificate = prefs.getString("cert_" + site, "");
|
|
if (!certificate.isEmpty()) {
|
|
certificate = new String(Base64.decode(certificate, Base64.DEFAULT));
|
|
}
|
|
|
|
String privateKey = prefs.getString("key_" + site, "");
|
|
if (!privateKey.isEmpty()) {
|
|
privateKey = new String(Base64.decode(privateKey, Base64.DEFAULT));
|
|
}
|
|
|
|
Gmitohtml.setClientCertificate(site, certificate.getBytes(), privateKey.getBytes());
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
try {
|
|
Gmitohtml.startDaemon("127.0.0.1:1967");
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
scheduleCheckTimeout();
|
|
|
|
// If we get killed, after returning from here, restart
|
|
return START_STICKY;
|
|
}
|
|
|
|
@Override
|
|
public IBinder onBind(Intent intent) {
|
|
// We don't provide binding, so return null
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public void onDestroy() {
|
|
Log.d("xenia", "service destroyed");
|
|
}
|
|
}
|