Home | History | Annotate | Download | only in media
      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 
     17 package com.android.server.media;
     18 
     19 import android.app.ActivityManager;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.media.IMediaResourceMonitor;
     23 import android.os.Binder;
     24 import android.os.RemoteException;
     25 import android.os.UserHandle;
     26 import android.os.UserManager;
     27 import android.util.Log;
     28 import android.util.Slog;
     29 import com.android.server.SystemService;
     30 
     31 import java.util.List;
     32 
     33 /** This class provides a system service that monitors media resource usage. */
     34 public 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                     return;
     64                 }
     65                 UserManager manager = (UserManager) getContext().getSystemService(
     66                         Context.USER_SERVICE);
     67                 int[] userIds = manager.getEnabledProfileIds(ActivityManager.getCurrentUser());
     68                 if (userIds == null || userIds.length == 0) {
     69                     return;
     70                 }
     71                 Intent intent = new Intent(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
     72                 intent.putExtra(Intent.EXTRA_PACKAGES, pkgNames);
     73                 intent.putExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE, type);
     74                 for (int userId : userIds) {
     75                     getContext().sendBroadcastAsUser(intent, UserHandle.of(userId),
     76                             android.Manifest.permission.RECEIVE_MEDIA_RESOURCE_USAGE);
     77                 }
     78             } finally {
     79                 Binder.restoreCallingIdentity(identity);
     80             }
     81         }
     82 
     83         private String[] getPackageNamesFromPid(int pid) {
     84             try {
     85                 for (ActivityManager.RunningAppProcessInfo proc :
     86                         ActivityManager.getService().getRunningAppProcesses()) {
     87                     if (proc.pid == pid) {
     88                         return proc.pkgList;
     89                     }
     90                 }
     91             } catch (RemoteException e) {
     92                 Slog.w(TAG, "ActivityManager.getRunningAppProcesses() failed");
     93             }
     94             return null;
     95         }
     96     }
     97 }
     98