Skip to content

Commit

Permalink
Author: Masala <[email protected]>
Browse files Browse the repository at this point in the history
Date:   Sat Aug 13 05:42:34 2022 -0400

cmd/gogio: add android foreground permission

This adds the permission android.permission.FOREGROUND_SERVICE to the
android application Metadata

Signed-off-by: Masala <[email protected]>
  • Loading branch information
mixmasala committed Aug 13, 2022
1 parent 2edf599 commit 81e14a3
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 35 deletions.
111 changes: 76 additions & 35 deletions gogio/androidbuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
Expand Down Expand Up @@ -49,6 +50,7 @@ type manifestData struct {
Features []string
IconSnip string
AppName string
HasService bool
}

const (
Expand All @@ -68,6 +70,7 @@ const (
<item name="android:statusBarColor">#40000000</item>
</style>
</resources>`
foregroundPermission = "android.permission.FOREGROUND_SERVICE"
)

func init() {
Expand Down Expand Up @@ -146,9 +149,6 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
return err
}

if err := compileAndroid(tmpDir, tools, bi); err != nil {
return err
}
switch *buildMode {
case "archive":
return archiveAndroid(tmpDir, bi, perms)
Expand Down Expand Up @@ -248,6 +248,18 @@ func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err erro
if err != nil {
return err
}

// walk tmpDir to find generated R.java that is generated from Manifest.xml
err = filepath.Walk(tmpDir, func(path string, info fs.FileInfo, err error) error {
if !info.IsDir() && filepath.Ext(info.Name()) == ".java" {
javaFiles = append(javaFiles, path)
}
return nil
})
if err != nil {
return err
}

if len(javaFiles) == 0 {
return fmt.Errorf("the gioui.org/app package contains no .java files (gioui.org module too old?)")
}
Expand Down Expand Up @@ -337,22 +349,6 @@ func archiveAndroid(tmpDir string, bi *buildInfo, perms []string) (err error) {
}

func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, perms []string, isBundle bool) (err error) {
classes := filepath.Join(tmpDir, "classes")
var classFiles []string
err = filepath.Walk(classes, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if filepath.Ext(path) == ".class" {
classFiles = append(classFiles, path)
}
return nil
})
classFiles = append(classFiles, extraJars...)
dexDir := filepath.Join(tmpDir, "apk")
if err := os.MkdirAll(dexDir, 0755); err != nil {
return err
}
// https://developer.android.com/distribute/best-practices/develop/target-sdk
targetSDK := 31
if bi.minsdk > targetSDK {
Expand All @@ -362,22 +358,6 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
if bi.minsdk > minSDK {
minSDK = bi.minsdk
}
if len(classFiles) > 0 {
d8 := exec.Command(
filepath.Join(tools.buildtools, "d8"),
"--lib", tools.androidjar,
"--output", dexDir,
"--min-api", strconv.Itoa(minSDK),
)
d8.Args = append(d8.Args, classFiles...)
if _, err := runCmd(d8); err != nil {
major, minor, ok := determineJDKVersion()
if ok && (major != 1 || minor != 8) {
return fmt.Errorf("unsupported JDK version %d.%d, expected 1.8\nd8 error: %v", major, minor, err)
}
return err
}
}

// Compile resources.
resDir := filepath.Join(tmpDir, "res")
Expand Down Expand Up @@ -446,6 +426,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
Features: features,
IconSnip: iconSnip,
AppName: appName,
HasService: stringsContains(permissions, foregroundPermission),
}
tmpl, err := template.New("test").Parse(
`<?xml version="1.0" encoding="utf-8"?>
Expand All @@ -468,6 +449,19 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
{{if .HasService}}
<service android:name="org.gioui.GioForegroundService"
android:stopWithTask="true">
<meta-data android:name="org.gioui.ForegroundChannelID"
android:value="gio_foreground" />
<meta-data android:name="org.gioui.ForegroundChannelName"
android:value="GioForeground" />
<meta-data android:name="org.gioui.ForegroundChannelDesc"
android:value="" />
<meta-data android:name="org.gioui.ForegroundNotificationID"
android:value="0x42424242" />
</service>
{{end}}
</application>
</manifest>`)
var manifestBuffer bytes.Buffer
Expand All @@ -486,6 +480,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
"--manifest", manifest,
"-I", tools.androidjar,
"-o", linkAPK,
"--java", tmpDir,
}
if isBundle {
args = append(args, "--proto-format")
Expand All @@ -496,6 +491,43 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
return err
}

if err := compileAndroid(tmpDir, tools, bi); err != nil {
return err
}

classes := filepath.Join(tmpDir, "classes")
var classFiles []string
err = filepath.Walk(classes, func(path string, f os.FileInfo, err error) error {
if err != nil {
return err
}
if filepath.Ext(path) == ".class" {
classFiles = append(classFiles, path)
}
return nil
})
classFiles = append(classFiles, extraJars...)
dexDir := filepath.Join(tmpDir, "apk")
if err := os.MkdirAll(dexDir, 0755); err != nil {
return err
}
if len(classFiles) > 0 {
d8 := exec.Command(
filepath.Join(tools.buildtools, "d8"),
"--lib", tools.androidjar,
"--output", dexDir,
"--min-api", strconv.Itoa(minSDK),
)
d8.Args = append(d8.Args, classFiles...)
if _, err := runCmd(d8); err != nil {
major, minor, ok := determineJDKVersion()
if ok && (major != 1 || minor != 8) {
return fmt.Errorf("unsupported JDK version %d.%d, expected 1.8\nd8 error: %v", major, minor, err)
}
return err
}
}

// The Go standard library archive/zip doesn't support appending to zip
// files. Copy files from `link.apk` (generated by aapt2) along with classes.dex and
// the Go libraries to a new `app.zip` file.
Expand Down Expand Up @@ -865,6 +897,15 @@ func getPermissions(ps []string) ([]string, []string) {
return permissions, features
}

func stringsContains(strings []string, str string) bool {
for _, s := range strings {
if str == s {
return true
}
}
return false
}

func latestPlatform(sdk string) (string, error) {
allPlats, err := filepath.Glob(filepath.Join(sdk, "platforms", "android-*"))
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions gogio/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ var AndroidPermissions = map[string][]string{
"wakelock": {
"android.permission.WAKE_LOCK",
},
"foreground": {
"android.permission.FOREGROUND_SERVICE",
},
}

var AndroidFeatures = map[string][]string{
Expand Down

0 comments on commit 81e14a3

Please sign in to comment.