Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b67c3b1f authored by Yu-Ting Tseng's avatar Yu-Ting Tseng
Browse files

Add NDK system APIs for ActivityManager process observer and running app process info.

Bug: 440134516
Test: atest AActivityManagerTest
Flag: NONE NDK APIs. Will flag guard the callsite
Change-Id: I59f552d6b23ef3a601346c4bafd214ea5af60360
parent 636b080f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -48,12 +48,12 @@ parcelable RunningAppProcessInfo {
    /**
     * All packages that have been loaded into the process.
     */
    @utf8InCpp String[] pkgList;
    @nullable @utf8InCpp String[] pkgList;

    /**
     * Additional packages loaded into the process as dependency.
     */
    @utf8InCpp String[] pkgDeps;
    @nullable @utf8InCpp String[] pkgDeps;

    /**
     * Constant for {@link #flags}: this is an app that is unable to
+250 −0
Original line number Diff line number Diff line
@@ -19,9 +19,15 @@
#include <utils/Log.h>

#include <android/activity_manager.h>
#include <android/app/BnProcessObserver.h>
#include <android/app/IProcessObserver.h>
#include <android/binder_status.h>
#include <android/binder_auto_utils.h>
#include <android/app/RunningAppProcessInfo.h>
#include <binder/ActivityManager.h>

#include <mutex>
#include <vector>

namespace android {
namespace activitymanager {
@@ -193,6 +199,73 @@ void UidObserver::unregisterSelf() {
    ALOGV("UidObserver: Unregistered with ActivityManager");
}

class ProcessObserver : public app::BnProcessObserver {
public:
    explicit ProcessObserver(void* cookie)
          : mOnProcessStarted(nullptr),
            mOnForegroundActivitiesChanged(nullptr),
            mOnForegroundServicesChanged(nullptr),
            mOnProcessDied(nullptr),
            mCookie(cookie) {}

    void setOnProcessStarted(AActivityManager_onProcessStarted cb) { mOnProcessStarted = cb; }
    void setOnForegroundActivitiesChanged(AActivityManager_onForegroundActivitiesChanged cb) {
        mOnForegroundActivitiesChanged = cb;
    }
    void setOnForegroundServicesChanged(AActivityManager_onForegroundServicesChanged cb) {
        mOnForegroundServicesChanged = cb;
    }
    void setOnProcessDied(AActivityManager_onProcessDied cb) { mOnProcessDied = cb; }

    bool hasCallbacks() const {
        return mOnProcessStarted || mOnForegroundActivitiesChanged ||
               mOnForegroundServicesChanged || mOnProcessDied;
    }

    binder::Status onProcessStarted(int pid, int processUid, int packageUid,
                                    const std::string& packageName,
                                    const std::string& processName) override {
        if (mOnProcessStarted) {
            mOnProcessStarted(pid, processUid, packageUid, packageName.c_str(),
                              processName.c_str(), mCookie);
        }
        return binder::Status::ok();
    }

    binder::Status onForegroundActivitiesChanged(int pid, int uid,
                                                 bool foregroundActivities) override {
        if (mOnForegroundActivitiesChanged) {
            const AActivityManager_ForegroundActivitiesState state =
                    foregroundActivities
                            ? AACTIVITYMANAGER_HAS_FOREGROUND_ACTIVITIES
                            : AACTIVITYMANAGER_NO_FOREGROUND_ACTIVITIES;
            mOnForegroundActivitiesChanged(pid, uid, state, mCookie);
        }
        return binder::Status::ok();
    }

    binder::Status onForegroundServicesChanged(int pid, int uid, int32_t serviceTypes) override {
        if (mOnForegroundServicesChanged) {
            mOnForegroundServicesChanged(pid, uid, serviceTypes, mCookie);
        }
        return binder::Status::ok();
    }

    binder::Status onProcessDied(int pid, int uid) override {
        if (mOnProcessDied) {
            mOnProcessDied(pid, uid, mCookie);
        }
        return binder::Status::ok();
    }

private:
    AActivityManager_onProcessStarted mOnProcessStarted;
    AActivityManager_onForegroundActivitiesChanged mOnForegroundActivitiesChanged;
    AActivityManager_onForegroundServicesChanged mOnForegroundServicesChanged;
    AActivityManager_onProcessDied mOnProcessDied;
    void* mCookie;
};

} // activitymanager
} // android

@@ -221,6 +294,163 @@ void AActivityManager_removeUidImportanceListener(
    }
}

struct AActivityManager_ProcessObserver {
    sp<ProcessObserver> observer;
    bool registered = false;
};

AActivityManager_ProcessObserver* AActivityManager_createProcessObserver(void* cookie) {
    auto handle = new AActivityManager_ProcessObserver();
    if (!handle) {
        return nullptr;
    }
    handle->observer = sp<ProcessObserver>::make(cookie);
    if (handle->observer == nullptr) {
        delete handle;
        return nullptr;
    }
    return handle;
}

void AActivityManager_destroyProcessObserver(AActivityManager_ProcessObserver* observer) {
    if (observer == nullptr) {
        return;
    }
    if (observer->registered) {
        gAm.unregisterProcessObserver(observer->observer);
    }
    delete observer;
}

void AActivityManager_ProcessObserver_setOnProcessStarted(
        AActivityManager_ProcessObserver* observer, AActivityManager_onProcessStarted callback) {
    if (observer && observer->observer) {
        observer->observer->setOnProcessStarted(callback);
    }
}

void AActivityManager_ProcessObserver_setOnForegroundActivitiesChanged(
        AActivityManager_ProcessObserver* observer,
        AActivityManager_onForegroundActivitiesChanged callback) {
    if (observer && observer->observer) {
        observer->observer->setOnForegroundActivitiesChanged(callback);
    }
}

void AActivityManager_ProcessObserver_setOnForegroundServicesChanged(
        AActivityManager_ProcessObserver* observer,
        AActivityManager_onForegroundServicesChanged callback) {
    if (observer && observer->observer) {
        observer->observer->setOnForegroundServicesChanged(callback);
    }
}

void AActivityManager_ProcessObserver_setOnProcessDied(
        AActivityManager_ProcessObserver* observer, AActivityManager_onProcessDied callback) {
    if (observer && observer->observer) {
        observer->observer->setOnProcessDied(callback);
    }
}

binder_status_t AActivityManager_registerProcessObserver(
        AActivityManager_ProcessObserver* observer) {
    if (observer == nullptr || observer->observer == nullptr) {
        return STATUS_BAD_VALUE;
    }
    if (observer->registered) {
        return STATUS_INVALID_OPERATION;
    }
    if (!observer->observer->hasCallbacks()) {
        return STATUS_BAD_VALUE;
    }

    status_t status = gAm.registerProcessObserver(observer->observer);
    if (status != OK) {
        ALOGE("ProcessObserver: Failed to register with ActivityManager (err %d)", status);
        return ndk::ScopedAStatus::fromStatus(status).getStatus();
    }

    observer->registered = true;
    return STATUS_OK;
}

void AActivityManager_unregisterProcessObserver(AActivityManager_ProcessObserver* observer) {
    if (observer == nullptr || !observer->registered) {
        return;
    }
    gAm.unregisterProcessObserver(observer->observer);
    observer->registered = false;
}

struct ARunningAppProcessInfo {
    pid_t pid;
    uid_t uid;
    std::string processName;
    std::vector<std::string> pkgList;
    int32_t importance;
    std::vector<const char*> pkgListCStr;
};

struct ARunningAppProcessInfoList {
    std::vector<ARunningAppProcessInfo> list;
};

binder_status_t AActivityManager_getRunningAppProcesses(
        ARunningAppProcessInfoList** outProcessInfoList) {
    if (outProcessInfoList == nullptr) {
        return STATUS_BAD_VALUE;
    }

    std::vector<app::RunningAppProcessInfo> processes;
    status_t status = gAm.getRunningAppProcesses(&processes);
    if (status != OK) {
        return ndk::ScopedAStatus::fromStatus(status).getStatus();
    }

    auto* list = new ARunningAppProcessInfoList();
    list->list.reserve(processes.size());

    for (const auto& p : processes) {
        ARunningAppProcessInfo info;
        info.pid = p.pid;
        info.uid = p.uid;
        info.processName = p.processName;
        if (p.pkgList.has_value()) {
            for (const auto& pkg : p.pkgList.value()) {
                if (pkg.has_value()) {
                    info.pkgList.push_back(pkg.value());
                }
            }
        }
        info.importance = p.importance;

        info.pkgListCStr.reserve(info.pkgList.size());
        for (const auto& pkg : info.pkgList) {
            info.pkgListCStr.push_back(pkg.c_str());
        }
        list->list.emplace_back(std::move(info));
    }

    *outProcessInfoList = list;
    return STATUS_OK;
}

void AActivityManager_RunningAppProcessInfoList_destroy(const ARunningAppProcessInfoList* list) {
    delete list;
}

size_t AActivityManager_RunningAppProcessInfoList_getSize(const ARunningAppProcessInfoList* list) {
    return list->list.size();
}

const ARunningAppProcessInfo* AActivityManager_RunningAppProcessInfoList_get(
        const ARunningAppProcessInfoList* list, size_t index) {
    if (index >= list->list.size()) {
        return nullptr;
    }
    return &list->list[index];
}

bool AActivityManager_isUidActive(uid_t uid) {
    return gAm.isUidActive(uid, getTag());
}
@@ -229,3 +459,23 @@ int32_t AActivityManager_getUidImportance(uid_t uid) {
    return UidObserver::procStateToImportance(gAm.getUidProcessState(uid, getTag()));
}

pid_t ARunningAppProcessInfo_getPid(const ARunningAppProcessInfo* info) { return info->pid; }

uid_t ARunningAppProcessInfo_getUid(const ARunningAppProcessInfo* info) { return info->uid; }

const char* ARunningAppProcessInfo_getProcessName(const ARunningAppProcessInfo* info) {
    return info->processName.c_str();
}

const char* const* ARunningAppProcessInfo_getPackageList(const ARunningAppProcessInfo* info,
                                                         size_t* outNumPackages) {
    *outNumPackages = info->pkgListCStr.size();
    if (info->pkgListCStr.empty()) {
        return nullptr;
    }
    return info->pkgListCStr.data();
}

int32_t ARunningAppProcessInfo_getImportance(const ARunningAppProcessInfo* info) {
    return info->importance;
}
+257 −5
Original line number Diff line number Diff line
@@ -19,12 +19,22 @@

#include <sys/cdefs.h>
#include <sys/types.h>
#include <android/binder_status.h>

__BEGIN_DECLS

struct AActivityManager_UidImportanceListener;
typedef struct AActivityManager_UidImportanceListener AActivityManager_UidImportanceListener;

struct AActivityManager_ProcessObserver;
typedef struct AActivityManager_ProcessObserver AActivityManager_ProcessObserver;

struct ARunningAppProcessInfo;
typedef struct ARunningAppProcessInfo ARunningAppProcessInfo;

struct ARunningAppProcessInfoList;
typedef struct ARunningAppProcessInfoList ARunningAppProcessInfoList;

/**
 * Callback interface when Uid Importance has changed for a uid.
 *
@@ -37,7 +47,8 @@ typedef struct AActivityManager_UidImportanceListener AActivityManager_UidImport
 *
 * Introduced in API 31.
 */
typedef void (*AActivityManager_onUidImportance)(uid_t uid, int32_t uidImportance, void* cookie);
typedef void (*AActivityManager_onUidImportance)(uid_t uid, int32_t uidImportance,
                                                 void* _Nullable cookie);

/**
 * ActivityManager Uid Importance constants.
@@ -133,10 +144,10 @@ enum {
 * upon failure. Upon success, the returned AActivityManager_UidImportanceListener pointer
 * must be removed and released through AActivityManager_removeUidImportanceListener.
 */
AActivityManager_UidImportanceListener* AActivityManager_addUidImportanceListener(
        AActivityManager_onUidImportance onUidImportance,
AActivityManager_UidImportanceListener* _Nullable AActivityManager_addUidImportanceListener(
        AActivityManager_onUidImportance _Nullable onUidImportance,
        int32_t importanceCutpoint,
        void* cookie) __INTRODUCED_IN(31);
        void* _Nullable cookie) __INTRODUCED_IN(31);

/**
 * Removes a UidImportanceListener that was added with AActivityManager_addUidImportanceListener.
@@ -146,7 +157,7 @@ AActivityManager_UidImportanceListener* AActivityManager_addUidImportanceListene
 * @param listener the UidImportanceListener to be removed.
 */
void AActivityManager_removeUidImportanceListener(
        AActivityManager_UidImportanceListener* listener) __INTRODUCED_IN(31);
        AActivityManager_UidImportanceListener* _Nullable listener) __INTRODUCED_IN(31);

