Added hardwareproperties SystemService

Add HardwarePropertiesManagerService which call native methods to
get CPU, GPU, battery temperatures, CPU usage info, fan speeds.
Restrict hardware properties retrieval only for device and profile
owners.

Bug: 26945055
Change-Id: I4d6b30b78e575532d5e9cfa59ef6cd81355439d4
This commit is contained in:
Polina Bondarenko
2016-02-12 20:38:23 +01:00
parent 5393a6605f
commit f8754ac212
12 changed files with 212 additions and 24 deletions

View File

@@ -215,6 +215,7 @@ LOCAL_SRC_FILES += \
core/java/android/os/IBatteryPropertiesRegistrar.aidl \
core/java/android/os/ICancellationSignal.aidl \
core/java/android/os/IDeviceIdleController.aidl \
core/java/android/os/IHardwarePropertiesManager.aidl \
core/java/android/os/IMaintenanceActivityListener.aidl \
core/java/android/os/IMessenger.aidl \
core/java/android/os/INetworkActivityListener.aidl \

View File

@@ -89,6 +89,7 @@ import android.os.BatteryManager;
import android.os.DropBoxManager;
import android.os.HardwarePropertiesManager;
import android.os.IBinder;
import android.os.IHardwarePropertiesManager;
import android.os.IPowerManager;
import android.os.IUserManager;
import android.os.PowerManager;
@@ -715,7 +716,14 @@ final class SystemServiceRegistry {
new CachedServiceFetcher<HardwarePropertiesManager>() {
@Override
public HardwarePropertiesManager createService(ContextImpl ctx) {
return new HardwarePropertiesManager();
IBinder b = ServiceManager.getService(Context.HARDWARE_PROPERTIES_SERVICE);
IHardwarePropertiesManager service =
IHardwarePropertiesManager.Stub.asInterface(b);
if (service == null) {
Log.wtf(TAG, "Failed to get hardwareproperties service.");
return null;
}
return new HardwarePropertiesManager(ctx, service);
}});
registerService(Context.SOUND_TRIGGER_SERVICE, SoundTriggerManager.class,

View File

@@ -0,0 +1,18 @@
/* Copyright 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 android.os;
parcelable CpuUsageInfo;

View File

@@ -17,10 +17,12 @@ package android.os;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.util.Log;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* The HardwarePropertiesManager class provides a mechanism of accessing hardware state of a
* device: CPU, GPU and battery temperatures, CPU usage per core, fan speed, etc.
@@ -29,11 +31,7 @@ public class HardwarePropertiesManager {
private static final String TAG = HardwarePropertiesManager.class.getSimpleName();
private static native void nativeInit();
private static native float[] nativeGetFanSpeeds();
private static native float[] nativeGetDeviceTemperatures(int type);
private static native CpuUsageInfo[] nativeGetCpuUsages();
private final IHardwarePropertiesManager mService;
@Retention(RetentionPolicy.SOURCE)
@IntDef({
@@ -54,9 +52,13 @@ public class HardwarePropertiesManager {
/** Temperature of battery in Celsius. */
public static final int DEVICE_TEMPERATURE_BATTERY = 2;
/** Calling app context. */
private final Context mContext;
/** @hide */
public HardwarePropertiesManager() {
nativeInit();
public HardwarePropertiesManager(Context context, IHardwarePropertiesManager service) {
mContext = context;
mService = service;
}
/**
@@ -68,13 +70,19 @@ public class HardwarePropertiesManager {
* Empty if platform doesn't provide the queried temperature.
*
* @throws IllegalArgumentException if an incorrect temperature type is queried.
* @throws SecurityException if a non profile or device owner tries to call this method.
*/
public @NonNull float[] getDeviceTemperatures(@DeviceTemperatureType int type) {
switch (type) {
case DEVICE_TEMPERATURE_CPU:
case DEVICE_TEMPERATURE_GPU:
case DEVICE_TEMPERATURE_BATTERY:
return nativeGetDeviceTemperatures(type);
try {
return mService.getDeviceTemperatures(mContext.getOpPackageName(), type);
} catch (RemoteException e) {
Log.w(TAG, "Could not get device temperatures", e);
return new float[0];
}
default:
throw new IllegalArgumentException();
}
@@ -85,18 +93,32 @@ public class HardwarePropertiesManager {
*
* @return an array of {@link android.os.CpuUsageInfo} for each core.
* Empty if CPU usage is not supported on this system.
*
* @throws SecurityException if a non profile or device owner tries to call this method.
*/
public @NonNull CpuUsageInfo[] getCpuUsages() {
return nativeGetCpuUsages();
try {
return mService.getCpuUsages(mContext.getOpPackageName());
} catch (RemoteException e) {
Log.w(TAG, "Could not get CPU usages", e);
return new CpuUsageInfo[0];
}
}
/**
* Return an array of fan speeds in RPM.
*
* @return an arrat of float fan speeds. Empty if there is no fans or fan speed
* not supported on this system.
* @return an array of float fan speeds in RPM. Empty if there are no fans or fan speed is not
* supported on this system.
*
* @throws SecurityException if a non profile or device owner tries to call this method.
*/
public @NonNull float[] getFanSpeeds() {
return nativeGetFanSpeeds();
try {
return mService.getFanSpeeds(mContext.getOpPackageName());
} catch (RemoteException e) {
Log.w(TAG, "Could not get fan speeds", e);
return new float[0];
}
}
}

View File

@@ -0,0 +1,28 @@
/*
**
** Copyright 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 android.os;
import android.os.CpuUsageInfo;
/** @hide */
interface IHardwarePropertiesManager {
float[] getDeviceTemperatures(String callingPackage, int type);
CpuUsageInfo[] getCpuUsages(String callingPackage);
float[] getFanSpeeds(String callingPackage);
}

View File

@@ -177,8 +177,7 @@ LOCAL_SRC_FILES:= \
com_android_internal_net_NetworkStatsFactory.cpp \
com_android_internal_os_Zygote.cpp \
com_android_internal_util_VirtualRefBasePtr.cpp \
com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp \
android_os_HardwarePropertiesManager.cpp
com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \

View File

@@ -198,7 +198,6 @@ extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env
extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
extern int register_com_android_internal_os_Zygote(JNIEnv *env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
extern int register_android_os_HardwarePropertiesManager(JNIEnv *env);
static AndroidRuntime* gCurRuntime = NULL;
@@ -1390,7 +1389,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
REG_JNI(register_android_os_HardwarePropertiesManager),
};

View File

@@ -0,0 +1,99 @@
/*
* 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 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 java.util.Arrays;
/**
* Service for {@link HardwarePropertiesManager}
*/
public class HardwarePropertiesManagerService extends IHardwarePropertiesManager.Stub {
private static native void nativeInit();
private static native float[] nativeGetFanSpeeds();
private static native float[] nativeGetDeviceTemperatures(int type);
private static native CpuUsageInfo[] nativeGetCpuUsages();
private final Context mContext;
private final Object mLock = new Object();
public HardwarePropertiesManagerService(Context context) {
mContext = context;
synchronized (mLock) {
nativeInit();
}
}
@Override
public float[] getDeviceTemperatures(String callingPackage, int type) throws SecurityException {
enforceHardwarePropertiesRetrievalAllowed(callingPackage);
synchronized (mLock) {
return nativeGetDeviceTemperatures(type);
}
}
@Override
public CpuUsageInfo[] getCpuUsages(String callingPackage) throws SecurityException {
enforceHardwarePropertiesRetrievalAllowed(callingPackage);
synchronized (mLock) {
return nativeGetCpuUsages();
}
}
@Override
public float[] getFanSpeeds(String callingPackage) throws SecurityException {
enforceHardwarePropertiesRetrievalAllowed(callingPackage);
synchronized (mLock) {
return nativeGetFanSpeeds();
}
}
/**
* 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 a non profile or device owner tries to retrieve information
* provided by the service.
*/
private void enforceHardwarePropertiesRetrievalAllowed(String callingPackage)
throws SecurityException {
final PackageManager pm = mContext.getPackageManager();
try {
final int uid = pm.getPackageUid(callingPackage, 0);
if (Binder.getCallingUid() != uid) {
throw new SecurityException("The caller has faked the package name.");
}
} catch (PackageManager.NameNotFoundException e) {
throw new SecurityException("The caller has faked the package name.");
}
final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
if (!dpm.isDeviceOwnerApp(callingPackage) && !dpm.isProfileOwnerApp(callingPackage)) {
throw new SecurityException("The caller is not a device or profile owner.");
}
}
}

View File

@@ -17,6 +17,7 @@ LOCAL_SRC_FILES += \
$(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
$(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
$(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
$(LOCAL_REL_DIR)/com_android_server_HardwarePropertiesManagerService.cpp \
$(LOCAL_REL_DIR)/com_android_server_hdmi_HdmiCecController.cpp \
$(LOCAL_REL_DIR)/com_android_server_input_InputApplicationHandle.cpp \
$(LOCAL_REL_DIR)/com_android_server_input_InputManagerService.cpp \

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#define LOG_TAG "HardwarePropertiesManager-JNI"
#define LOG_TAG "HardwarePropertiesManagerService-JNI"
#include "JNIHelp.h"
#include "jni.h"
@@ -137,7 +137,7 @@ static jobjectArray nativeGetCpuUsages(JNIEnv *env, jclass /* clazz */) {
// ----------------------------------------------------------------------------
static const JNINativeMethod gHardwarePropertiesManagerMethods[] = {
static const JNINativeMethod gHardwarePropertiesManagerServiceMethods[] = {
/* name, signature, funcPtr */
{ "nativeInit", "()V",
(void*) nativeInit },
@@ -149,11 +149,11 @@ static const JNINativeMethod gHardwarePropertiesManagerMethods[] = {
(void*) nativeGetCpuUsages }
};
int register_android_os_HardwarePropertiesManager(JNIEnv* env) {
int register_android_server_HardwarePropertiesManagerService(JNIEnv* env) {
gHardwarePropertiesModule = nullptr;
int res = jniRegisterNativeMethods(env, "android/os/HardwarePropertiesManager",
gHardwarePropertiesManagerMethods,
NELEM(gHardwarePropertiesManagerMethods));
int res = jniRegisterNativeMethods(env, "com/android/server/HardwarePropertiesManagerService",
gHardwarePropertiesManagerServiceMethods,
NELEM(gHardwarePropertiesManagerServiceMethods));
jclass clazz = env->FindClass("android/os/CpuUsageInfo");
gCpuUsageInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
gCpuUsageInfoClassInfo.initMethod = GetMethodIDOrDie(env, gCpuUsageInfoClassInfo.clazz,

View File

@@ -44,6 +44,7 @@ int register_android_server_hdmi_HdmiCecController(JNIEnv* env);
int register_android_server_tv_TvInputHal(JNIEnv* env);
int register_android_server_PersistentDataBlockService(JNIEnv* env);
int register_android_server_Watchdog(JNIEnv* env);
int register_android_server_HardwarePropertiesManagerService(JNIEnv* env);
};
using namespace android;
@@ -83,6 +84,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
register_android_server_tv_TvInputHal(env);
register_android_server_PersistentDataBlockService(env);
register_android_server_Watchdog(env);
register_android_server_HardwarePropertiesManagerService(env);
return JNI_VERSION_1_4;

View File

@@ -488,6 +488,7 @@ public final class SystemServer {
MmsServiceBroker mmsService = null;
EntropyMixer entropyMixer = null;
VrManagerService vrManagerService = null;
HardwarePropertiesManagerService hardwarePropertiesService = null;
boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
@@ -962,6 +963,17 @@ public final class SystemServer {
Slog.e(TAG, "Failure starting SerialService", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
"StartHardwarePropertiesManagerService");
try {
hardwarePropertiesService = new HardwarePropertiesManagerService(context);
ServiceManager.addService(Context.HARDWARE_PROPERTIES_SERVICE,
hardwarePropertiesService);
} catch (Throwable e) {
Slog.e(TAG, "Failure starting HardwarePropertiesManagerService", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
mSystemServiceManager.startService(TwilightService.class);