{"record":{"id":"d9dd420a8e0640ce","repo":"microg/GmsCore","slug":"uid","errorCode":null,"errorMessage":"UID [","messagePattern":"UID \\[","errorType":"validation","errorClass":"SecurityException","httpStatus":null,"severity":"error","filePath":"play-services-base/core/src/main/java/org/microg/gms/common/PackageUtils.java","lineNumber":260,"sourceCode":"    }\n\n    @Nullable\n    public static String getAndCheckPackage(@NonNull Context context, @Nullable String suggestedPackageName, int callingUid, int callingPid) {\n        String packageName = packageFromProcessId(context, callingPid);\n        if (packageName == null) {\n            String[] packagesForUid = context.getPackageManager().getPackagesForUid(callingUid);\n            if (packagesForUid != null && packagesForUid.length != 0) {\n                if (packagesForUid.length == 1) {\n                    packageName = packagesForUid[0];\n                } else if (Arrays.asList(packagesForUid).contains(suggestedPackageName)) {\n                    packageName = suggestedPackageName;\n                } else {\n                    packageName = packagesForUid[0];\n                }\n            }\n        }\n        if (packageName != null && suggestedPackageName != null && !packageName.equals(suggestedPackageName)) {\n            throw new SecurityException(\"UID [\" + callingUid + \"] is not related to packageName [\" + suggestedPackageName + \"] (seems to be \" + packageName + \")\");\n        }\n        return packageName;\n    }\n\n    @Nullable\n    @Deprecated\n    public static String packageFromProcessId(@NonNull Context context, int pid) {\n        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);\n        if (manager == null) return null;\n        if (pid <= 0) return null;\n        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = manager.getRunningAppProcesses();\n        if (runningAppProcesses != null) {\n            for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcesses) {\n                if (processInfo.pid == pid && processInfo.pkgList.length == 1) {\n                    return processInfo.pkgList[0];\n                }\n            }\n        }","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-base/core/src/main/java/org/microg/gms/common/PackageUtils.java#L242-L278","documentation":"getAndCheckPackage resolves the package names owning the calling UID and throws this SecurityException if the resolved package differs from the suggestedPackageName argument. This is microG's implementation of the Play services package-identity check: an app may not claim a package name it does not actually own.","triggerScenarios":"Calling a microG service with a package name (in metadata, extras, or an API argument) that differs from the actual calling app's package; a shared-UID/multi-process setup where getPackagesForUid returns a different package than suggested; a renamed/repackaged app still sending its old package name.","commonSituations":"Copy-pasted client code leaving another app's package name in constants; app rebranding without updating the reported package name; apps sharing a UID via android:sharedUserId resolving to the first package.","solutions":["Use context.getPackageName() (or the real application id from build.gradle) for the suggestedPackageName argument instead of a hardcoded string.","If the app uses sharedUserId, ensure the suggested name matches the package resolved for the shared UID.","After a rebrand/repackage, update all places that report the package name (manifest, build config, service calls).","Catch SecurityException and log both the resolved and suggested names to diagnose which identifier is stale."],"exampleFix":"// before\nString pkg = \"com.example.oldapp\";\nPackageUtils.getAndCheckPackage(context, pkg, Process.myUid());\n\n// after\nString pkg = context.getPackageName();\nPackageUtils.getAndCheckPackage(context, pkg, Process.myUid());","handlingStrategy":"validation","validationCode":"String real = context.getPackageName();\nif (suggestedPackageName != null && !suggestedPackageName.equals(real)) {\n    throw new IllegalArgumentException(\"suggestedPackageName '\" + suggestedPackageName + \"' != actual '\" + real + \"'\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return PackageUtils.getAndCheckPackage(context, suggestedPkg, callingUid);\n} catch (SecurityException e) {\n    Log.w(TAG, \"Package identity mismatch, using real package\", e);\n    return context.getPackageName();\n}","preventionTips":["Always derive the package name from context.getPackageName(), not constants.","Update reported package name after app renames/rebrands.","Check sharedUserId setups: the resolved package may be the first package in the shared UID.","Test identity checks on release builds where applicationId may differ from debug."],"tags":["android","security","package-name","identity"],"backgroundTag":"permission-denied","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}