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; 18 19import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY; 20import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU; 21import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU; 22import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN; 23import static android.os.HardwarePropertiesManager.TEMPERATURE_CURRENT; 24import static android.os.HardwarePropertiesManager.TEMPERATURE_SHUTDOWN; 25import static android.os.HardwarePropertiesManager.TEMPERATURE_THROTTLING; 26import static android.os.HardwarePropertiesManager.TEMPERATURE_THROTTLING_BELOW_VR_MIN; 27 28import android.Manifest; 29import android.app.ActivityManager; 30import android.app.AppOpsManager; 31import android.app.admin.DevicePolicyManager; 32import android.content.Context; 33import android.content.pm.PackageManager; 34import android.os.Binder; 35import android.os.CpuUsageInfo; 36import android.os.IHardwarePropertiesManager; 37import android.os.Process; 38import android.os.UserHandle; 39import com.android.internal.util.DumpUtils; 40import com.android.server.vr.VrManagerInternal; 41 42import java.io.FileDescriptor; 43import java.io.PrintWriter; 44import java.util.Arrays; 45 46/** 47 * Service for {@link HardwarePropertiesManager} 48 */ 49public class HardwarePropertiesManagerService extends IHardwarePropertiesManager.Stub { 50 51 private static final String TAG = "HardwarePropertiesManagerService"; 52 private static native void nativeInit(); 53 54 private static native float[] nativeGetFanSpeeds(); 55 private static native float[] nativeGetDeviceTemperatures(int type, int source); 56 private static native CpuUsageInfo[] nativeGetCpuUsages(); 57 58 private final Context mContext; 59 private final Object mLock = new Object(); 60 private final AppOpsManager mAppOps; 61 62 public HardwarePropertiesManagerService(Context context) { 63 mContext = context; 64 mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE); 65 synchronized (mLock) { 66 nativeInit(); 67 } 68 } 69 70 // TODO - Make HardwarePropertiesManager APIs require a userId to verifiy 71 // cross user permission - b/63697518 72 @Override 73 public float[] getDeviceTemperatures(String callingPackage, int type, int source) 74 throws SecurityException { 75 enforceHardwarePropertiesRetrievalAllowed(callingPackage); 76 synchronized (mLock) { 77 return nativeGetDeviceTemperatures(type, source); 78 } 79 } 80 81 // TODO - Make HardwarePropertiesManager APIs require a userId to verifiy 82 // cross user permission - b/63697518 83 @Override 84 public CpuUsageInfo[] getCpuUsages(String callingPackage) throws SecurityException { 85 enforceHardwarePropertiesRetrievalAllowed(callingPackage); 86 synchronized (mLock) { 87 return nativeGetCpuUsages(); 88 } 89 } 90 91 // TODO - Make HardwarePropertiesManager APIs require a userId to verifiy 92 // cross user permission - b/63697518 93 @Override 94 public float[] getFanSpeeds(String callingPackage) throws SecurityException { 95 enforceHardwarePropertiesRetrievalAllowed(callingPackage); 96 synchronized (mLock) { 97 return nativeGetFanSpeeds(); 98 } 99 } 100 101 private String getCallingPackageName() { 102 final String[] packages = mContext.getPackageManager().getPackagesForUid( 103 Binder.getCallingUid()); 104 if (packages != null && packages.length > 0) { 105 return packages[0]; 106 } 107 return "unknown"; 108 } 109 110 private void dumpTempValues(String pkg, PrintWriter pw, int type, 111 String typeLabel) { 112 dumpTempValues(pkg, pw, type, typeLabel, "temperatures: ", 113 TEMPERATURE_CURRENT); 114 dumpTempValues(pkg, pw, type, typeLabel, "throttling temperatures: ", 115 TEMPERATURE_THROTTLING); 116 dumpTempValues(pkg, pw, type, typeLabel, "shutdown temperatures: ", 117 TEMPERATURE_SHUTDOWN); 118 dumpTempValues(pkg, pw, type, typeLabel, "vr throttling temperatures: ", 119 TEMPERATURE_THROTTLING_BELOW_VR_MIN); 120 } 121 122 private void dumpTempValues(String pkg, PrintWriter pw, int type, 123 String typeLabel, String subLabel, int valueType) { 124 pw.println(typeLabel + subLabel + Arrays.toString(getDeviceTemperatures( 125 pkg, type, valueType))); 126 } 127 128 @Override 129 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 130 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 131 pw.println("****** Dump of HardwarePropertiesManagerService ******"); 132 133 final String PKG = getCallingPackageName(); 134 dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_CPU, "CPU "); 135 dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_GPU, "GPU "); 136 dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_BATTERY, "Battery "); 137 dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_SKIN, "Skin "); 138 139 float[] fanSpeeds = getFanSpeeds(PKG); 140 pw.println("Fan speed: " + Arrays.toString(fanSpeeds) + "\n"); 141 142 CpuUsageInfo[] cpuUsageInfos = getCpuUsages(PKG); 143 int core = 0; 144 for (int i = 0; i < cpuUsageInfos.length; i++) { 145 pw.println("Cpu usage of core: " + i + 146 ", active = " + cpuUsageInfos[i].getActive() + 147 ", total = " + cpuUsageInfos[i].getTotal()); 148 } 149 pw.println("****** End of HardwarePropertiesManagerService dump ******"); 150 } 151 152 /** 153 * Throws SecurityException if the calling package is not allowed to retrieve information 154 * provided by the service. 155 * 156 * @param callingPackage The calling package name. 157 * 158 * @throws SecurityException if something other than the device owner, the current VR service, 159 * or a caller holding the {@link Manifest.permission#DEVICE_POWER} permission tries to 160 * retrieve information provided by this service. 161 */ 162 private void enforceHardwarePropertiesRetrievalAllowed(String callingPackage) 163 throws SecurityException { 164 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 165 final int userId = UserHandle.getUserId(Binder.getCallingUid()); 166 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 167 final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class); 168 if (!dpm.isDeviceOwnerApp(callingPackage) 169 && !vrService.isCurrentVrListener(callingPackage, userId) 170 && mContext.checkCallingOrSelfPermission(Manifest.permission.DEVICE_POWER) 171 != PackageManager.PERMISSION_GRANTED) { 172 throw new SecurityException("The caller is not a device owner, bound VrListenerService" 173 + ", or holding the DEVICE_POWER permission."); 174 } 175 } 176} 177 178 179