Skip to content

Commit

Permalink
Basic Rust-based foreground service
Browse files Browse the repository at this point in the history
  • Loading branch information
vi committed Aug 16, 2023
1 parent 1490974 commit 939ea90
Show file tree
Hide file tree
Showing 10 changed files with 743 additions and 20 deletions.
10 changes: 10 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,13 @@ android {
dependencies {

}
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'

cargo {
module = "../wgserv"
libname = "wgserv"
// targets = ["arm", "arm64", "x86", "x86_64"]
targets = ["arm64"]
apiLevel = 21
profile = "release"
}
28 changes: 24 additions & 4 deletions app/src/main/java/org/vi_server/wgserver/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

Expand All @@ -26,22 +27,41 @@ protected void onCreate(Bundle savedInstanceState) {
EditText t = findViewById(R.id.tConfig);
String config = t.getText().toString();

intent.putExtra("config", config);
long instance = Native.create();
String ret = Native.setConfig(instance, config);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ctx.startForegroundService(intent);
TextView s = findViewById(R.id.tStatus);
if (ret != null && !ret.isEmpty()) {
s.setText(ret);
} else {
ctx.startService(intent);
intent.putExtra("instance", instance);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ctx.startForegroundService(intent);
} else {
ctx.startService(intent);
}
s.setText("started");
}

});
}
{
Button b = findViewById(R.id.bStop);
b.setOnClickListener(view -> {
TextView s = findViewById(R.id.tStatus);
Intent intent = new Intent(ctx, Serv.class);
ctx.stopService(intent);
s.setText("stopped");
});
}

{
Button b = findViewById(R.id.bSampleConfig);
b.setOnClickListener(view -> {
EditText t = findViewById(R.id.tConfig);
t.setText(Native.getSampleConfig());
});
}
}
}
23 changes: 23 additions & 0 deletions app/src/main/java/org/vi_server/wgserver/Native.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.vi_server.wgserver;

public class Native {
static {
System.loadLibrary("wgserv");
}

public static native long create();

/// Empty or null string = no error
public static native String setConfig(long instance, String toml_config);

/// Block thread and start it for real
///
/// Empty or null string means no error
public static native String run(long instance);

/// Stop and deallocate the instance
/// May be called from other thread
public static native void destroy(long instance);

public static native String getSampleConfig();
}
39 changes: 26 additions & 13 deletions app/src/main/java/org/vi_server/wgserver/Serv.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager;
import android.util.Log;

public class Serv extends Service {
private static final String CHANNEL_DEFAULT_IMPORTANCE = "default";
private static final int ONGOING_NOTIFICATION_ID = 1;
private static Notification.Builder nb;
private static long instance = 0;
private static PowerManager.WakeLock wl;

@Override
Expand All @@ -29,7 +31,15 @@ public void onCreate() {

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String config = intent.getStringExtra("config");
if (instance != 0) {
Native.destroy(instance);
}
instance = intent.getLongExtra("instance", 0);
if (instance == 0) {
this.stopForeground(true);
this.stopSelf();
return super.onStartCommand(intent, flags, startId);
}

Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
Expand All @@ -47,9 +57,6 @@ public int onStartCommand(Intent intent, int flags, int startId) {

CharSequence notiftext = getText(R.string.service_desc);

boolean failed = false;

// start here

nb = new Notification.Builder(this)
.setContentTitle(getText(R.string.app_name))
Expand All @@ -60,24 +67,26 @@ public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nb.setChannelId(CHANNEL_DEFAULT_IMPORTANCE);
}
if (failed) {
nb.setContentText("Failed to start service");
}

Notification notification = nb.build();

startForeground(ONGOING_NOTIFICATION_ID, notification);

if (failed) {
this.stopForeground(true);
this.stopSelf();
return super.onStartCommand(intent, flags, startId);
}

PowerManager pm = (PowerManager)this.getSystemService(
Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "wgserver:wl");
wl.acquire();

new Thread(() -> {
String ret2 = Native.run(instance);
if (ret2 == null || ret2.isEmpty()) {
Log.i("WgServer","Background thread exited without signaling failure");
} else {
Log.w("WgServer", "Background thread existed with error: " + ret2);
}
this.stopSelf();
}).start();

return super.onStartCommand(intent, flags, startId);
}

Expand All @@ -88,6 +97,10 @@ public void onDestroy() {
wl.release();
wl = null;
}
if (instance != 0) {
Native.destroy(instance);
instance=0;
}
super.onDestroy();
}
}
22 changes: 20 additions & 2 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,21 @@
<Button
android:id="@+id/bStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="30pt"
android:text="Start" />

<Button
android:id="@+id/bStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="30pt"
android:text="Stop" />

<Button
android:id="@+id/bSampleConfig"
android:layout_width="wrap_content"
android:layout_height="30pt"
android:layout_weight="1"
android:text="Sample config" />
</LinearLayout>

<EditText
Expand All @@ -34,4 +41,15 @@
android:gravity="start|top"
android:inputType="textMultiLine" />

<Space
android:layout_width="match_parent"
android:layout_height="4pt"
android:background="#F51F9000" />

<TextView
android:id="@+id/tStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="idle" />

</LinearLayout>
11 changes: 10 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'org.mozilla.rust-android-gradle:plugin:0.9.3'
}
}
plugins {
id 'com.android.application' version '7.3.1' apply false
id 'com.android.library' version '7.3.1' apply false
Expand Down
1 change: 1 addition & 0 deletions wgserv/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
Loading

0 comments on commit 939ea90

Please sign in to comment.