/**
 * Queries if a uid is currently active.
@@ -167,6 +178,247 @@ bool AActivityManager_isUidActive(uid_t uid) __INTRODUCED_IN(31);
 */
int32_t AActivityManager_getUidImportance(uid_t uid) __INTRODUCED_IN(31);

/**
 * The state of foreground activities in a process.
 */
typedef enum AActivityManager_ForegroundActivitiesState : int32_t {
    /**
     * The process has no foreground activities.
     *
     * Introduced in API 37.
     */
    AACTIVITYMANAGER_NO_FOREGROUND_ACTIVITIES = 0,
    /**
     * The process has one or more foreground activities.
     *
     * Introduced in API 37.
     */
    AACTIVITYMANAGER_HAS_FOREGROUND_ACTIVITIES = 1,
} AActivityManager_ForegroundActivitiesState;

/**
 * Callback interface for being notified when a process is started.
 *
 * @param pid The pid of the process.
 * @param processUid The UID associated with the process.
 * @param packageUid The UID associated with the package.
 * @param packageName The name of the package.
 * @param processName The name of the process.
 * @param cookie The cookie provided when the listener was registered.
 */
typedef void (*AActivityManager_onProcessStarted)(pid_t pid, uid_t processUid, uid_t packageUid,
                                                  const char* _Nonnull packageName,
                                                  const char* _Nonnull processName,
                                                  void* _Nonnull cookie);

