func newAPIService(id protocol.DeviceID, cfg *config.Wrapper, assetDir string, m *model.Model, eventSub *events.BufferedSubscription, discoverer *discover.CachingMux, relayService *relay.Service, errors, systemLog *logger.Recorder) (*apiService, error) { service := &apiService{ id: id, cfg: cfg, assetDir: assetDir, model: m, eventSub: eventSub, discoverer: discoverer, relayService: relayService, systemConfigMut: sync.NewMutex(), stop: make(chan struct{}), configChanged: make(chan struct{}), listenerMut: sync.NewMutex(), guiErrors: errors, systemLog: systemLog, } seen := make(map[string]struct{}) for file := range auto.Assets() { theme := strings.Split(file, "/")[0] if _, ok := seen[theme]; !ok { seen[theme] = struct{}{} service.themes = append(service.themes, theme) } } var err error service.listener, err = service.getListener(cfg.GUI()) return service, err }
func setupGUI(mainService *suture.Supervisor, cfg *config.Wrapper, m *model.Model, apiSub *events.BufferedSubscription, discoverer *discover.CachingMux, relayService *relay.Service, errors, systemLog *logger.Recorder, runtimeOptions RuntimeOptions) { guiCfg := cfg.GUI() if !guiCfg.Enabled { return } if guiCfg.InsecureAdminAccess { l.Warnln("Insecure admin access is enabled.") } api, err := newAPIService(myID, cfg, runtimeOptions.assetDir, m, apiSub, discoverer, relayService, errors, systemLog) if err != nil { l.Fatalln("Cannot start GUI:", err) } cfg.Subscribe(api) mainService.Add(api) if cfg.Options().StartBrowser && !runtimeOptions.noBrowser && !runtimeOptions.stRestarting { // Can potentially block if the utility we are invoking doesn't // fork, and just execs, hence keep it in it's own routine. go openURL(guiCfg.URL()) } }