152f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk/*
252f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * Copyright 2015 The Android Open Source Project
352f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk *
452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
552f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * you may not use this file except in compliance with the License.
652f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * You may obtain a copy of the License at
752f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk *
852f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
952f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk *
1052f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * Unless required by applicable law or agreed to in writing, software
1152f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
1252f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1352f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * See the License for the specific language governing permissions and
1452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk * limitations under the License.
1552f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk */
1652f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
1752f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk#include <binder/ProcessInfoService.h>
1852f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk#include <binder/IServiceManager.h>
1952f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
2052f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk#include <utils/Log.h>
2152f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk#include <utils/String16.h>
2252f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
2352f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunknamespace android {
2452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
2552f0407d6871c43d1e6502ec6754d5811c86ed82Ruben BrunkProcessInfoService::ProcessInfoService() {
2652f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    updateBinderLocked();
2752f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk}
2852f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
2952f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunkstatus_t ProcessInfoService::getProcessStatesImpl(size_t length, /*in*/ int32_t* pids,
3052f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        /*out*/ int32_t* states) {
3152f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    status_t err = NO_ERROR;
3252f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    sp<IProcessInfoService> pis;
3352f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    mProcessInfoLock.lock();
3452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    pis = mProcessInfoService;
3552f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    mProcessInfoLock.unlock();
3652f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
3752f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) {
3852f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
3952f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        if (pis != NULL) {
4052f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk            err = pis->getProcessStatesFromPids(length, /*in*/ pids, /*out*/ states);
4152f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk            if (err == NO_ERROR) return NO_ERROR; // success
4252f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk            if (IInterface::asBinder(pis)->isBinderAlive()) return err;
4352f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        }
4452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        sleep(1);
4552f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
4652f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        mProcessInfoLock.lock();
4752f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        if (pis == mProcessInfoService) {
4852f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk            updateBinderLocked();
4952f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        }
5052f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        pis = mProcessInfoService;
5152f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        mProcessInfoLock.unlock();
5252f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    }
5352f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
5452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    ALOGW("%s: Could not retrieve process states from ProcessInfoService after %d retries.",
5552f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk            __FUNCTION__, BINDER_ATTEMPT_LIMIT);
5652f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
5752f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    return TIMED_OUT;
5852f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk}
5952f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
60b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peevstatus_t ProcessInfoService::getProcessStatesScoresImpl(size_t length,
61b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        /*in*/ int32_t* pids, /*out*/ int32_t* states,
62b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        /*out*/ int32_t *scores) {
63b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    status_t err = NO_ERROR;
64b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    sp<IProcessInfoService> pis;
65b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    mProcessInfoLock.lock();
66b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    pis = mProcessInfoService;
67b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    mProcessInfoLock.unlock();
68b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev
69b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) {
70b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev
71b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        if (pis != NULL) {
72b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev            err = pis->getProcessStatesAndOomScoresFromPids(length,
73b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev                    /*in*/ pids, /*out*/ states, /*out*/ scores);
74b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev            if (err == NO_ERROR) return NO_ERROR; // success
75b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev            if (IInterface::asBinder(pis)->isBinderAlive()) return err;
76b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        }
77b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        sleep(1);
78b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev
79b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        mProcessInfoLock.lock();
80b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        if (pis == mProcessInfoService) {
81b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev            updateBinderLocked();
82b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        }
83b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        pis = mProcessInfoService;
84b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev        mProcessInfoLock.unlock();
85b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    }
86b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev
87b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    ALOGW("%s: Could not retrieve process states and scores "
88b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev            "from ProcessInfoService after %d retries.", __FUNCTION__,
89b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev            BINDER_ATTEMPT_LIMIT);
90b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev
91b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev    return TIMED_OUT;
92b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev}
93b4f33df8911e1b2804714fc4e78e8172d2eadd46Emilian Peev
9452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunkvoid ProcessInfoService::updateBinderLocked() {
9552f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    const sp<IServiceManager> sm(defaultServiceManager());
9652f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    if (sm != NULL) {
9752f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        const String16 name("processinfo");
9852f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk        mProcessInfoService = interface_cast<IProcessInfoService>(sm->checkService(name));
9952f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk    }
10052f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk}
10152f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
10252f0407d6871c43d1e6502ec6754d5811c86ed82Ruben BrunkANDROID_SINGLETON_STATIC_INSTANCE(ProcessInfoService);
10352f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk
10452f0407d6871c43d1e6502ec6754d5811c86ed82Ruben Brunk}; // namespace android
105