/**
 * Callback interface for being notified when the foreground activities of a process change.
 *
 * @param pid The pid of the process.
 * @param uid The UID of the process.
 * @param state The foreground activities state.
 * @param cookie The cookie provided when the listener was registered.
 */
typedef void (*AActivityManager_onForegroundActivitiesChanged)(
        pid_t pid, uid_t uid, AActivityManager_ForegroundActivitiesState state,
        void* _Nonnull cookie);

/**
 * Callback interface for being notified when the foreground services of a process change.
 *
 * @param pid The pid of the process.
 * @param uid The UID of the process.
 * @param serviceTypes The types of foreground services.
 * @param cookie The cookie provided when the listener was registered.
 */
typedef void (*AActivityManager_onForegroundServicesChanged)(pid_t pid, uid_t uid,
                                                             int32_t serviceTypes,
                                                             void* _Nonnull cookie);

/**
 * Callback interface for being notified when a process dies.
 *
 * @param pid The pid of the process.
 * @param uid The UID of the process.
 * @param cookie The cookie provided when the listener was registered.
 */
typedef void (*AActivityManager_onProcessDied)(pid_t pid, uid_t uid, void* _Nonnull cookie);

/**
 * Creates a process observer.
 *
 * The returned observer is not active until registered with
 * AActivityManager_registerProcessObserver().
 *
 * The returned observer must be destroyed with AActivityManager_destroyProcessObserver().
 *
 * @param cookie A cookie that will be passed back to the listener callbacks.
 * @return An opaque pointer of AActivityManager_ProcessObserver, or nullptr upon failure.
 */
