Skip to content

Commit

Permalink
[service] query pkg cpu usage
Browse files Browse the repository at this point in the history
  • Loading branch information
Tornaco committed Oct 28, 2022
1 parent 653f87a commit 65caee1
Show file tree
Hide file tree
Showing 9 changed files with 196 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import android.content.Intent;
import android.content.pm.UserInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;

Expand All @@ -16,6 +15,7 @@
import java.util.stream.Collectors;

import github.tornaco.android.thanos.core.app.start.StartRecord;
import github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats;
import github.tornaco.android.thanos.core.app.usage.ProcessCpuUsageStats;
import github.tornaco.android.thanos.core.os.ProcessName;
import github.tornaco.android.thanos.core.os.SwapInfo;
Expand Down Expand Up @@ -789,6 +789,11 @@ public float getTotalCpuPercent(boolean update) {
return server.getTotalCpuPercent(update);
}

@SneakyThrows
public List<PkgCpuUsageStats> getTopNCpuUsagePackages(int n, boolean update) {
return server.getTopNCpuUsagePackages(n, update);
}

@SneakyThrows
public SwapInfo getSwapInfo() {
return server.getSwapInfo();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,4 +233,6 @@ interface IActivityManager {
void setSmartStandByByPassIfHasVisibleWindowsEnabled(boolean enable);

float getTotalCpuPercent(boolean update);

List<PkgCpuUsageStats> getTopNCpuUsagePackages(int n, boolean update);
}
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,10 @@ public static class Default implements github.tornaco.android.thanos.core.app.IA
{
return 0.0f;
}
@Override public java.util.List<github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats> getTopNCpuUsagePackages(int n, boolean update) throws android.os.RemoteException
{
return null;
}
@Override
public android.os.IBinder asBinder() {
return null;
Expand Down Expand Up @@ -2040,6 +2044,18 @@ public static github.tornaco.android.thanos.core.app.IActivityManager asInterfac
reply.writeFloat(_result);
return true;
}
case TRANSACTION_getTopNCpuUsagePackages:
{
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
boolean _arg1;
_arg1 = (0!=data.readInt());
java.util.List<github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats> _result = this.getTopNCpuUsagePackages(_arg0, _arg1);
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
Expand Down Expand Up @@ -5012,6 +5028,28 @@ public java.lang.String getInterfaceDescriptor()
}
return _result;
}
@Override public java.util.List<github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats> getTopNCpuUsagePackages(int n, boolean update) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(n);
_data.writeInt(((update)?(1):(0)));
boolean _status = mRemote.transact(Stub.TRANSACTION_getTopNCpuUsagePackages, _data, _reply, 0);
if (!_status && getDefaultImpl() != null) {
return getDefaultImpl().getTopNCpuUsagePackages(n, update);
}
_reply.readException();
_result = _reply.createTypedArrayList(github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats.CREATOR);
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public static github.tornaco.android.thanos.core.app.IActivityManager sDefaultImpl;
}
static final int TRANSACTION_getCurrentFrontApp = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
Expand Down Expand Up @@ -5145,6 +5183,7 @@ public java.lang.String getInterfaceDescriptor()
static final int TRANSACTION_isSmartStandByByPassIfHasVisibleWindows = (android.os.IBinder.FIRST_CALL_TRANSACTION + 128);
static final int TRANSACTION_setSmartStandByByPassIfHasVisibleWindowsEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 129);
static final int TRANSACTION_getTotalCpuPercent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 130);
static final int TRANSACTION_getTopNCpuUsagePackages = (android.os.IBinder.FIRST_CALL_TRANSACTION + 131);
public static boolean setDefaultImpl(github.tornaco.android.thanos.core.app.IActivityManager impl) {
// Only one user of this interface can use this function
// at a time. This is a heuristic to detect if two different
Expand Down Expand Up @@ -5325,4 +5364,5 @@ public static github.tornaco.android.thanos.core.app.IActivityManager getDefault
public boolean isSmartStandByByPassIfHasVisibleWindows() throws android.os.RemoteException;
public void setSmartStandByByPassIfHasVisibleWindowsEnabled(boolean enable) throws android.os.RemoteException;
public float getTotalCpuPercent(boolean update) throws android.os.RemoteException;
public java.util.List<github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats> getTopNCpuUsagePackages(int n, boolean update) throws android.os.RemoteException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* (C) Copyright 2022 Thanox
*
* 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.
*
*/

package github.tornaco.android.thanos.core.app.usage;

import android.os.Parcel;
import android.os.Parcelable;

import github.tornaco.android.thanos.core.pm.Pkg;

public class PkgCpuUsageStats implements Parcelable {
public Pkg pkg;
public String cpuRatioString;

protected PkgCpuUsageStats(Parcel in) {
pkg = in.readParcelable(Pkg.class.getClassLoader());
cpuRatioString = in.readString();
}

public PkgCpuUsageStats(Pkg pkg, String cpuRatioString) {
this.pkg = pkg;
this.cpuRatioString = cpuRatioString;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(pkg, flags);
dest.writeString(cpuRatioString);
}

@Override
public int describeContents() {
return 0;
}

public static final Creator<PkgCpuUsageStats> CREATOR = new Creator<PkgCpuUsageStats>() {
@Override
public PkgCpuUsageStats createFromParcel(Parcel in) {
return new PkgCpuUsageStats(in);
}

@Override
public PkgCpuUsageStats[] newArray(int size) {
return new PkgCpuUsageStats[size];
}
};
}
1 change: 1 addition & 0 deletions android/android_sdk/thanos.aidl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ parcelable github.tornaco.android.thanos.core.app.ActivityAssistInfo;
parcelable github.tornaco.android.thanos.core.app.event.ThanosEvent;
parcelable github.tornaco.android.thanos.core.app.start.StartRecord;
parcelable github.tornaco.android.thanos.core.app.usage.ProcessCpuUsageStats;
parcelable github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats;
parcelable github.tornaco.android.thanos.core.pm.ParceledListSlice;
parcelable github.tornaco.android.thanos.core.process.ProcessRecord;
parcelable github.tornaco.android.thanos.core.pm.AppInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package github.tornaco.android.thanos.dashboard

import github.tornaco.android.thanos.core.app.usage.PkgCpuUsageStats
import github.tornaco.android.thanos.core.pm.AppInfo

data class StatusHeaderInfo(
val runningAppsCount: Int,
val memory: MemUsage,
Expand All @@ -37,6 +40,12 @@ data class MemUsage(
data class CpuUsage(
// 0-100
val totalPercent: Int = 1,
val topNPkgs: List<AppCpuUsage> = emptyList()
)

data class AppCpuUsage(
val appInfo: AppInfo,
val percent: String,
)

enum class MemType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.times
import github.tornaco.android.thanos.R
import github.tornaco.android.thanos.dashboard.AppCpuUsage
import github.tornaco.android.thanos.dashboard.MemType
import github.tornaco.android.thanos.dashboard.MemUsage
import github.tornaco.android.thanos.dashboard.StatusHeaderInfo
Expand Down Expand Up @@ -158,9 +159,30 @@ private fun CpuProgressBar(
}
)
}
MediumSpacer()
Column(verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally) {
headerInfo.cpu.topNPkgs.forEach {
AppCpuUsage(it)
}
}
}
}

