/*
 * Copyright (C) 2020 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.
 */

#define LOG_NDEBUG 0
#define LOG_TAG "AActivityManager"
#include <utils/Log.h>

#include <android/activity_manager.h>
#include <binder/ActivityManager.h>

namespace android {
namespace activitymanager {

// Global instance of ActivityManager, service is obtained only on first use.
static ActivityManager gAm;
// String tag used with ActivityManager.
static const String16& getTag() {
    static String16 tag("libandroid");
    return tag;
}

struct UidObserver : public BnUidObserver, public virtual IBinder::DeathRecipient {
    explicit UidObserver(const AActivityManager_onUidImportance& cb,
                         int32_t cutpoint, void* cookie)
          : mCallback(cb), mImportanceCutpoint(cutpoint), mCookie(cookie), mRegistered(false) {}
    bool registerSelf();
    void unregisterSelf();

    // IUidObserver
    void onUidGone(uid_t uid, bool disabled) override;
    void onUidActive(uid_t uid) override;
    void onUidIdle(uid_t uid, bool disabled) override;
    void onUidStateChanged(uid_t uid, int32_t procState, int64_t procStateSeq,
                           int32_t capability) override;
    void onUidProcAdjChanged(uid_t uid, int32_t adj) override;

    // IBinder::DeathRecipient implementation
    void binderDied(const wp<IBinder>& who) override;

    static int32_t procStateToImportance(int32_t procState);
    static int32_t importanceToProcState(int32_t importance);