AActivityManager_ProcessObserver* _Nullable AActivityManager_createProcessObserver(
        void* _Nonnull cookie) __INTRODUCED_IN(37);

/**
 * Destroys a process observer.
 *
 * If the observer is registered, it will be unregistered first.
 *
 * @param observer The observer to destroy.
 */
void AActivityManager_destroyProcessObserver(
        AActivityManager_ProcessObserver* _Nonnull observer) __INTRODUCED_IN(37);

/**
 * Sets the callback for when a process starts. Must be called before registering the observer.
 * @param observer The process observer.
 * @param callback The callback to set. Can be null to unset.
 */
void AActivityManager_ProcessObserver_setOnProcessStarted(
        AActivityManager_ProcessObserver* _Nonnull observer,
        AActivityManager_onProcessStarted _Nullable callback) __INTRODUCED_IN(37);

/**
 * Sets the callback for when foreground activities change. Must be called before registering the
 * observer.
 * @param observer The process observer.
 * @param callback The callback to set. Can be null to unset.
 */
void AActivityManager_ProcessObserver_setOnForegroundActivitiesChanged(
        AActivityManager_ProcessObserver* _Nonnull observer,
        AActivityManager_onForegroundActivitiesChanged _Nullable callback) __INTRODUCED_IN(37);