@Composable
private fun AppCpuUsage(usage: AppCpuUsage) {
val onSurfaceColor = getColorAttribute(R.attr.colorOnSurface)
Row(horizontalArrangement = Arrangement.Start, verticalAlignment = Alignment.CenterVertically) {
AppIcon(modifier = Modifier.size(16.dp), usage.appInfo)
Text(
modifier = Modifier,
textAlign = TextAlign.Center,
text = "${usage.percent}%",
style = MaterialTheme.typography.bodySmall.copy(fontSize = 10.sp),
color = Color(onSurfaceColor)
)
}
}

@Composable
private fun MemProgressBar(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,24 +115,30 @@ class NavViewModel2 @Inject constructor(@ApplicationContext private val context:
}

fun loadHeaderStatus(showLoading: Boolean = true) {
if (thanox.isServiceInstalled) {
viewModelScope.launch {
if (showLoading) {
_state.value = _state.value.copy(isLoading = true)
withSubscriptionStatus(context) { isSubscribed: Boolean? ->
isSubscribed?.let {
if (it) {
if (thanox.isServiceInstalled) {
viewModelScope.launch {
if (showLoading) {
_state.value = _state.value.copy(isLoading = true)
}
val state: StatusHeaderInfo = getStatusHeaderInfo()
_state.value =
_state.value.copy(statusHeaderInfo = state, isLoading = false)
}
}
}
val state: StatusHeaderInfo = getStatusHeaderInfo()
_state.value = _state.value.copy(statusHeaderInfo = state, isLoading = false)
}
}
}

fun loadAppStatus() {
viewModelScope.launch {
val isPrivacyStatementAccepted = isPrivacyStatementAccepted()
_state.value = _state.value.copy(
showPrivacyStatement = !isPrivacyStatementAccepted,
showFirstRunTips = isPrivacyStatementAccepted
&& AppPreference.isFirstRun(context),
_state.value = _state.value.copy(showPrivacyStatement = !isPrivacyStatementAccepted,
showFirstRunTips = isPrivacyStatementAccepted && !thanox.isServiceInstalled && AppPreference.isFirstRun(
context),
patchSources = if (thanox.isServiceInstalled) thanox.patchingSource else emptyList())
}
}
Expand All @@ -149,56 +155,51 @@ class NavViewModel2 @Inject constructor(@ApplicationContext private val context:
var swapAvailableSizeString = ""
var swapUsedPercent = 0
var swapEnabled = false
var runningAppsCount = 0

// Only load for pro.
thanox.ifServiceInstalled { manager ->
runningAppsCount = manager.activityManager.runningAppsCount
val memoryInfo = manager.activityManager.memoryInfo
if (memoryInfo != null) {
memTotalSizeString = Formatter.formatFileSize(context, memoryInfo.totalMem)
memUsageSizeString = Formatter.formatFileSize(context,
memoryInfo.totalMem - memoryInfo.availMem)
memAvailableSizeString =
Formatter.formatFileSize(context, memoryInfo.availMem)
memUsedPercent =
(100 * ((memoryInfo.totalMem - memoryInfo.availMem).toFloat() / memoryInfo.totalMem.toFloat()

val runningAppsCount: Int = thanox.activityManager.runningAppsCount
val memoryInfo = thanox.activityManager.memoryInfo
if (memoryInfo != null) {
memTotalSizeString = Formatter.formatFileSize(context, memoryInfo.totalMem)
memUsageSizeString =
Formatter.formatFileSize(context, memoryInfo.totalMem - memoryInfo.availMem)
memAvailableSizeString = Formatter.formatFileSize(context, memoryInfo.availMem)
memUsedPercent =
(100 * ((memoryInfo.totalMem - memoryInfo.availMem).toFloat() / memoryInfo.totalMem.toFloat()
.coerceAtLeast(1f))).toInt()
}
val swapInfo = thanox.activityManager.swapInfo
if (swapInfo != null) {
swapEnabled = swapInfo.totalSwap > 0
if (swapEnabled) {
swapTotalSizeString = Formatter.formatFileSize(context, swapInfo.totalSwap)
swapUsageSizeString = Formatter.formatFileSize(context,
swapInfo.totalSwap - swapInfo.freeSwap)
swapAvailableSizeString =
Formatter.formatFileSize(context, swapInfo.freeSwap)
swapUsedPercent =
(100 * ((swapInfo.totalSwap - swapInfo.freeSwap).toFloat() / swapInfo.totalSwap.toFloat()
.coerceAtLeast(1f))).toInt()
}
val swapInfo = manager.activityManager.swapInfo
if (swapInfo != null) {
swapEnabled = swapInfo.totalSwap > 0
if (swapEnabled) {
swapTotalSizeString =
Formatter.formatFileSize(context, swapInfo.totalSwap)
swapUsageSizeString = Formatter.formatFileSize(context,
swapInfo.totalSwap - swapInfo.freeSwap)
swapAvailableSizeString =
Formatter.formatFileSize(context, swapInfo.freeSwap)
swapUsedPercent =
(100 * ((swapInfo.totalSwap - swapInfo.freeSwap).toFloat() / swapInfo.totalSwap.toFloat()
.coerceAtLeast(1f))).toInt()
}
}
}

val cpuPercent =
(thanox.activityManager.getTotalCpuPercent(true)).coerceAtLeast(1f).toInt()

StatusHeaderInfo(runningAppsCount,
MemUsage(MemType.MEMORY,
memTotalSizeString,
memUsedPercent,
memUsageSizeString,
memAvailableSizeString,
true),
MemUsage(MemType.SWAP,
swapTotalSizeString,
swapUsedPercent,
swapUsageSizeString,
swapAvailableSizeString,
swapEnabled),
CpuUsage(cpuPercent))
StatusHeaderInfo(runningAppsCount = runningAppsCount,
memory = MemUsage(memType = MemType.MEMORY,
memTotalSizeString = memTotalSizeString,
memUsagePercent = memUsedPercent,
memUsageSizeString = memUsageSizeString,
memAvailableSizeString = memAvailableSizeString,
isEnabled = true),
swap = MemUsage(memType = MemType.SWAP,
memTotalSizeString = swapTotalSizeString,
memUsagePercent = swapUsedPercent,
memUsageSizeString = swapUsageSizeString,
memAvailableSizeString = swapAvailableSizeString,
isEnabled = swapEnabled),
cpu = CpuUsage(totalPercent = cpuPercent))

}.getOrElse {
XLog.e("getStatusHeaderInfo error", it)
defaultStatusHeaderInfo
Expand Down
2 changes: 1 addition & 1 deletion android/internal/Thanox-Internal

0 comments on commit 65caee1

Please sign in to comment.