Merge branch 'android-service' of dan/ui into master

This commit is contained in:
erinn 2019-06-25 09:46:30 -07:00 committed by Gogs
commit d85961bb14
7 changed files with 189 additions and 53 deletions

View File

@ -1,7 +1,9 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<manifest package="ca.openprivacy.cwtch.ui" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto"> <manifest package="ca.openprivacy.cwtch.ui" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="cwtch" android:icon="@drawable/ic_launcher"> <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="cwtch" android:icon="@drawable/ic_launcher">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="ca.openprivacy.cwtch.ui.CwtchActivity" android:label="cwtch" android:theme="@style/AppTheme" android:screenOrientation="unspecified" android:launchMode="singleTop" android:windowSoftInputMode="adjustResize"> <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name="ca.openprivacy.cwtch.ui.CwtchActivity"
android:label="cwtch" android:theme="@style/AppTheme" android:screenOrientation="unspecified" android:launchMode="singleTop" android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
@ -63,6 +65,48 @@
</activity> </activity>
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices --> <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
<service
android:name="ca.openprivacy.cwtch.ui.CwtchService"
android:process=":cwtchService">
<!--
<intent-filter>
<action android:name="ca.openprivacy.cwtch.ui.CwtchService"/>
</intent-filter>
-->
<!-- Application arguments -->
<meta-data android:name="android.app.arguments" android:value="-service"/>
<!-- Application arguments -->
<meta-data android:name="android.app.lib_name" android:value="go"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="1"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="1"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/bearer/libqandroidbearer.so:plugins/mediaservice/libqtmedia_android.so:lib/libQt5MultimediaQuick.so:lib/libQt5QuickParticles.so"/>
<meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroidBearer.jar:jar/QtMultimedia.jar"/>
<meta-data android:name="android.app.static_init_classes" android:value="org.qtproject.qt5.android.multimedia.QtMultimediaUtils"/>
<!-- Used to specify custom system library path to run with local system libs -->
<!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
<!-- Messages maps -->
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
<!-- Messages maps -->
<!-- Background running -->
<!-- <meta-data android:name="android.app.background_running" android:value="true"/> -->
<!-- Background running -->
</service>
</application> </application>
@ -72,6 +116,7 @@
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" />
<uses-feature android:glEsVersion="0x00020000" android:required="true"/> <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

View File