/**
 * Sets the callback for when foreground services change. Must be called before registering the
 * observer.
 * @param observer The process observer.
 * @param callback The callback to set. Can be null to unset.
 */
void AActivityManager_ProcessObserver_setOnForegroundServicesChanged(
        AActivityManager_ProcessObserver* _Nonnull observer,
        AActivityManager_onForegroundServicesChanged _Nullable callback) __INTRODUCED_IN(37);

/**
 * Sets the callback for when a process dies. Must be called before registering the observer.
 * @param observer The process observer.
 * @param callback The callback to set. Can be null to unset.
 */
void AActivityManager_ProcessObserver_setOnProcessDied(
        AActivityManager_ProcessObserver* _Nonnull observer,
        AActivityManager_onProcessDied _Nullable callback) __INTRODUCED_IN(37);

/**
 * Registers a process observer to receive callbacks about process state changes.
 *
 * At least one callback must be set on the observer.
 *
 * This API requires android.Manifest.permission.PACKAGE_USAGE_STATS permission.
 *
 * @param observer The observer to register.
 * @return STATUS_OK on success, or a negative error code on failure.
 */
binder_status_t AActivityManager_registerProcessObserver(
        AActivityManager_ProcessObserver* _Nonnull observer) __INTRODUCED_IN(37);

/**
 * Unregisters a process observer that was registered with AActivityManager_registerProcessObserver.
 *
 * When this returns, it's guaranteed the listener callbacks will no longer be invoked.
 *
 * @param observer The AActivityManager_ProcessObserver to be removed.
 */
void AActivityManager_unregisterProcessObserver(
        AActivityManager_ProcessObserver* _Nonnull observer) __INTRODUCED_IN(37);

/**
 * Gets a list of running application processes.
 *
 * This API requires android.Manifest.permission.PACKAGE_USAGE_STATS permission.
 *
 * On success, `outProcessInfoList` will be populated with a list of running processes.
 * The caller owns this list and must release it by calling
 * AActivityManager_RunningAppProcessInfoList_destroy().
 *
 * @param outProcessInfoList A pointer that will be set to the list of running processes.
 * @return STATUS_OK on success, or a negative error code on failure.
 */
binder_status_t AActivityManager_getRunningAppProcesses(
        ARunningAppProcessInfoList* _Nullable* _Nonnull outProcessInfoList) __INTRODUCED_IN(37);

/**
 * Destroys a list of running app process info.
 *
 * @param list The list to destroy, obtained from AActivityManager_getRunningAppProcesses.
 */
void AActivityManager_RunningAppProcessInfoList_destroy(
        const ARunningAppProcessInfoList* _Nullable list) __INTRODUCED_IN(37);

/**
 * Gets the number of entries in the list.
 *
 * @param list The list.
 * @return The number of entries.
 */
size_t AActivityManager_RunningAppProcessInfoList_getSize(
        const ARunningAppProcessInfoList* _Nonnull list) __INTRODUCED_IN(37);

/**
 * Gets an entry from the list.
 *
 * The returned pointer is valid only for the lifetime of the list. Do not free it.
 *
 * @param list The list.
 * @param index The index of the entry to get.
 * @return The entry, or nullptr if the index is out of bounds.
 */
const ARunningAppProcessInfo* _Nullable AActivityManager_RunningAppProcessInfoList_get(
        const ARunningAppProcessInfoList* _Nonnull list, size_t index) __INTRODUCED_IN(37);

