88 "errors"
99 "fmt"
1010 "io"
11+ "io/fs"
1112 "io/ioutil"
1213 "os"
1314 "os/exec"
@@ -49,6 +50,7 @@ type manifestData struct {
4950 Features []string
5051 IconSnip string
5152 AppName string
53+ HasService bool
5254}
5355
5456const (
@@ -146,9 +148,6 @@ func buildAndroid(tmpDir string, bi *buildInfo) error {
146148 return err
147149 }
148150
149- if err := compileAndroid (tmpDir , tools , bi ); err != nil {
150- return err
151- }
152151 switch * buildMode {
153152 case "archive" :
154153 return archiveAndroid (tmpDir , bi , perms )
@@ -248,6 +247,18 @@ func compileAndroid(tmpDir string, tools *androidTools, bi *buildInfo) (err erro
248247 if err != nil {
249248 return err
250249 }
250+
251+ // walk tmpDir to find generated R.java that is generated from Manifest.xml
252+ err = filepath .Walk (tmpDir , func (path string , info fs.FileInfo , err error ) error {
253+ if ! info .IsDir () && filepath .Ext (info .Name ()) == ".java" {
254+ javaFiles = append (javaFiles , path )
255+ }
256+ return nil
257+ })
258+ if err != nil {
259+ return err
260+ }
261+
251262 if len (javaFiles ) == 0 {
252263 return fmt .Errorf ("the gioui.org/app package contains no .java files (gioui.org module too old?)" )
253264 }
@@ -337,22 +348,6 @@ func archiveAndroid(tmpDir string, bi *buildInfo, perms []string) (err error) {
337348}
338349
339350func exeAndroid (tmpDir string , tools * androidTools , bi * buildInfo , extraJars , perms []string , isBundle bool ) (err error ) {
340- classes := filepath .Join (tmpDir , "classes" )
341- var classFiles []string
342- err = filepath .Walk (classes , func (path string , f os.FileInfo , err error ) error {
343- if err != nil {
344- return err
345- }
346- if filepath .Ext (path ) == ".class" {
347- classFiles = append (classFiles , path )
348- }
349- return nil
350- })
351- classFiles = append (classFiles , extraJars ... )
352- dexDir := filepath .Join (tmpDir , "apk" )
353- if err := os .MkdirAll (dexDir , 0755 ); err != nil {
354- return err
355- }
356351 // https://developer.android.com/distribute/best-practices/develop/target-sdk
357352 targetSDK := 31
358353 if bi .minsdk > targetSDK {
@@ -362,22 +357,6 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
362357 if bi .minsdk > minSDK {
363358 minSDK = bi .minsdk
364359 }
365- if len (classFiles ) > 0 {
366- d8 := exec .Command (
367- filepath .Join (tools .buildtools , "d8" ),
368- "--lib" , tools .androidjar ,
369- "--output" , dexDir ,
370- "--min-api" , strconv .Itoa (minSDK ),
371- )
372- d8 .Args = append (d8 .Args , classFiles ... )
373- if _ , err := runCmd (d8 ); err != nil {
374- major , minor , ok := determineJDKVersion ()
375- if ok && (major != 1 || minor != 8 ) {
376- return fmt .Errorf ("unsupported JDK version %d.%d, expected 1.8\n d8 error: %v" , major , minor , err )
377- }
378- return err
379- }
380- }
381360
382361 // Compile resources.
383362 resDir := filepath .Join (tmpDir , "res" )
@@ -446,6 +425,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
446425 Features : features ,
447426 IconSnip : iconSnip ,
448427 AppName : appName ,
428+ HasService : hasForegroundPermission (permissions ),
449429 }
450430 tmpl , err := template .New ("test" ).Parse (
451431 `<?xml version="1.0" encoding="utf-8"?>
@@ -468,6 +448,11 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
468448 <category android:name="android.intent.category.LAUNCHER" />
469449 </intent-filter>
470450 </activity>
451+ {{if .HasService}}
452+ <service android:name="org.gioui.GioForegroundService"
453+ android:stopWithTask="true">
454+ </service>
455+ {{end}}
471456 </application>
472457</manifest>` )
473458 var manifestBuffer bytes.Buffer
@@ -486,6 +471,7 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
486471 "--manifest" , manifest ,
487472 "-I" , tools .androidjar ,
488473 "-o" , linkAPK ,
474+ "--java" , tmpDir ,
489475 }
490476 if isBundle {
491477 args = append (args , "--proto-format" )
@@ -496,6 +482,43 @@ func exeAndroid(tmpDir string, tools *androidTools, bi *buildInfo, extraJars, pe
496482 return err
497483 }
498484
485+ if err := compileAndroid (tmpDir , tools , bi ); err != nil {
486+ return err
487+ }
488+
489+ classes := filepath .Join (tmpDir , "classes" )
490+ var classFiles []string
491+ err = filepath .Walk (classes , func (path string , f os.FileInfo , err error ) error {
492+ if err != nil {
493+ return err
494+ }
495+ if filepath .Ext (path ) == ".class" {
496+ classFiles = append (classFiles , path )
497+ }
498+ return nil
499+ })
500+ classFiles = append (classFiles , extraJars ... )
501+ dexDir := filepath .Join (tmpDir , "apk" )
502+ if err := os .MkdirAll (dexDir , 0755 ); err != nil {
503+ return err
504+ }
505+ if len (classFiles ) > 0 {
506+ d8 := exec .Command (
507+ filepath .Join (tools .buildtools , "d8" ),
508+ "--lib" , tools .androidjar ,
509+ "--output" , dexDir ,
510+ "--min-api" , strconv .Itoa (minSDK ),
511+ )
512+ d8 .Args = append (d8 .Args , classFiles ... )
513+ if _ , err := runCmd (d8 ); err != nil {
514+ major , minor , ok := determineJDKVersion ()
515+ if ok && (major != 1 || minor != 8 ) {
516+ return fmt .Errorf ("unsupported JDK version %d.%d, expected 1.8\n d8 error: %v" , major , minor , err )
517+ }
518+ return err
519+ }
520+ }
521+
499522 // The Go standard library archive/zip doesn't support appending to zip
500523 // files. Copy files from `link.apk` (generated by aapt2) along with classes.dex and
501524 // the Go libraries to a new `app.zip` file.
@@ -865,6 +888,17 @@ func getPermissions(ps []string) ([]string, []string) {
865888 return permissions , features
866889}
867890
891+ func hasForegroundPermission (permissions []string ) bool {
892+ if fgPerms , ok := AndroidPermissions ["foreground" ]; ok {
893+ for _ , p := range permissions {
894+ if p == fgPerms [0 ] { // []string, len 1
895+ return true
896+ }
897+ }
898+ }
899+ return false
900+ }
901+
868902func latestPlatform (sdk string ) (string , error ) {
869903 allPlats , err := filepath .Glob (filepath .Join (sdk , "platforms" , "android-*" ))
870904 if err != nil {
0 commit comments