    AActivityManager_onUidImportance mCallback;
    int32_t mImportanceCutpoint;
    void* mCookie;
    std::mutex mRegisteredLock;
    bool mRegistered GUARDED_BY(mRegisteredLock);
};

//static
int32_t UidObserver::procStateToImportance(int32_t procState) {
    // TODO: remove this after adding Importance to onUidStateChanged callback.
    if (procState == ActivityManager::PROCESS_STATE_NONEXISTENT) {
        return AACTIVITYMANAGER_IMPORTANCE_GONE;
    } else if (procState >= ActivityManager::PROCESS_STATE_HOME) {
        return AACTIVITYMANAGER_IMPORTANCE_CACHED;
    } else if (procState == ActivityManager::PROCESS_STATE_HEAVY_WEIGHT) {
        return AACTIVITYMANAGER_IMPORTANCE_CANT_SAVE_STATE;
    } else if (procState >= ActivityManager::PROCESS_STATE_TOP_SLEEPING) {
        return AACTIVITYMANAGER_IMPORTANCE_TOP_SLEEPING;
    } else if (procState >= ActivityManager::PROCESS_STATE_SERVICE) {
        return AACTIVITYMANAGER_IMPORTANCE_SERVICE;
    } else if (procState >= ActivityManager::PROCESS_STATE_TRANSIENT_BACKGROUND) {
        return AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE;
    } else if (procState >= ActivityManager::PROCESS_STATE_IMPORTANT_FOREGROUND) {
        return AACTIVITYMANAGER_IMPORTANCE_VISIBLE;
    } else if (procState >= ActivityManager::PROCESS_STATE_FOREGROUND_SERVICE) {
        return AACTIVITYMANAGER_IMPORTANCE_FOREGROUND_SERVICE;
    } else {
        return AACTIVITYMANAGER_IMPORTANCE_FOREGROUND;
    }
}

//static
int32_t UidObserver::importanceToProcState(int32_t importance) {
    // TODO: remove this after adding Importance to onUidStateChanged callback.
    if (importance == AACTIVITYMANAGER_IMPORTANCE_GONE) {
        return ActivityManager::PROCESS_STATE_NONEXISTENT;
    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_CACHED) {
        return ActivityManager::PROCESS_STATE_HOME;
    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_CANT_SAVE_STATE) {
        return ActivityManager::PROCESS_STATE_HEAVY_WEIGHT;
    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_TOP_SLEEPING) {
        return ActivityManager::PROCESS_STATE_TOP_SLEEPING;
    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_SERVICE) {
        return ActivityManager::PROCESS_STATE_SERVICE;
    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_PERCEPTIBLE) {
        return ActivityManager::PROCESS_STATE_TRANSIENT_BACKGROUND;
    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_VISIBLE) {
        return ActivityManager::PROCESS_STATE_IMPORTANT_FOREGROUND;
    } else if (importance >= AACTIVITYMANAGER_IMPORTANCE_FOREGROUND_SERVICE) {
        return ActivityManager::PROCESS_STATE_FOREGROUND_SERVICE;
    } else {
        return ActivityManager::PROCESS_STATE_TOP;
    }
}


void UidObserver::onUidGone(uid_t uid, bool disabled __unused) {
    std::scoped_lock lock{mRegisteredLock};

    if (mRegistered && mCallback) {
        mCallback(uid, AACTIVITYMANAGER_IMPORTANCE_GONE, mCookie);
    }
}

void UidObserver::onUidActive(uid_t uid __unused) {}

void UidObserver::onUidIdle(uid_t uid __unused, bool disabled __unused) {}

void UidObserver::onUidProcAdjChanged(uid_t uid __unused, int32_t adj __unused) {}

void UidObserver::onUidStateChanged(uid_t uid, int32_t procState,
                                    int64_t procStateSeq __unused,
                                    int32_t capability __unused) {
    std::scoped_lock lock{mRegisteredLock};

    if (mRegistered && mCallback) {
        mCallback(uid, procStateToImportance(procState), mCookie);
    }
}

void UidObserver::binderDied(const wp<IBinder>& /*who*/) {
    // ActivityManager is dead, try to re-register.
    {
        std::scoped_lock lock{mRegisteredLock};
        // If client already unregistered, don't try to re-register.
        if (!mRegistered) {
            return;
        }
        // Clear mRegistered to re-register.
        mRegistered = false;
    }
    registerSelf();
}

bool UidObserver::registerSelf() {
    std::scoped_lock lock{mRegisteredLock};
    if (mRegistered) {
        return true;
    }

    status_t res = gAm.linkToDeath(this);
    if (res != OK) {
        ALOGE("UidObserver: Failed to linkToDeath with ActivityManager (err %d)", res);
        return false;
    }

    // TODO: it seems only way to get all changes is to set cutoff to PROCESS_STATE_UNKNOWN.
    // But there is no equivalent of PROCESS_STATE_UNKNOWN in the UidImportance.
    // If mImportanceCutpoint is < 0, use PROCESS_STATE_UNKNOWN instead.
    res = gAm.registerUidObserver(
            this,
            ActivityManager::UID_OBSERVER_GONE | ActivityManager::UID_OBSERVER_PROCSTATE,
            (mImportanceCutpoint < 0) ? ActivityManager::PROCESS_STATE_UNKNOWN
                                      : importanceToProcState(mImportanceCutpoint),
            getTag());
    if (res != OK) {
        ALOGE("UidObserver: Failed to register with ActivityManager (err %d)", res);
        gAm.unlinkToDeath(this);
        return false;
    }

    mRegistered = true;
    ALOGV("UidObserver: Registered with ActivityManager");
    return true;
}

void UidObserver::unregisterSelf() {
    std::scoped_lock lock{mRegisteredLock};

    if (mRegistered) {
        gAm.unregisterUidObserver(this);
        gAm.unlinkToDeath(this);
        mRegistered = false;
    }

    ALOGV("UidObserver: Unregistered with ActivityManager");
}

} // activitymanager
} // android

using namespace android;
using namespace activitymanager;

struct AActivityManager_UidImportanceListener : public UidObserver {
};

AActivityManager_UidImportanceListener* AActivityManager_addUidImportanceListener(
        AActivityManager_onUidImportance onUidImportance, int32_t importanceCutpoint, void* cookie) {
    sp<UidObserver> observer(new UidObserver(onUidImportance, importanceCutpoint, cookie));
    if (observer == nullptr || !observer->registerSelf()) {
        return nullptr;
    }
    observer->incStrong((void *)AActivityManager_addUidImportanceListener);
    return static_cast<AActivityManager_UidImportanceListener*>(observer.get());
}

void AActivityManager_removeUidImportanceListener(
        AActivityManager_UidImportanceListener* listener) {
    if (listener != nullptr) {
        UidObserver* observer = static_cast<UidObserver*>(listener);
        observer->unregisterSelf();
        observer->decStrong((void *)AActivityManager_addUidImportanceListener);
    }
}

bool AActivityManager_isUidActive(uid_t uid) {
    return gAm.isUidActive(uid, getTag());
}

int32_t AActivityManager_getUidImportance(uid_t uid) {
    return UidObserver::procStateToImportance(gAm.getUidProcessState(uid, getTag()));
}

