1539d25613834439303e3c4cb270587c343808f17Todd Poynor/*
2539d25613834439303e3c4cb270587c343808f17Todd Poynor * Copyright (C) 2017 The Android Open Source Project
3539d25613834439303e3c4cb270587c343808f17Todd Poynor *
4539d25613834439303e3c4cb270587c343808f17Todd Poynor * Licensed under the Apache License, Version 2.0 (the "License");
5539d25613834439303e3c4cb270587c343808f17Todd Poynor * you may not use this file except in compliance with the License.
6539d25613834439303e3c4cb270587c343808f17Todd Poynor * You may obtain a copy of the License at
7539d25613834439303e3c4cb270587c343808f17Todd Poynor *
8539d25613834439303e3c4cb270587c343808f17Todd Poynor *      http://www.apache.org/licenses/LICENSE-2.0
9539d25613834439303e3c4cb270587c343808f17Todd Poynor *
10539d25613834439303e3c4cb270587c343808f17Todd Poynor * Unless required by applicable law or agreed to in writing, software
11539d25613834439303e3c4cb270587c343808f17Todd Poynor * distributed under the License is distributed on an "AS IS" BASIS,
12539d25613834439303e3c4cb270587c343808f17Todd Poynor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13539d25613834439303e3c4cb270587c343808f17Todd Poynor * See the License for the specific language governing permissions and
14539d25613834439303e3c4cb270587c343808f17Todd Poynor * limitations under the License.
15539d25613834439303e3c4cb270587c343808f17Todd Poynor */
16539d25613834439303e3c4cb270587c343808f17Todd Poynor
17539d25613834439303e3c4cb270587c343808f17Todd Poynor#include "ThermalService.h"
18539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <android/os/IThermalService.h>
19539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <android/os/IThermalEventListener.h>
20539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <android/os/Temperature.h>
21539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <binder/IPCThreadState.h>
22539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <binder/IServiceManager.h>
23539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <utils/Errors.h>
24539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <utils/Mutex.h>
25539d25613834439303e3c4cb270587c343808f17Todd Poynor#include <utils/String16.h>
26539d25613834439303e3c4cb270587c343808f17Todd Poynor
27539d25613834439303e3c4cb270587c343808f17Todd Poynornamespace android {
28539d25613834439303e3c4cb270587c343808f17Todd Poynornamespace os {
29539d25613834439303e3c4cb270587c343808f17Todd Poynor
30539d25613834439303e3c4cb270587c343808f17Todd Poynor/**
31539d25613834439303e3c4cb270587c343808f17Todd Poynor * Notify registered listeners of a thermal throttling start/stop event.
32539d25613834439303e3c4cb270587c343808f17Todd Poynor * @param temperature the temperature at which the event was generated
33539d25613834439303e3c4cb270587c343808f17Todd Poynor */
34539d25613834439303e3c4cb270587c343808f17Todd Poynorbinder::Status ThermalService::notifyThrottling(
35539d25613834439303e3c4cb270587c343808f17Todd Poynor    const bool isThrottling, const Temperature& temperature) {
36539d25613834439303e3c4cb270587c343808f17Todd Poynor    Mutex::Autolock _l(mListenersLock);
37539d25613834439303e3c4cb270587c343808f17Todd Poynor
38539d25613834439303e3c4cb270587c343808f17Todd Poynor    mThrottled = isThrottling;
39539d25613834439303e3c4cb270587c343808f17Todd Poynor    mThrottleTemperature = temperature;
40539d25613834439303e3c4cb270587c343808f17Todd Poynor
41539d25613834439303e3c4cb270587c343808f17Todd Poynor    for (size_t i = 0; i < mListeners.size(); i++) {
42539d25613834439303e3c4cb270587c343808f17Todd Poynor      mListeners[i]->notifyThrottling(isThrottling, temperature);
43539d25613834439303e3c4cb270587c343808f17Todd Poynor    }
44539d25613834439303e3c4cb270587c343808f17Todd Poynor    return binder::Status::ok();
45539d25613834439303e3c4cb270587c343808f17Todd Poynor}
46539d25613834439303e3c4cb270587c343808f17Todd Poynor
47539d25613834439303e3c4cb270587c343808f17Todd Poynor/**
48539d25613834439303e3c4cb270587c343808f17Todd Poynor * Query whether the system is currently thermal throttling.
49539d25613834439303e3c4cb270587c343808f17Todd Poynor * @return true if currently thermal throttling, else false
50539d25613834439303e3c4cb270587c343808f17Todd Poynor */
51539d25613834439303e3c4cb270587c343808f17Todd Poynorbinder::Status ThermalService::isThrottling(bool* _aidl_return) {
52539d25613834439303e3c4cb270587c343808f17Todd Poynor    Mutex::Autolock _l(mListenersLock);
53539d25613834439303e3c4cb270587c343808f17Todd Poynor    *_aidl_return = mThrottled;
54539d25613834439303e3c4cb270587c343808f17Todd Poynor    return binder::Status::ok();
55539d25613834439303e3c4cb270587c343808f17Todd Poynor}
56539d25613834439303e3c4cb270587c343808f17Todd Poynor
57539d25613834439303e3c4cb270587c343808f17Todd Poynor/**
58539d25613834439303e3c4cb270587c343808f17Todd Poynor * Register a new thermal event listener.
59539d25613834439303e3c4cb270587c343808f17Todd Poynor * @param listener the client's IThermalEventListener instance to which
60539d25613834439303e3c4cb270587c343808f17Todd Poynor *                 notifications are to be sent
61539d25613834439303e3c4cb270587c343808f17Todd Poynor */
62539d25613834439303e3c4cb270587c343808f17Todd Poynorbinder::Status ThermalService::registerThermalEventListener(
63539d25613834439303e3c4cb270587c343808f17Todd Poynor    const sp<IThermalEventListener>& listener) {
64539d25613834439303e3c4cb270587c343808f17Todd Poynor    {
65539d25613834439303e3c4cb270587c343808f17Todd Poynor        if (listener == NULL)
66539d25613834439303e3c4cb270587c343808f17Todd Poynor            return binder::Status::ok();
67539d25613834439303e3c4cb270587c343808f17Todd Poynor        Mutex::Autolock _l(mListenersLock);
68539d25613834439303e3c4cb270587c343808f17Todd Poynor        // check whether this is a duplicate
69539d25613834439303e3c4cb270587c343808f17Todd Poynor        for (size_t i = 0; i < mListeners.size(); i++) {
70539d25613834439303e3c4cb270587c343808f17Todd Poynor            if (IInterface::asBinder(mListeners[i]) ==
71539d25613834439303e3c4cb270587c343808f17Todd Poynor                IInterface::asBinder(listener)) {
72539d25613834439303e3c4cb270587c343808f17Todd Poynor                return binder::Status::ok();
73539d25613834439303e3c4cb270587c343808f17Todd Poynor            }
74539d25613834439303e3c4cb270587c343808f17Todd Poynor        }
75539d25613834439303e3c4cb270587c343808f17Todd Poynor
76539d25613834439303e3c4cb270587c343808f17Todd Poynor        mListeners.add(listener);
77539d25613834439303e3c4cb270587c343808f17Todd Poynor        IInterface::asBinder(listener)->linkToDeath(this);
78539d25613834439303e3c4cb270587c343808f17Todd Poynor    }
79539d25613834439303e3c4cb270587c343808f17Todd Poynor
80539d25613834439303e3c4cb270587c343808f17Todd Poynor    return binder::Status::ok();
81539d25613834439303e3c4cb270587c343808f17Todd Poynor}
82539d25613834439303e3c4cb270587c343808f17Todd Poynor
83539d25613834439303e3c4cb270587c343808f17Todd Poynor/**
84539d25613834439303e3c4cb270587c343808f17Todd Poynor * Unregister a previously-registered thermal event listener.
85539d25613834439303e3c4cb270587c343808f17Todd Poynor * @param listener the client's IThermalEventListener instance to which
86539d25613834439303e3c4cb270587c343808f17Todd Poynor *                 notifications are to no longer be sent
87539d25613834439303e3c4cb270587c343808f17Todd Poynor */
88539d25613834439303e3c4cb270587c343808f17Todd Poynorbinder::Status ThermalService::unregisterThermalEventListener(
89539d25613834439303e3c4cb270587c343808f17Todd Poynor    const sp<IThermalEventListener>& listener) {
90539d25613834439303e3c4cb270587c343808f17Todd Poynor    if (listener == NULL)
91539d25613834439303e3c4cb270587c343808f17Todd Poynor        return binder::Status::ok();
92539d25613834439303e3c4cb270587c343808f17Todd Poynor    Mutex::Autolock _l(mListenersLock);
93539d25613834439303e3c4cb270587c343808f17Todd Poynor    for (size_t i = 0; i < mListeners.size(); i++) {
94539d25613834439303e3c4cb270587c343808f17Todd Poynor        if (IInterface::asBinder(mListeners[i]) ==
95539d25613834439303e3c4cb270587c343808f17Todd Poynor            IInterface::asBinder(listener)) {
96539d25613834439303e3c4cb270587c343808f17Todd Poynor            IInterface::asBinder(mListeners[i])->unlinkToDeath(this);
97539d25613834439303e3c4cb270587c343808f17Todd Poynor            mListeners.removeAt(i);
98539d25613834439303e3c4cb270587c343808f17Todd Poynor            break;
99539d25613834439303e3c4cb270587c343808f17Todd Poynor        }
100539d25613834439303e3c4cb270587c343808f17Todd Poynor    }
101539d25613834439303e3c4cb270587c343808f17Todd Poynor
102539d25613834439303e3c4cb270587c343808f17Todd Poynor    return binder::Status::ok();
103539d25613834439303e3c4cb270587c343808f17Todd Poynor}
104539d25613834439303e3c4cb270587c343808f17Todd Poynor
105539d25613834439303e3c4cb270587c343808f17Todd Poynorvoid ThermalService::binderDied(const wp<IBinder>& who) {
106539d25613834439303e3c4cb270587c343808f17Todd Poynor    Mutex::Autolock _l(mListenersLock);
107539d25613834439303e3c4cb270587c343808f17Todd Poynor
108539d25613834439303e3c4cb270587c343808f17Todd Poynor    for (size_t i = 0; i < mListeners.size(); i++) {
109539d25613834439303e3c4cb270587c343808f17Todd Poynor        if (IInterface::asBinder(mListeners[i]) == who) {
110539d25613834439303e3c4cb270587c343808f17Todd Poynor            mListeners.removeAt(i);
111539d25613834439303e3c4cb270587c343808f17Todd Poynor            break;
112539d25613834439303e3c4cb270587c343808f17Todd Poynor        }
113539d25613834439303e3c4cb270587c343808f17Todd Poynor    }
114539d25613834439303e3c4cb270587c343808f17Todd Poynor}
115539d25613834439303e3c4cb270587c343808f17Todd Poynor
116539d25613834439303e3c4cb270587c343808f17Todd Poynor/**
117539d25613834439303e3c4cb270587c343808f17Todd Poynor * Publish the supplied ThermalService to servicemanager.
118539d25613834439303e3c4cb270587c343808f17Todd Poynor */
119539d25613834439303e3c4cb270587c343808f17Todd Poynorvoid ThermalService::publish(
120539d25613834439303e3c4cb270587c343808f17Todd Poynor    const sp<ThermalService>& service) {
121539d25613834439303e3c4cb270587c343808f17Todd Poynor    defaultServiceManager()->addService(String16("thermalservice"),
122539d25613834439303e3c4cb270587c343808f17Todd Poynor                                        service);
123539d25613834439303e3c4cb270587c343808f17Todd Poynor}
124539d25613834439303e3c4cb270587c343808f17Todd Poynor
125539d25613834439303e3c4cb270587c343808f17Todd Poynor}  // namespace os
126539d25613834439303e3c4cb270587c343808f17Todd Poynor}  // namespace android
127