/**
 * Gets the pid of the process.
 * @param info The process info object from an ARunningAppProcessInfoList.
 * @return The process ID.
 */
pid_t ARunningAppProcessInfo_getPid(const ARunningAppProcessInfo* _Nonnull info)
        __INTRODUCED_IN(37);

/**
 * Gets the uid of the process.
 * @param info The process info object from an ARunningAppProcessInfoList.
 * @return The user ID.
 */
uid_t ARunningAppProcessInfo_getUid(const ARunningAppProcessInfo* _Nonnull info)
        __INTRODUCED_IN(37);

/**
 * Gets the name of the process.
 * The returned string is valid for the lifetime of the ARunningAppProcessInfo object.
 * @param info The process info object from an ARunningAppProcessInfoList.
 * @return The process name in UTF-8.
 */
const char* _Nonnull ARunningAppProcessInfo_getProcessName(
        const ARunningAppProcessInfo* _Nonnull info) __INTRODUCED_IN(37);

/**
 * Gets the list of packages in the process.
 * The returned array and its strings are valid for the lifetime of the ARunningAppProcessInfo
 * object.
 * @param info The process info object from an ARunningAppProcessInfoList.
 * @param outNumPackages Pointer to a size_t to store the number of packages.
 * @return An array of package names in UTF-8. The array is owned by the ARunningAppProcessInfo
 * object. Returns nullptr if there are no packages.
 */
const char* _Nonnull const* _Nullable ARunningAppProcessInfo_getPackageList(
        const ARunningAppProcessInfo* _Nonnull info, size_t* _Nonnull outNumPackages)
        __INTRODUCED_IN(37);

/**
 * Gets the importance of the process.
 * @param info The process info object from an ARunningAppProcessInfoList.
 * @return The importance level. See AACTIVITYMANAGER_IMPORTANCE_* constants.
 */
int32_t ARunningAppProcessInfo_getImportance(const ARunningAppProcessInfo* _Nonnull info)
        __INTRODUCED_IN(37);

__END_DECLS

#endif  // __AACTIVITYMANAGER_H__
+17 −0
Original line number Diff line number Diff line
@@ -4,6 +4,23 @@ LIBANDROID {
    AActivityManager_removeUidImportanceListener; # systemapi introduced=31
    AActivityManager_isUidActive; # systemapi introduced=31
    AActivityManager_getUidImportance; # systemapi introduced=31
    AActivityManager_createProcessObserver; # systemapi introduced=37
    AActivityManager_destroyProcessObserver; # systemapi introduced=37
    AActivityManager_ProcessObserver_setOnProcessStarted; # systemapi introduced=37
    AActivityManager_ProcessObserver_setOnForegroundActivitiesChanged; # systemapi introduced=37
    AActivityManager_ProcessObserver_setOnForegroundServicesChanged; # systemapi introduced=37
    AActivityManager_ProcessObserver_setOnProcessDied; # systemapi introduced=37
    AActivityManager_registerProcessObserver; # systemapi introduced=37
    AActivityManager_unregisterProcessObserver; # systemapi introduced=37
    AActivityManager_getRunningAppProcesses; # systemapi introduced=37
    AActivityManager_RunningAppProcessInfoList_destroy; # systemapi introduced=37
    AActivityManager_RunningAppProcessInfoList_getSize; # systemapi introduced=37
    AActivityManager_RunningAppProcessInfoList_get; # systemapi introduced=37
    ARunningAppProcessInfo_getPid; # systemapi introduced=37
    ARunningAppProcessInfo_getUid; # systemapi introduced=37
    ARunningAppProcessInfo_getProcessName; # systemapi introduced=37
    ARunningAppProcessInfo_getPackageList; # systemapi introduced=37
    ARunningAppProcessInfo_getImportance; # systemapi introduced=37
    ADynamicInstrumentationManager_TargetProcess_create; # systemapi
    ADynamicInstrumentationManager_TargetProcess_destroy; # systemapi
    ADynamicInstrumentationManager_MethodDescriptor_create; # systemapi
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ cc_test {
        "libutils",
        "libandroid",
        "libbinder",
        "libbinder_ndk",
    ],

    static_libs: [