//go:build android // +build android package main import ( "context" "os" "sync" "forge.cadoles.com/arcad/arcast" "forge.cadoles.com/arcad/arcast/pkg/browser/gioui" "forge.cadoles.com/arcad/arcast/pkg/selfsigned" "forge.cadoles.com/arcad/arcast/pkg/server" "gioui.org/app" "gioui.org/io/system" "gioui.org/layout" "gioui.org/op" "github.com/gioui-plugins/gio-plugins/plugin" "github.com/gioui-plugins/gio-plugins/safedata" "github.com/gioui-plugins/gio-plugins/safedata/giosafedata" "github.com/gioui-plugins/gio-plugins/webviewer/webview" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/logger" ) const instanceIDSecretIdentifier = "instance_id" func main() { ctx := context.Background() webview.SetDebug(true) window := app.NewWindow( app.Fullscreen.Option(), ) browser := gioui.NewBrowser(window) var safeDataConfig safedata.Config var safeDataConfigWaigGroup sync.WaitGroup var initSafeDataConfig sync.Once safeDataConfigWaigGroup.Add(1) go func() { ops := new(op.Ops) for { evt := window.NextEvent() plugin.Install(window, evt) switch evt := evt.(type) { case system.DestroyEvent: os.Exit(0) return case system.FrameEvent: gtx := layout.NewContext(ops, evt) browser.Layout(gtx) evt.Frame(gtx.Ops) case app.ViewEvent: initSafeDataConfig.Do(func() { defer safeDataConfigWaigGroup.Done() safeDataConfig = giosafedata.NewConfigFromViewEvent(window, evt, "com.cadoles.arcast_player") }) } } }() go func() { for { ctx, cancel := context.WithCancel(ctx) defer cancel() safeDataConfigWaigGroup.Wait() safe := safedata.NewSafeData(safeDataConfig) instanceID, err := getInstanceIDFromSafeData(ctx, safe) if err != nil { logger.Fatal(ctx, "could not retrieve instance id", logger.CapturedE(errors.WithStack(err))) } cert, err := selfsigned.NewLANCert() if err != nil { logger.Fatal(ctx, "could not generate self signed certificate", logger.CapturedE(errors.WithStack(err))) } server := server.New( browser, server.WithInstanceID(instanceID), server.WithAppsEnabled(true), server.WithDefaultApp("home"), server.WithApps(arcast.DefaultApps...), server.WithTLSCertificate(cert), ) if err := server.Start(); err != nil { logger.Fatal(ctx, "could not start server", logger.CapturedE(errors.WithStack(err))) } defer func() { if err := server.Stop(); err != nil { logger.Error(ctx, "could not stop server", logger.CapturedE(errors.WithStack(err))) } }() if err := server.Wait(); err != nil { logger.Error(ctx, "could not wait for server", logger.CapturedE(errors.WithStack(err))) } } }() app.Main() } func getInstanceIDFromSafeData(ctx context.Context, safe *safedata.SafeData) (string, error) { instanceIDSecret, err := safe.Get(instanceIDSecretIdentifier) if err != nil && err.Error() != "not found" { logger.Error(ctx, "could not retrieve instance id secret", logger.CapturedE(errors.WithStack(err))) } var instanceID string if len(instanceIDSecret.Data) > 0 { instanceID = string(instanceIDSecret.Data) } else { instanceID = server.NewRandomInstanceID() instanceIDSecret.Identifier = instanceIDSecretIdentifier instanceIDSecret.Data = []byte(instanceID) instanceIDSecret.Description = "Arcast player instance identifier" if err := safe.Set(instanceIDSecret); err != nil { return "", errors.Wrapf(err, "could not save instance id secret") } } return instanceID, nil }