{"record":{"id":"b07874974308e27a","repo":"asLody/VirtualApp","slug":"invalid-userid","errorCode":null,"errorMessage":"Invalid userId ","messagePattern":"Invalid userId ","errorType":"exception","errorClass":"SecurityException","httpStatus":null,"severity":"error","filePath":"VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/VPackageManagerService.java","lineNumber":279,"sourceCode":"    private int updateFlagsNought(int flags) {\n        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {\n            return flags;\n        }\n        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE\n                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {\n            // Caller expressed an explicit opinion about what encryption\n            // aware/unaware components they want to see, so fall through and\n            // give them what they want\n        } else {\n            // Caller expressed no opinion, so match based on user state\n            flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE;\n        }\n        return flags;\n    }\n\n    private void checkUserId(int userId) {\n        if (!VUserManagerService.get().exists(userId)) {\n            throw new SecurityException(\"Invalid userId \" + userId);\n        }\n    }\n\n    @Override\n    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {\n        checkUserId(userId);\n        flags = updateFlagsNought(flags);\n        synchronized (mPackages) {\n            VPackage p = mPackages.get(component.getPackageName());\n            if (p != null) {\n                PackageSetting ps = (PackageSetting) p.mExtras;\n                VPackage.ActivityComponent a = mActivities.mActivities.get(component);\n                if (a != null) {\n                    ActivityInfo activityInfo = PackageParserEx.generateActivityInfo(a, flags, ps.readUserState(userId), userId);\n                    ComponentFixer.fixComponentInfo(ps, activityInfo, userId);\n                    return activityInfo;\n                }\n            }","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/asLody/VirtualApp/blob/666fefcb5d3f39cc944001c3457c38ffd6544c87/VirtualApp/lib/src/main/java/com/lody/virtual/server/pm/VPackageManagerService.java#L261-L297","documentation":"VPackageManagerService.checkUserId() validates that the target user profile exists via VUserManagerService.get().exists(userId). Package/component lookups are per-user in VirtualApp; querying a userId that was never created throws SecurityException(\"Invalid userId \"+userId) instead of returning null data.","triggerScenarios":"Calling getPackageInfo, getActivityInfo, getReceiverInfo, getServiceInfo, getProviderInfo, or resolveIntent with a flags+userId where the userId is not an installed virtual user — e.g. userId 0 in a fresh VirtualApp install (only user 10+ typically exists), a stale cached userId after the user was removed, or an hardcoded user id.","commonSituations":"Hardcoding userId=0 in multi-user virtual setups; calling PM APIs after VUserManagerService users were wiped (reinstall of the host app); concurrent user removal while another thread performs a package lookup; passing an OS userId (e.g. from UserManager) instead of a VirtualApp user id.","solutions":["Create/obtain a valid user via VUserManagerService (e.g. start/create user) and pass its id to package lookups.","Before calling, guard with VUserManagerService.get().exists(userId) and fall back to a valid user id.","Replace hardcoded userId (especially 0) with the id of the currently active virtual user.","Handle user removal: refresh cached userIds and retry after the user is recreated."],"exampleFix":"// before\nPackageInfo pi = vPms.getPackageInfo(pkg, 0, 0); // userId 0 may not exist\n// after\nint userId = VUserManagerService.get().exists(0) ? 0 : VUserManagerService.get().getUsers().get(0).id;\nif (!VUserManagerService.get().exists(userId)) { userId = vUserManager.createUser(\"user\").id; }\nPackageInfo pi = vPms.getPackageInfo(pkg, 0, userId);","handlingStrategy":"validation","validationCode":"if (!VUserManagerService.get().exists(userId)) {\n    // pick a valid user or create one before any package lookup\n    userId = VUserManagerService.get().getUsers().get(0).id;\n}","typeGuard":"boolean isValidVirtualUser(int userId) {\n    return VUserManagerService.get() != null && VUserManagerService.get().exists(userId);\n}","tryCatchPattern":"try {\n    return vPms.getPackageInfo(packageName, flags, userId);\n} catch (SecurityException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Invalid userId\")) {\n        return vPms.getPackageInfo(packageName, flags, getDefaultVirtualUserId());\n    }\n    throw e;\n}","preventionTips":["Never hardcode userId (especially 0); resolve the active virtual user at runtime.","Refresh cached user ids after user creation/removal or host app reinstall.","Guard every per-user PM lookup with VUserManagerService.get().exists(userId).","Distinguish OS user ids from VirtualApp user ids in your code to avoid mixing the two namespaces."],"tags":["android","package-manager","multi-user","virtualapp"],"backgroundTag":"permission-denied","analyzedSha":"666fefcb5d3f39cc944001c3457c38ffd6544c87","analyzedAt":"2026-09-09T11:09:01.694Z","contentChangedAt":"2026-09-09T11:09:01.694Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}