@ -4,8 +4,10 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.NotificationChannel; import android.app.NotificationChannel;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.util.Log; import android.util.Log;
import android.os.Bundle;
import android.content.ComponentName;
import static android.app.Notification.DEFAULT_LIGHTS; import static android.app.Notification.DEFAULT_LIGHTS;
import static android.app.Notification.DEFAULT_SOUND; import static android.app.Notification.DEFAULT_SOUND;
@ -18,19 +20,6 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.Build.VERSION.SDK_INT; import static android.os.Build.VERSION.SDK_INT;
import static android.app.Notification.CATEGORY_SERVICE; import static android.app.Notification.CATEGORY_SERVICE;
/*import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE;
import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE;
import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL;
import static android.support.v4.app.NotificationCompat.PRIORITY_LOW;
import static android.support.v4.app.NotificationCompat.PRIORITY_MIN;
import static android.support.v4.app.NotificationCompat.PRIORITY_DEFAULT;
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
import static android.support.v4.content.ContextCompat.getColor;*/
public class CwtchActivity extends org.qtproject.qt5.android.bindings.QtActivity public class CwtchActivity extends org.qtproject.qt5.android.bindings.QtActivity
{ {
private static NotificationManager m_notificationManager; private static NotificationManager m_notificationManager;
@ -50,11 +39,24 @@ public class CwtchActivity extends org.qtproject.qt5.android.bindings.QtActivity
private static String CONTENT_NOTIFICATION_ID_NAME = "content"; private static String CONTENT_NOTIFICATION_ID_NAME = "content";
public CwtchActivity() public CwtchActivity() {
{
m_instance = this; m_instance = this;
} }
// https://github.com/bbernhard/qtandroidservices_example/blob/master/source/java/MyCustomAppActivity.java
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
Log.i("CwtchActivity", "Starting service!");
Intent serviceIntent = new Intent(this, ca.openprivacy.cwtch.ui.CwtchService.class);
ComponentName ret = startService(serviceIntent);
if (ret == null) {
Log.i("CwtchActivity", "Started Service: FAILED with null");
} else {
Log.i("CwtchActivity", "Started Service: " + ret.flattenToString());
}
}
public static void notify(String s) public static void notify(String s)
{ {
if (m_notificationManager == null) { if (m_notificationManager == null) {

View File

@ -0,0 +1,15 @@
package ca.openprivacy.cwtch.ui;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
import android.content.Context;
import android.content.Intent;
import org.qtproject.qt5.android.bindings.QtService;
// https://github.com/bbernhard/qtandroidservices_example
public class CwtchService extends QtService {
}

View File

@ -6,6 +6,9 @@ import (
) )
func TorStatusPoller(setTorStatus func(int, string), acn connectivity.ACN) { func TorStatusPoller(setTorStatus func(int, string), acn connectivity.ACN) {
if acn == nil {
return
}
for { for {
time.Sleep(time.Second) time.Sleep(time.Second)

View File

@ -1,11 +1,11 @@
package gothings package android
import ( import (
"github.com/therecipe/qt/androidextras" "github.com/therecipe/qt/androidextras"
"github.com/therecipe/qt/core" "github.com/therecipe/qt/core"
) )
type AndroidCwtchActivity struct { type CwtchActivity struct {
core.QObject core.QObject
_ func() `constructor:"init"` _ func() `constructor:"init"`
@ -15,13 +15,13 @@ type AndroidCwtchActivity struct {
_ func(string) `slot:"updateAndroidNotification"` _ func(string) `slot:"updateAndroidNotification"`
} }
func (c *AndroidCwtchActivity) init() { func (c *CwtchActivity) init() {
c.createOngoingNotification() c.createOngoingNotification()
c.ConnectNotificationChanged(c.updateAndroidNotification) c.ConnectNotificationChanged(c.updateAndroidNotification)
} }
func (c *AndroidCwtchActivity) updateAndroidNotification(n string) { func (c *CwtchActivity) updateAndroidNotification(n string) {
var err = androidextras.QAndroidJniObject_CallStaticMethodVoid2Caught( var err = androidextras.QAndroidJniObject_CallStaticMethodVoid2Caught(
"ca/openprivacy/cwtch/ui/CwtchActivity", "ca/openprivacy/cwtch/ui/CwtchActivity",
@ -35,7 +35,7 @@ func (c *AndroidCwtchActivity) updateAndroidNotification(n string) {
} }
} }
func (c *AndroidCwtchActivity) createOngoingNotification() { func (c *CwtchActivity) createOngoingNotification() {
var err = androidextras.QAndroidJniObject_CallStaticMethodVoid2Caught( var err = androidextras.QAndroidJniObject_CallStaticMethodVoid2Caught(
"ca/openprivacy/cwtch/ui/CwtchActivity", "ca/openprivacy/cwtch/ui/CwtchActivity",

View File

@ -8,11 +8,13 @@ import (
) )
var CwtchApp app.Application var CwtchApp app.Application
var CwtchService app.ApplicationService
var EventBus event.Manager var EventBus event.Manager
var AppBus event.Manager var AppBus event.Manager
var ACN connectivity.ACN var ACN connectivity.ACN
var Peer libPeer.CwtchPeer var Peer libPeer.CwtchPeer
var CwtchDir string var CwtchDir string
var IPCBridge event.IPCBridge
type AckId struct { type AckId struct {
ID string ID string

131
main.go
View File

@ -2,12 +2,13 @@ package main
import ( import (
libapp "cwtch.im/cwtch/app" libapp "cwtch.im/cwtch/app"
"cwtch.im/cwtch/event/bridge"
"cwtch.im/ui/go/characters" "cwtch.im/ui/go/characters"
"cwtch.im/ui/go/gobjects" "cwtch.im/ui/go/gobjects"
"cwtch.im/ui/go/gothings" "cwtch.im/ui/go/gothings"
"cwtch.im/ui/go/gothings/android"
"cwtch.im/ui/go/the" "cwtch.im/ui/go/the"
"flag" "flag"
"fmt"
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity" "git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
"git.openprivacy.ca/openprivacy/libricochet-go/log" "git.openprivacy.ca/openprivacy/libricochet-go/log"
"github.com/therecipe/qt/core" "github.com/therecipe/qt/core"
@ -35,8 +36,10 @@ func init() {
} }
func main() { func main() {
log.Infoln("ui main()\n")
flagDebug := flag.Bool("debug", false, "turn on extra logging. WARNING: THIS MAY EXPOSE PRIVATE INFORMATION IN CONSOLE OUTPUT!") flagDebug := flag.Bool("debug", false, "turn on extra logging. WARNING: THIS MAY EXPOSE PRIVATE INFORMATION IN CONSOLE OUTPUT!")
flagLocal := flag.Bool("local", false, "load user interface from the local folder \"qml\" instead of the built-in UI") flagLocal := flag.Bool("local", false, "load user interface from the local folder \"qml\" instead of the built-in UI")
flagService := flag.Bool("service", false, "indicate this process should run as an android service")
flag.Parse() flag.Parse()
if *flagDebug { if *flagDebug {
@ -45,6 +48,60 @@ func main() {
log.SetLevel(log.LevelInfo) log.SetLevel(log.LevelInfo)
} }
// TESTING
log.SetLevel(log.LevelDebug)
log.ExcludeFromPattern("connection/connection")
log.ExcludeFromPattern("outbound/3dhauthchannel")
log.ExcludeFromPattern("event/eventmanager")
if os.Getenv("CWTCH_FOLDER") != "" {
the.CwtchDir = os.Getenv("CWTCH_FOLDER")
} else if runtime.GOOS == "android" {
the.CwtchDir = path.Join(androidBaseDir, "files")
} else {
usr, err := user.Current()
if err != nil {
log.Errorf("\nerror: could not load current user: %v\n", err)
os.Exit(1)
}
the.CwtchDir = path.Join(usr.HomeDir, ".cwtch")
}
the.ACN = nil
the.Peer = nil
the.IPCBridge = nil
the.CwtchApp = nil
the.CwtchService = nil
os.MkdirAll(the.CwtchDir, 0700)
if *flagService {
mainService()
} else {
mainUi(*flagLocal)
}
if the.ACN != nil {
the.ACN.Close()
}
}
func mainService() {
log.Infoln("I am the service")
log.Infoln("Starting a cwtch app...")
go loadNetworkingAndFiles(nil, true)
//app := androidextras.NewQAndroidService(len(os.Args), os.Args)
app := gui.NewQGuiApplication(len(os.Args), os.Args)
log.Infoln("Cwtch Service starting app.Exec")
app.Exec()
}
func mainUi(flagLocal bool) {
log.Infoln("I am the application")
app := gui.NewQGuiApplication(len(os.Args), os.Args)
// our globals // our globals
gcd := gothings.NewGrandCentralDispatcher(nil) gcd := gothings.NewGrandCentralDispatcher(nil)
gcd.SetOs(runtime.GOOS) gcd.SetOs(runtime.GOOS)
@ -64,13 +121,12 @@ func main() {
// this is to load local qml files quickly when developing // this is to load local qml files quickly when developing
var qmlSource *core.QUrl var qmlSource *core.QUrl
if *flagLocal { if flagLocal {
qmlSource = core.QUrl_FromLocalFile("./qml/main.qml") qmlSource = core.QUrl_FromLocalFile("./qml/main.qml")
} else { } else {
qmlSource = core.NewQUrl3("qrc:/qml/main.qml", 0) qmlSource = core.NewQUrl3("qrc:/qml/main.qml", 0)
} }
app := gui.NewQGuiApplication(len(os.Args), os.Args)
app.SetWindowIcon(gui.NewQIcon5(":/qml/images/cwtch-icon.png")) app.SetWindowIcon(gui.NewQIcon5(":/qml/images/cwtch-icon.png"))
// load english first so it becomes the default in case we don't have a .ts for the user's locale, or if it contains unfinished strings // load english first so it becomes the default in case we don't have a .ts for the user's locale, or if it contains unfinished strings
@ -111,33 +167,19 @@ func main() {
} }
engine.RootContext().SetContextProperty("gcd", gcd) engine.RootContext().SetContextProperty("gcd", gcd)
var androidCwtchActivity = gothings.NewAndroidCwtchActivity(nil) var androidCwtchActivity = android.NewCwtchActivity(nil)
engine.RootContext().SetContextProperty("androidCwtchActivity", androidCwtchActivity) engine.RootContext().SetContextProperty("androidCwtchActivity", androidCwtchActivity)
engine.Load(qmlSource) engine.Load(qmlSource)
the.ACN = nil
go loadNetworkingAndFiles(gcd) go loadNetworkingAndFiles(gcd, false)
log.Infoln("Cwtch App starting app.Exec")
app.Exec() app.Exec()
if the.ACN != nil {
the.ACN.Close()
}
} }
func loadNetworkingAndFiles(gcd *gothings.GrandCentralDispatcher) { func loadACN() {
if os.Getenv("CWTCH_FOLDER") != "" {
the.CwtchDir = os.Getenv("CWTCH_FOLDER")
} else if runtime.GOOS == "android" {
the.CwtchDir = path.Join(androidBaseDir, "files")
} else {
usr, err := user.Current()
if err != nil {
fmt.Printf("\nerror: could not load current user: %v\n", err)
os.Exit(1)
}
the.CwtchDir = path.Join(usr.HomeDir, ".cwtch")
}
torpath := "tor" torpath := "tor"
if runtime.GOOS == "android" { if runtime.GOOS == "android" {
torpath = path.Join(androidBaseDir, "lib/libtor.so") torpath = path.Join(androidBaseDir, "lib/libtor.so")
@ -163,12 +205,39 @@ func loadNetworkingAndFiles(gcd *gothings.GrandCentralDispatcher) {
log.Errorf("Could not start Tor: %v", err) log.Errorf("Could not start Tor: %v", err)
os.Exit(1) os.Exit(1)
} }
}
the.Peer = nil
os.MkdirAll(the.CwtchDir, 0700) func loadNetworkingAndFiles(gcd *gothings.GrandCentralDispatcher, service bool) {
if runtime.GOOS == "android" {
the.CwtchApp = libapp.NewApp(the.ACN, the.CwtchDir) clientIn := path.Join(the.CwtchDir, "clientIn")
the.AppBus = the.CwtchApp.GetPrimaryBus() serviceIn := path.Join(the.CwtchDir, "serviceIn")
go characters.AppEventListener(gcd) if service {
the.CwtchApp.LoadProfiles("be gay do crime") loadACN()
serviceBridge, err := bridge.NewPipeBridgeService(serviceIn, clientIn)
if err != nil {
log.Errorf("Could not create service bridge: %v\n", err)
os.Exit(1)
}
log.Infoln("Creating New App Service")
the.CwtchService = libapp.NewAppService(the.ACN, the.CwtchDir, serviceBridge)
} else {
clientBridge, err := bridge.NewPipeBridgeClient(clientIn, serviceIn)
if err != nil {
log.Errorf("Could not create client bridge: %v\n", err)
os.Exit(1)
}
log.Infoln("Creating New App Client")
the.CwtchApp = libapp.NewAppClient(the.CwtchDir, clientBridge)
}
} else {
loadACN()
log.Infoln("Creating New App")
the.CwtchApp = libapp.NewApp(the.ACN, the.CwtchDir)
}
if !service {
the.AppBus = the.CwtchApp.GetPrimaryBus()
go characters.AppEventListener(gcd)
the.CwtchApp.LoadProfiles("be gay do crime")
}
} }