/*
|
* 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;
|
|
import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_BATTERY;
|
import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_CPU;
|
import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_GPU;
|
import static android.os.HardwarePropertiesManager.DEVICE_TEMPERATURE_SKIN;
|
import static android.os.HardwarePropertiesManager.TEMPERATURE_CURRENT;
|
import static android.os.HardwarePropertiesManager.TEMPERATURE_SHUTDOWN;
|
import static android.os.HardwarePropertiesManager.TEMPERATURE_THROTTLING;
|
import static android.os.HardwarePropertiesManager.TEMPERATURE_THROTTLING_BELOW_VR_MIN;
|
|
import android.Manifest;
|
import android.app.AppOpsManager;
|
import android.app.admin.DevicePolicyManager;
|
import android.content.Context;
|
import android.content.pm.PackageManager;
|
import android.os.Binder;
|
import android.os.CpuUsageInfo;
|
import android.os.IHardwarePropertiesManager;
|
import android.os.UserHandle;
|
|
import com.android.internal.util.DumpUtils;
|
import com.android.server.vr.VrManagerInternal;
|
|
import java.io.FileDescriptor;
|
import java.io.PrintWriter;
|
import java.util.Arrays;
|
|
/**
|
* Service for {@link HardwarePropertiesManager}
|
*/
|
public class HardwarePropertiesManagerService extends IHardwarePropertiesManager.Stub {
|
|
private static final String TAG = "HardwarePropertiesManagerService";
|
private static native void nativeInit();
|
|
private static native float[] nativeGetFanSpeeds();
|
private static native float[] nativeGetDeviceTemperatures(int type, int source);
|
private static native CpuUsageInfo[] nativeGetCpuUsages();
|
|
private final Context mContext;
|
private final Object mLock = new Object();
|
private final AppOpsManager mAppOps;
|
|
public HardwarePropertiesManagerService(Context context) {
|
mContext = context;
|
mAppOps = (AppOpsManager)mContext.getSystemService(Context.APP_OPS_SERVICE);
|
synchronized (mLock) {
|
nativeInit();
|
}
|
}
|
|
// TODO - Make HardwarePropertiesManager APIs require a userId to verifiy
|
// cross user permission - b/63697518
|
@Override
|
public float[] getDeviceTemperatures(String callingPackage, int type, int source)
|
throws SecurityException {
|
enforceHardwarePropertiesRetrievalAllowed(callingPackage);
|
synchronized (mLock) {
|
return nativeGetDeviceTemperatures(type, source);
|
}
|
}
|
|
// TODO - Make HardwarePropertiesManager APIs require a userId to verifiy
|
// cross user permission - b/63697518
|
@Override
|
public CpuUsageInfo[] getCpuUsages(String callingPackage) throws SecurityException {
|
enforceHardwarePropertiesRetrievalAllowed(callingPackage);
|
synchronized (mLock) {
|
return nativeGetCpuUsages();
|
}
|
}
|
|
// TODO - Make HardwarePropertiesManager APIs require a userId to verifiy
|
// cross user permission - b/63697518
|
@Override
|
public float[] getFanSpeeds(String callingPackage) throws SecurityException {
|
enforceHardwarePropertiesRetrievalAllowed(callingPackage);
|
synchronized (mLock) {
|
return nativeGetFanSpeeds();
|
}
|
}
|
|
private String getCallingPackageName() {
|
final String[] packages = mContext.getPackageManager().getPackagesForUid(
|
Binder.getCallingUid());
|
if (packages != null && packages.length > 0) {
|
return packages[0];
|
}
|
return "unknown";
|
}
|
|
private void dumpTempValues(String pkg, PrintWriter pw, int type,
|
String typeLabel) {
|
dumpTempValues(pkg, pw, type, typeLabel, "temperatures: ",
|
TEMPERATURE_CURRENT);
|
dumpTempValues(pkg, pw, type, typeLabel, "throttling temperatures: ",
|
TEMPERATURE_THROTTLING);
|
dumpTempValues(pkg, pw, type, typeLabel, "shutdown temperatures: ",
|
TEMPERATURE_SHUTDOWN);
|
dumpTempValues(pkg, pw, type, typeLabel, "vr throttling temperatures: ",
|
TEMPERATURE_THROTTLING_BELOW_VR_MIN);
|
}
|
|
private void dumpTempValues(String pkg, PrintWriter pw, int type,
|
String typeLabel, String subLabel, int valueType) {
|
pw.println(typeLabel + subLabel + Arrays.toString(getDeviceTemperatures(
|
pkg, type, valueType)));
|
}
|
|
@Override
|
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
|
pw.println("****** Dump of HardwarePropertiesManagerService ******");
|
|
final String PKG = getCallingPackageName();
|
dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_CPU, "CPU ");
|
dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_GPU, "GPU ");
|
dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_BATTERY, "Battery ");
|
dumpTempValues(PKG, pw, DEVICE_TEMPERATURE_SKIN, "Skin ");
|
|
float[] fanSpeeds = getFanSpeeds(PKG);
|
pw.println("Fan speed: " + Arrays.toString(fanSpeeds) + "\n");
|
|
CpuUsageInfo[] cpuUsageInfos = getCpuUsages(PKG);
|
int core = 0;
|
for (int i = 0; i < cpuUsageInfos.length; i++) {
|
pw.println("Cpu usage of core: " + i +
|
", active = " + cpuUsageInfos[i].getActive() +
|
", total = " + cpuUsageInfos[i].getTotal());
|
}
|
pw.println("****** End of HardwarePropertiesManagerService dump ******");
|
}
|
|
/**
|
* Throws SecurityException if the calling package is not allowed to retrieve information
|
* provided by the service.
|
*
|
* @param callingPackage The calling package name.
|
*
|
* @throws SecurityException if something other than the device owner, the current VR service,
|
* or a caller holding the {@link Manifest.permission#DEVICE_POWER} permission tries to
|
* retrieve information provided by this service.
|
*/
|
private void enforceHardwarePropertiesRetrievalAllowed(String callingPackage)
|
throws SecurityException {
|
mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
|
final int userId = UserHandle.getUserId(Binder.getCallingUid());
|
final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
|
final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
|
if (!dpm.isDeviceOwnerApp(callingPackage)
|
&& mContext.checkCallingOrSelfPermission(Manifest.permission.DEVICE_POWER)
|
!= PackageManager.PERMISSION_GRANTED
|
&& (vrService == null || !vrService.isCurrentVrListener(callingPackage, userId))) {
|
throw new SecurityException("The caller is neither a device owner"
|
+ ", nor holding the DEVICE_POWER permission, nor the current VrListener.");
|
}
|
}
|
}
|