Xiaomi-protobuf: combine installed apps and watchface cache when reporting installed apps

Because the list of installed apps and the list of installed faces are
requested from Xiaomi devices separately, a race condition will occur if
the lists are not combined: when processing the AppInfo event, all
previously known installed apps are removed from the app manager cache, which
will cause either all apps or all faces to get forgotten.
This commit is contained in:
MrYoranimo
2026-05-15 01:21:20 +02:00
parent d5643468b9
commit a16b90f6aa
3 changed files with 29 additions and 7 deletions
@@ -441,6 +441,14 @@ public class XiaomiSupport extends AbstractDeviceSupport {
return this.healthService;
}
public XiaomiRpkService getRpkService() {
return this.rpkService;
}
public XiaomiWatchfaceService getWatchfaceService() {
return this.watchfaceService;
}
@Override
public String customStringFilter(final String inputString) {
return StringUtils.replaceEach(inputString, EMOJI_SOURCE, EMOJI_TARGET);
@@ -22,11 +22,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.R;
@@ -154,8 +154,10 @@ public class XiaomiRpkService extends AbstractXiaomiService implements XiaomiDat
GBDeviceApp gbDeviceApp = new GBDeviceApp(UUID.nameUUIDFromBytes(packageName.getBytes()), appName, packageName, "", GBDeviceApp.Type.APP_GENERIC);
apps.add(gbDeviceApp);
}
final List<GBDeviceApp> appsAndFaces = new ArrayList<>(apps);
appsAndFaces.addAll(getSupport().getWatchfaceService().getInstalledFacesCache());
final GBDeviceEventAppInfo appInfoCmd = new GBDeviceEventAppInfo();
appInfoCmd.apps = apps.toArray(new GBDeviceApp[0]);
appInfoCmd.apps = appsAndFaces.toArray(new GBDeviceApp[0]);
getSupport().evaluateGBDeviceEvent(appInfoCmd);
}
@@ -205,4 +207,8 @@ public class XiaomiRpkService extends AbstractXiaomiService implements XiaomiDat
device.sendDeviceUpdateIntent(getSupport().getContext());
}
}
public Collection<? extends GBDeviceApp> getInstalledAppsCache() {
return Collections.unmodifiableList(apps);
}
}
@@ -20,6 +20,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -45,6 +47,7 @@ public class XiaomiWatchfaceService extends AbstractXiaomiService implements Xia
private final Set<UUID> allWatchfaces = new HashSet<>();
private final Set<UUID> userWatchfaces = new HashSet<>();
private final List<GBDeviceApp> facesCache = new ArrayList<>();
private UUID activeWatchface = null;
// Not null if we're installing a firmware
@@ -102,10 +105,9 @@ public class XiaomiWatchfaceService extends AbstractXiaomiService implements Xia
allWatchfaces.clear();
userWatchfaces.clear();
facesCache.clear();
activeWatchface = null;
final List<GBDeviceApp> gbDeviceApps = new ArrayList<>();
for (final XiaomiProto.WatchfaceInfo watchface : watchfaceList.getWatchfaceList()) {
final UUID uuid = toWatchfaceUUID(watchface.getId());
allWatchfaces.add(uuid);
@@ -123,11 +125,13 @@ public class XiaomiWatchfaceService extends AbstractXiaomiService implements Xia
"",
GBDeviceApp.Type.WATCHFACE
);
gbDeviceApps.add(gbDeviceApp);
facesCache.add(gbDeviceApp);
}
final List<GBDeviceApp> appsAndFaces = new ArrayList<>(facesCache);
appsAndFaces.addAll(getSupport().getRpkService().getInstalledAppsCache());
final GBDeviceEventAppInfo appInfoCmd = new GBDeviceEventAppInfo();
appInfoCmd.apps = gbDeviceApps.toArray(new GBDeviceApp[0]);
appInfoCmd.apps = appsAndFaces.toArray(new GBDeviceApp[0]);
getSupport().evaluateGBDeviceEvent(appInfoCmd);
}
@@ -281,4 +285,8 @@ public class XiaomiWatchfaceService extends AbstractXiaomiService implements Xia
device.sendDeviceUpdateIntent(getSupport().getContext());
}
}
public Collection<? extends GBDeviceApp> getInstalledFacesCache() {
return Collections.unmodifiableList(facesCache);
}
}