func Start() { if launcher != nil { return } var err error logger.BeginTracing() InitI18n() // DesktopAppInfo.ShouldShow does not know deepin. gio.DesktopAppInfoSetDesktopEnv("Deepin") soft, err := NewSoftwareCenter() if err != nil { startFailed(err) return } im := NewItemManager(soft) cm := NewCategoryManager() timeInfo, _ := im.GetAllTimeInstalled() appChan := make(chan *gio.AppInfo) go func() { allApps := gio.AppInfoGetAll() for _, app := range allApps { appChan <- app } close(appChan) }() dbPath, _ := GetDBPath(SoftwareCenterDataDir, CategoryNameDBPath) db, err := sql.Open("sqlite3", dbPath) var wg sync.WaitGroup const N = 20 wg.Add(N) for i := 0; i < N; i++ { go func() { for app := range appChan { if !app.ShouldShow() { app.Unref() continue } desktopApp := gio.ToDesktopAppInfo(app) item := NewItem(desktopApp) cid, err := QueryCategoryId(desktopApp, db) if err != nil { item.SetCategoryId(OtherID) } item.SetCategoryId(cid) item.SetTimeInstalled(timeInfo[item.Id()]) im.AddItem(item) cm.AddItem(item.Id(), item.GetCategoryId()) app.Unref() } wg.Done() }() } wg.Wait() if err == nil { db.Close() } launcher = NewLauncher() launcher.setItemManager(im) launcher.setCategoryManager(cm) store, err := storeApi.NewDStoreDesktop("com.deepin.store.Api", "/com/deepin/store/Api") if err == nil { launcher.setStoreApi(store) } names := []string{} for _, item := range im.GetAllItems() { names = append(names, item.Name()) } pinyinObj, err := NewPinYinSearchAdapter(names) launcher.setPinYinObject(pinyinObj) launcher.listenItemChanged() err = dbus.InstallOnSession(launcher) if err != nil { startFailed(err) return } coreSetting := gio.NewSettings("com.deepin.dde.launcher") if coreSetting == nil { startFailed(errors.New("get schema failed")) return } setting, err := NewSetting(coreSetting) if err != nil { startFailed(err) return } err = dbus.InstallOnSession(setting) if err != nil { startFailed(err) return } launcher.setSetting(setting) }
func (self *Launcher) emitItemChanged(name, status string, info map[string]ItemChangedStatus) { if info != nil { defer delete(info, name) } id := GenId(name) if status == SoftwareStatusCreated && self.itemManager.HasItem(id) { status = SoftwareStatusModified } logger.Info(name, "Status:", status) if status != SoftwareStatusDeleted { // cannot use float number here. the total wait time is about 12s. maxDuration := time.Second + time.Second/2 waitDuration := time.Millisecond * 0 deltaDuration := time.Millisecond * 100 app := CreateDesktopAppInfo(name) for app == nil && waitDuration < maxDuration { <-time.After(waitDuration) app = CreateDesktopAppInfo(name) waitDuration += deltaDuration } if app == nil { logger.Infof("create DesktopAppInfo for %q failed", name) return } defer app.Unref() if !app.ShouldShow() { logger.Info(app.GetFilename(), "should NOT show") return } itemInfo := NewItem(app) if info[name].timeInstalled != 0 { itemInfo.SetTimeInstalled(info[name].timeInstalled) } dbPath, _ := GetDBPath(SoftwareCenterDataDir, CategoryNameDBPath) db, err := sql.Open("sqlite3", dbPath) if err == nil { defer db.Close() cid, err := QueryCategoryId(app, db) if err != nil { itemInfo.SetCategoryId(OtherID) } itemInfo.SetCategoryId(cid) } self.itemManager.AddItem(itemInfo) self.categoryManager.AddItem(itemInfo.Id(), itemInfo.GetCategoryId()) } if !self.itemManager.HasItem(id) { logger.Info("get item failed") return } item := self.itemManager.GetItem(id) logger.Info("emit ItemChanged signal") dbus.Emit(self, "ItemChanged", status, NewItemInfoExport(item), item.GetCategoryId()) cid := self.itemManager.GetItem(id).GetCategoryId() if status == SoftwareStatusDeleted { self.itemManager.MarkLaunched(id) self.categoryManager.RemoveItem(id, cid) self.itemManager.RemoveItem(id) } else { self.categoryManager.AddItem(id, cid) } logger.Info(name, status, "successful") }