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 android.app.admin.DevicePolicyManager;
20import android.content.Context;
21import android.content.pm.PackageManager;
22import android.os.Binder;
23import android.os.CpuUsageInfo;
24import android.os.IHardwarePropertiesManager;
25import android.os.Process;
26import android.os.UserHandle;
27import com.android.server.vr.VrManagerInternal;
28
29import java.util.Arrays;
30
31/**
32 * Service for {@link HardwarePropertiesManager}
33 */
34public class HardwarePropertiesManagerService extends IHardwarePropertiesManager.Stub {
35
36    private static native void nativeInit();
37
38    private static native float[] nativeGetFanSpeeds();
39    private static native float[] nativeGetDeviceTemperatures(int type, int source);
40    private static native CpuUsageInfo[] nativeGetCpuUsages();
41
42    private final Context mContext;
43    private final Object mLock = new Object();
44
45    public HardwarePropertiesManagerService(Context context) {
46        mContext = context;
47        synchronized (mLock) {
48            nativeInit();
49        }
50    }
51
52    @Override
53    public float[] getDeviceTemperatures(String callingPackage, int type, int source)
54            throws SecurityException {
55        enforceHardwarePropertiesRetrievalAllowed(callingPackage);
56        synchronized (mLock) {
57            return nativeGetDeviceTemperatures(type, source);
58        }
59    }
60
61    @Override
62    public CpuUsageInfo[] getCpuUsages(String callingPackage) throws SecurityException {
63        enforceHardwarePropertiesRetrievalAllowed(callingPackage);
64        synchronized (mLock) {
65            return nativeGetCpuUsages();
66        }
67    }
68
69    @Override
70    public float[] getFanSpeeds(String callingPackage) throws SecurityException {
71        enforceHardwarePropertiesRetrievalAllowed(callingPackage);
72        synchronized (mLock) {
73            return nativeGetFanSpeeds();
74        }
75    }
76
77    /**
78     * Throws SecurityException if the calling package is not allowed to retrieve information
79     * provided by the service.
80     *
81     * @param callingPackage The calling package name.
82     *
83     * @throws SecurityException if something other than the profile or device owner, or the
84     *        current VR service tries to retrieve information provided by this service.
85     */
86    private void enforceHardwarePropertiesRetrievalAllowed(String callingPackage)
87            throws SecurityException {
88        final PackageManager pm = mContext.getPackageManager();
89        int uid = 0;
90        try {
91            uid = pm.getPackageUid(callingPackage, 0);
92            if (Binder.getCallingUid() != uid) {
93                throw new SecurityException("The caller has faked the package name.");
94            }
95        } catch (PackageManager.NameNotFoundException e) {
96            throw new SecurityException("The caller has faked the package name.");
97        }
98
99        final int userId = UserHandle.getUserId(uid);
100        final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
101        final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
102        if (!dpm.isDeviceOwnerApp(callingPackage) && !dpm.isProfileOwnerApp(callingPackage)
103                && !vrService.isCurrentVrListener(callingPackage, userId)) {
104            throw new SecurityException("The caller is not a device or profile owner or bound "
105                + "VrListenerService.");
106        }
107    }
108}
109