1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.media; 18 19import android.app.ActivityManager; 20import android.app.ActivityManagerNative; 21import android.content.Context; 22import android.content.Intent; 23import android.media.IMediaResourceMonitor; 24import android.os.Binder; 25import android.os.RemoteException; 26import android.os.UserHandle; 27import android.util.Log; 28import android.util.Slog; 29import com.android.server.SystemService; 30 31import java.util.List; 32 33/** This class provides a system service that monitors media resource usage. */ 34public class MediaResourceMonitorService extends SystemService { 35 private static final String TAG = "MediaResourceMonitor"; 36 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 37 38 private static final String SERVICE_NAME = "media_resource_monitor"; 39 40 private final MediaResourceMonitorImpl mMediaResourceMonitorImpl; 41 42 public MediaResourceMonitorService(Context context) { 43 super(context); 44 mMediaResourceMonitorImpl = new MediaResourceMonitorImpl(); 45 } 46 47 @Override 48 public void onStart() { 49 publishBinderService(SERVICE_NAME, mMediaResourceMonitorImpl); 50 } 51 52 class MediaResourceMonitorImpl extends IMediaResourceMonitor.Stub { 53 @Override 54 public void notifyResourceGranted(int pid, int type) 55 throws RemoteException { 56 if (DEBUG) { 57 Slog.d(TAG, "notifyResourceGranted(pid=" + pid + ", type=" + type + ")"); 58 } 59 final long identity = Binder.clearCallingIdentity(); 60 try { 61 String pkgNames[] = getPackageNamesFromPid(pid); 62 if (pkgNames != null) { 63 Intent intent = new Intent(Intent.ACTION_MEDIA_RESOURCE_GRANTED); 64 intent.putExtra(Intent.EXTRA_PACKAGES, pkgNames); 65 intent.putExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE, type); 66 getContext().sendBroadcastAsUser(intent, 67 new UserHandle(ActivityManager.getCurrentUser()), 68 android.Manifest.permission.RECEIVE_MEDIA_RESOURCE_USAGE); 69 } 70 } finally { 71 Binder.restoreCallingIdentity(identity); 72 } 73 } 74 75 private String[] getPackageNamesFromPid(int pid) { 76 try { 77 for (ActivityManager.RunningAppProcessInfo proc : 78 ActivityManagerNative.getDefault().getRunningAppProcesses()) { 79 if (proc.pid == pid) { 80 return proc.pkgList; 81 } 82 } 83 } catch (RemoteException e) { 84 Slog.w(TAG, "ActivityManager.getRunningAppProcesses() failed"); 85 } 86 return null; 87 } 88 } 89} 90