/* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.media; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.content.Context; import android.content.Intent; import android.media.IMediaResourceMonitor; import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.util.Log; import android.util.Slog; import com.android.server.SystemService; import java.util.List; /** This class provides a system service that monitors media resource usage. */ public class MediaResourceMonitorService extends SystemService { private static final String TAG = "MediaResourceMonitor"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final String SERVICE_NAME = "media_resource_monitor"; private final MediaResourceMonitorImpl mMediaResourceMonitorImpl; public MediaResourceMonitorService(Context context) { super(context); mMediaResourceMonitorImpl = new MediaResourceMonitorImpl(); } @Override public void onStart() { publishBinderService(SERVICE_NAME, mMediaResourceMonitorImpl); } class MediaResourceMonitorImpl extends IMediaResourceMonitor.Stub { @Override public void notifyResourceGranted(int pid, int type) throws RemoteException { if (DEBUG) { Slog.d(TAG, "notifyResourceGranted(pid=" + pid + ", type=" + type + ")"); } final long identity = Binder.clearCallingIdentity(); try { String pkgNames[] = getPackageNamesFromPid(pid); if (pkgNames == null) { return; } UserManager manager = (UserManager) getContext().getSystemService( Context.USER_SERVICE); int[] userIds = manager.getEnabledProfileIds(ActivityManager.getCurrentUser()); if (userIds == null || userIds.length == 0) { return; } Intent intent = new Intent(Intent.ACTION_MEDIA_RESOURCE_GRANTED); intent.putExtra(Intent.EXTRA_PACKAGES, pkgNames); intent.putExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE, type); for (int userId : userIds) { getContext().sendBroadcastAsUser(intent, UserHandle.of(userId), android.Manifest.permission.RECEIVE_MEDIA_RESOURCE_USAGE); } } finally { Binder.restoreCallingIdentity(identity); } } private String[] getPackageNamesFromPid(int pid) { try { for (ActivityManager.RunningAppProcessInfo proc : ActivityManagerNative.getDefault().getRunningAppProcesses()) { if (proc.pid == pid) { return proc.pkgList; } } } catch (RemoteException e) { Slog.w(TAG, "ActivityManager.getRunningAppProcesses() failed"); } return null; } } }