From 98f1f3400d7c5c3b2c3b22f57f590e1b9e5d484d Mon Sep 17 00:00:00 2001 From: riddle_hsu Date: Sat, 15 Nov 2014 18:16:49 +0800 Subject: [PATCH] [ActivityManager] Ensure provider external access count will be released. Sympton: Oom-adj of provider process will be always 0. Root Cause: Exception happend in openContentUri may not call removeContentProviderExternalUnchecked. Flow: application [MediaPlayer.setDataSource(Context context, Uri uri)] uri is invalid, IOException will be caught and below log will appear: "Couldn't open file on client side, trying server side" Continue to call setDataSource(String path, Map headers) ->mediaserver [MediaPlayerService::Client::setDataSource] setDataSource(httpService, url, headers) calls openContentProviderFile ->system_server (ActivityManagerService) [openContentUri] Increase externalProcessNoHandleCount for media provider. Call [openFile] to media provider. ->android.process.media [check permission for openFile] enforceReadPermissionInner ->system_server [checkComponentPermission] Use mediaserver's uid to check READ_EXTERNAL_STORAGE -> not granted due to it is pure native process, not a known package. Throw security exception then the flow of openContentUri is broke. And externalProcessNoHandleCount is unable to decrease. Application sample code: String invalidId = "54321"; Uri externalUri = MediaStore.Files.getContentUri("external"); Uri uri = Uri.withAppendedPath(externalUri, invalidId); mediaPlayer.setDataSource(mContext, uri); Solution: Move removeContentProviderExternalUnchecked to finally block. Change-Id: I75eec1f9631e9c6bb18449946d707d51ac21e8a7 --- .../java/com/android/server/am/ActivityManagerService.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 8dfb3217c0af1..909eaf3dea7bc 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -10032,10 +10032,9 @@ public final class ActivityManagerService extends ActivityManagerNative } finally { // Ensure that whatever happens, we clean up the identity state sCallerIdentity.remove(); + // Ensure we're done with the provider. + removeContentProviderExternalUnchecked(name, null, userId); } - - // We've got the fd now, so we're done with the provider. - removeContentProviderExternalUnchecked(name, null, userId); } else { Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); }