Gio's GioView.onDestroyView signals detach with ViewEvent{View: 0};
handleEvent already filters these, but add defense in depth so any
caller forwarding the event unfiltered cannot drive the JNI path
(GetObjectClass on a null ref aborts the process, the recents-wipe
SIGABRT). Completes the intent of PR #1, whose handleEvent guard is
already in master from the migration commit.
Fixes: recents-wipe crash defense (PR #1 superseded).
116 lines
2.5 KiB
Go
116 lines
2.5 KiB
Go
//go:build android
|
|
// +build android
|
|
|
|
//go:generate mkdir -p classes
|
|
//go:generate javac -nowarn -classpath $ANDROID_HOME/platforms/android-35/android.jar:openpgp-api.jar -d classes PgpConnect.java Permissions.java
|
|
//go:generate jar cf PgpConnect.jar -C classes .
|
|
//go:generate rm -rf classes
|
|
|
|
package passgo
|
|
|
|
/*
|
|
#import <jni.h>
|
|
#import "jni_android.h"
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"path"
|
|
"strings"
|
|
"sync"
|
|
"unsafe"
|
|
|
|
"gioui.org/app"
|
|
_ "gioui.org/app/permission/storage"
|
|
//"git.wow.st/gmp/jni"
|
|
)
|
|
|
|
var (
|
|
jvm uintptr
|
|
waitch chan struct{}
|
|
//w *app.Window
|
|
pgp PGP
|
|
installCompleteOnce sync.Once
|
|
)
|
|
|
|
func init() {
|
|
waitch = make(chan struct{})
|
|
}
|
|
|
|
//export Java_st_wow_git_passgo_PgpConnect_installComplete
|
|
func Java_st_wow_git_passgo_PgpConnect_installComplete(env *C.JNIEnv, class C.jclass, p C.jobject) {
|
|
log.Printf("InstallComplete()")
|
|
pgp = PGP(C.NewGlobalRef(env, p))
|
|
installCompleteOnce.Do(func() {
|
|
close(waitch)
|
|
})
|
|
}
|
|
|
|
func InitPgp(view uintptr) {
|
|
log.Printf("InitPgp()")
|
|
if view == 0 {
|
|
return // detach signal; nothing to register
|
|
}
|
|
jvm = app.JavaVM()
|
|
SetJVM(jvm) // why?
|
|
RunInJVM(func(env *JNIEnv) {
|
|
C.registerFragment(env, (C.jobject)(unsafe.Pointer(view)))
|
|
})
|
|
}
|
|
|
|
// InitPermissions registers the Permissions fragment, which requests the
|
|
// storage permissions (launching the system "All files access" settings
|
|
// screen on Android 11+) so the app can read the store in shared storage.
|
|
func InitPermissions(view uintptr) {
|
|
log.Printf("InitPermissions()")
|
|
if view == 0 {
|
|
return // detach signal; nothing to register
|
|
}
|
|
RunInJVM(func(env *JNIEnv) {
|
|
C.registerPermissionsFragment(env, (C.jobject)(unsafe.Pointer(view)))
|
|
})
|
|
}
|
|
|
|
func stopPgp() {
|
|
waitch = make(chan struct{})
|
|
}
|
|
|
|
func connect() {
|
|
<-waitch
|
|
}
|
|
|
|
// Clip copies a string to the clipboard
|
|
func Clip(x string) {
|
|
pgp.Clip(x)
|
|
}
|
|
|
|
func (s *Store) nativeDecrypt(name string) (string, error) {
|
|
connect()
|
|
data, err := ioutil.ReadFile(path.Join(s.Dir, strings.Join([]string{name, ".gpg"}, "")))
|
|
if err != nil {
|
|
return "", fmt.Errorf("Error reading file: %s", err)
|
|
}
|
|
ret, err := pgp.Decrypt(string(data))
|
|
return ret, err
|
|
}
|
|
|
|
func (s *Store) nativeEncrypt(pw string) ([]byte, error) {
|
|
connect()
|
|
ret, err := pgp.Encrypt(s.Id, pw)
|
|
return []byte(ret), err
|
|
}
|
|
|
|
func nativeIdentities() ([]string, error) {
|
|
//NOT IMPLEMENTED ON ANDROID
|
|
return []string{}, nil
|
|
log.Printf("nativeIdentities()")
|
|
connect()
|
|
log.Printf("calling pgp.GetId()")
|
|
id, err := pgp.GetId()
|
|
log.Printf("pgp.GetId() returned")
|
|
return []string{id}, err
|
|
}
|