diff --git a/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/ActivityManager.java b/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/ActivityManager.java index 6cee5ec49..acbc7c5ee 100644 --- a/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/ActivityManager.java +++ b/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/ActivityManager.java @@ -10,6 +10,7 @@ import java.util.List; import github.tornaco.android.thanos.core.app.start.StartRecord; +import github.tornaco.android.thanos.core.pm.Pkg; import github.tornaco.android.thanos.core.process.ProcessRecord; import lombok.AllArgsConstructor; import lombok.SneakyThrows; @@ -96,8 +97,8 @@ public int getRunningAppsCount() { } @SneakyThrows - public ProcessRecord[] getRunningAppProcessForPackage(String pkgName) { - return server.getRunningAppProcessForPackage(pkgName); + public ProcessRecord[] getRunningAppProcessForPackage(Pkg pkg) { + return server.getRunningAppProcessForPackage(pkg); } @SneakyThrows @@ -448,7 +449,7 @@ public void stopService(Intent intent) { @SneakyThrows public void killBackgroundProcesses(String packageName) { - server.killBackgroundProcesses(packageName); + server.killBackgroundProcesses(Pkg.systemUserPkg(packageName)); } @SneakyThrows @@ -511,6 +512,47 @@ public boolean checkGetContentProvider(String callerPkg, String name) { return server.checkGetContentProvider(callerPkg, name); } + // ****************************************************************** + // CAF API + // https://source.android.com/devices/tech/perf/cached-apps-freezer + // + // ****************************************************************** + + @SneakyThrows + public boolean isCachedAppsFreezerSupported() { + return server.isCachedAppsFreezerSupported(); + } + + @SneakyThrows + public void freezeApp(String pkgName) { + server.freezeApp(Pkg.systemUserPkg(pkgName)); + } + + @SneakyThrows + public void freezeApp(Pkg pkg) { + server.freezeApp(pkg); + } + + @SneakyThrows + public void freezeAppProcess(long pid) { + server.freezeAppProcess(pid); + } + + @SneakyThrows + public void unfreezeApp(Pkg pkg) { + server.unfreezeApp(pkg); + } + + @SneakyThrows + public void unfreezeApp(String pkgName) { + server.unfreezeApp(Pkg.systemUserPkg(pkgName)); + } + + @SneakyThrows + public void unfreezeAppProcess(long pid) { + server.unfreezeAppProcess(pid); + } + public IBinder asBinder() { return server.asBinder(); } diff --git a/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.aidl b/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.aidl index 959c87198..5a5e201c7 100644 --- a/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.aidl +++ b/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.aidl @@ -32,7 +32,7 @@ interface IActivityManager { int getRunningAppsCount(); - ProcessRecord[] getRunningAppProcessForPackage(String pkgName); + ProcessRecord[] getRunningAppProcessForPackage(in Pkg pkg); boolean isPackageRunning(String pkgName); List getStartRecordsByPackageName(String pkgName); @@ -131,7 +131,7 @@ interface IActivityManager { UserInfo getUserInfo(int userHandle); void stopService(in Intent intent); - void killBackgroundProcesses(String packageName); + void killBackgroundProcesses(in Pkg pkg); boolean isSmartStandByStopServiceEnabled(); void setSmartStandByStopServiceEnabled(boolean enable); @@ -167,4 +167,15 @@ interface IActivityManager { boolean checkGetContentProvider(String callerPkg, String name); List getAllStartRecordsForPackageSetWithRes(String pkgSetId, boolean allowed, boolean blocked); + + // ****************************************************************** + // CAF API + // https://source.android.com/devices/tech/perf/cached-apps-freezer + // + // ****************************************************************** + boolean isCachedAppsFreezerSupported(); + void freezeApp(in Pkg pkg); + void unfreezeApp(in Pkg pkg); + void freezeAppProcess(long pid); + void unfreezeAppProcess(long pid); } \ No newline at end of file diff --git a/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.java b/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.java index 536bbf0fb..b68220eb9 100644 --- a/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.java +++ b/android/android_framework/base/src/main/java/github/tornaco/android/thanos/core/app/IActivityManager.java @@ -64,7 +64,7 @@ public static class Default implements github.tornaco.android.thanos.core.app.IA { return 0; } - @Override public github.tornaco.android.thanos.core.process.ProcessRecord[] getRunningAppProcessForPackage(java.lang.String pkgName) throws android.os.RemoteException + @Override public github.tornaco.android.thanos.core.process.ProcessRecord[] getRunningAppProcessForPackage(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException { return null; } @@ -300,7 +300,7 @@ public static class Default implements github.tornaco.android.thanos.core.app.IA @Override public void stopService(android.content.Intent intent) throws android.os.RemoteException { } - @Override public void killBackgroundProcesses(java.lang.String packageName) throws android.os.RemoteException + @Override public void killBackgroundProcesses(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException { } @Override public boolean isSmartStandByStopServiceEnabled() throws android.os.RemoteException @@ -383,6 +383,28 @@ public static class Default implements github.tornaco.android.thanos.core.app.IA { return null; } + // ****************************************************************** + // CAF API + // https://source.android.com/devices/tech/perf/cached-apps-freezer + // + // ****************************************************************** + + @Override public boolean isCachedAppsFreezerSupported() throws android.os.RemoteException + { + return false; + } + @Override public void freezeApp(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException + { + } + @Override public void unfreezeApp(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException + { + } + @Override public void freezeAppProcess(long pid) throws android.os.RemoteException + { + } + @Override public void unfreezeAppProcess(long pid) throws android.os.RemoteException + { + } @Override public android.os.IBinder asBinder() { return null; @@ -615,8 +637,13 @@ public static github.tornaco.android.thanos.core.app.IActivityManager asInterfac case TRANSACTION_getRunningAppProcessForPackage: { data.enforceInterface(descriptor); - java.lang.String _arg0; - _arg0 = data.readString(); + github.tornaco.android.thanos.core.pm.Pkg _arg0; + if ((0!=data.readInt())) { + _arg0 = github.tornaco.android.thanos.core.pm.Pkg.CREATOR.createFromParcel(data); + } + else { + _arg0 = null; + } github.tornaco.android.thanos.core.process.ProcessRecord[] _result = this.getRunningAppProcessForPackage(_arg0); reply.writeNoException(); reply.writeTypedArray(_result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); @@ -1216,8 +1243,13 @@ public static github.tornaco.android.thanos.core.app.IActivityManager asInterfac case TRANSACTION_killBackgroundProcesses: { data.enforceInterface(descriptor); - java.lang.String _arg0; - _arg0 = data.readString(); + github.tornaco.android.thanos.core.pm.Pkg _arg0; + if ((0!=data.readInt())) { + _arg0 = github.tornaco.android.thanos.core.pm.Pkg.CREATOR.createFromParcel(data); + } + else { + _arg0 = null; + } this.killBackgroundProcesses(_arg0); reply.writeNoException(); return true; @@ -1428,6 +1460,60 @@ public static github.tornaco.android.thanos.core.app.IActivityManager asInterfac reply.writeTypedList(_result); return true; } + case TRANSACTION_isCachedAppsFreezerSupported: + { + data.enforceInterface(descriptor); + boolean _result = this.isCachedAppsFreezerSupported(); + reply.writeNoException(); + reply.writeInt(((_result)?(1):(0))); + return true; + } + case TRANSACTION_freezeApp: + { + data.enforceInterface(descriptor); + github.tornaco.android.thanos.core.pm.Pkg _arg0; + if ((0!=data.readInt())) { + _arg0 = github.tornaco.android.thanos.core.pm.Pkg.CREATOR.createFromParcel(data); + } + else { + _arg0 = null; + } + this.freezeApp(_arg0); + reply.writeNoException(); + return true; + } + case TRANSACTION_unfreezeApp: + { + data.enforceInterface(descriptor); + github.tornaco.android.thanos.core.pm.Pkg _arg0; + if ((0!=data.readInt())) { + _arg0 = github.tornaco.android.thanos.core.pm.Pkg.CREATOR.createFromParcel(data); + } + else { + _arg0 = null; + } + this.unfreezeApp(_arg0); + reply.writeNoException(); + return true; + } + case TRANSACTION_freezeAppProcess: + { + data.enforceInterface(descriptor); + long _arg0; + _arg0 = data.readLong(); + this.freezeAppProcess(_arg0); + reply.writeNoException(); + return true; + } + case TRANSACTION_unfreezeAppProcess: + { + data.enforceInterface(descriptor); + long _arg0; + _arg0 = data.readLong(); + this.unfreezeAppProcess(_arg0); + reply.writeNoException(); + return true; + } default: { return super.onTransact(code, data, reply, flags); @@ -1802,17 +1888,23 @@ public java.lang.String getInterfaceDescriptor() } return _result; } - @Override public github.tornaco.android.thanos.core.process.ProcessRecord[] getRunningAppProcessForPackage(java.lang.String pkgName) throws android.os.RemoteException + @Override public github.tornaco.android.thanos.core.process.ProcessRecord[] getRunningAppProcessForPackage(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); github.tornaco.android.thanos.core.process.ProcessRecord[] _result; try { _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(pkgName); + if ((pkg!=null)) { + _data.writeInt(1); + pkg.writeToParcel(_data, 0); + } + else { + _data.writeInt(0); + } boolean _status = mRemote.transact(Stub.TRANSACTION_getRunningAppProcessForPackage, _data, _reply, 0); if (!_status && getDefaultImpl() != null) { - return getDefaultImpl().getRunningAppProcessForPackage(pkgName); + return getDefaultImpl().getRunningAppProcessForPackage(pkg); } _reply.readException(); _result = _reply.createTypedArray(github.tornaco.android.thanos.core.process.ProcessRecord.CREATOR); @@ -3083,16 +3175,22 @@ public java.lang.String getInterfaceDescriptor() _data.recycle(); } } - @Override public void killBackgroundProcesses(java.lang.String packageName) throws android.os.RemoteException + @Override public void killBackgroundProcesses(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); - _data.writeString(packageName); + if ((pkg!=null)) { + _data.writeInt(1); + pkg.writeToParcel(_data, 0); + } + else { + _data.writeInt(0); + } boolean _status = mRemote.transact(Stub.TRANSACTION_killBackgroundProcesses, _data, _reply, 0); if (!_status && getDefaultImpl() != null) { - getDefaultImpl().killBackgroundProcesses(packageName); + getDefaultImpl().killBackgroundProcesses(pkg); return; } _reply.readException(); @@ -3545,6 +3643,120 @@ public java.lang.String getInterfaceDescriptor() } return _result; } + // ****************************************************************** + // CAF API + // https://source.android.com/devices/tech/perf/cached-apps-freezer + // + // ****************************************************************** + + @Override public boolean isCachedAppsFreezerSupported() throws android.os.RemoteException + { + android.os.Parcel _data = android.os.Parcel.obtain(); + android.os.Parcel _reply = android.os.Parcel.obtain(); + boolean _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + boolean _status = mRemote.transact(Stub.TRANSACTION_isCachedAppsFreezerSupported, _data, _reply, 0); + if (!_status && getDefaultImpl() != null) { + return getDefaultImpl().isCachedAppsFreezerSupported(); + } + _reply.readException(); + _result = (0!=_reply.readInt()); + } + finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } + @Override public void freezeApp(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException + { + android.os.Parcel _data = android.os.Parcel.obtain(); + android.os.Parcel _reply = android.os.Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + if ((pkg!=null)) { + _data.writeInt(1); + pkg.writeToParcel(_data, 0); + } + else { + _data.writeInt(0); + } + boolean _status = mRemote.transact(Stub.TRANSACTION_freezeApp, _data, _reply, 0); + if (!_status && getDefaultImpl() != null) { + getDefaultImpl().freezeApp(pkg); + return; + } + _reply.readException(); + } + finally { + _reply.recycle(); + _data.recycle(); + } + } + @Override public void unfreezeApp(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException + { + android.os.Parcel _data = android.os.Parcel.obtain(); + android.os.Parcel _reply = android.os.Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + if ((pkg!=null)) { + _data.writeInt(1); + pkg.writeToParcel(_data, 0); + } + else { + _data.writeInt(0); + } + boolean _status = mRemote.transact(Stub.TRANSACTION_unfreezeApp, _data, _reply, 0); + if (!_status && getDefaultImpl() != null) { + getDefaultImpl().unfreezeApp(pkg); + return; + } + _reply.readException(); + } + finally { + _reply.recycle(); + _data.recycle(); + } + } + @Override public void freezeAppProcess(long pid) throws android.os.RemoteException + { + android.os.Parcel _data = android.os.Parcel.obtain(); + android.os.Parcel _reply = android.os.Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeLong(pid); + boolean _status = mRemote.transact(Stub.TRANSACTION_freezeAppProcess, _data, _reply, 0); + if (!_status && getDefaultImpl() != null) { + getDefaultImpl().freezeAppProcess(pid); + return; + } + _reply.readException(); + } + finally { + _reply.recycle(); + _data.recycle(); + } + } + @Override public void unfreezeAppProcess(long pid) throws android.os.RemoteException + { + android.os.Parcel _data = android.os.Parcel.obtain(); + android.os.Parcel _reply = android.os.Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeLong(pid); + boolean _status = mRemote.transact(Stub.TRANSACTION_unfreezeAppProcess, _data, _reply, 0); + if (!_status && getDefaultImpl() != null) { + getDefaultImpl().unfreezeAppProcess(pid); + return; + } + _reply.readException(); + } + finally { + _reply.recycle(); + _data.recycle(); + } + } public static github.tornaco.android.thanos.core.app.IActivityManager sDefaultImpl; } static final int TRANSACTION_getCurrentFrontApp = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); @@ -3647,6 +3859,11 @@ public java.lang.String getInterfaceDescriptor() static final int TRANSACTION_isNetStatTrackerEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 97); static final int TRANSACTION_checkGetContentProvider = (android.os.IBinder.FIRST_CALL_TRANSACTION + 98); static final int TRANSACTION_getAllStartRecordsForPackageSetWithRes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 99); + static final int TRANSACTION_isCachedAppsFreezerSupported = (android.os.IBinder.FIRST_CALL_TRANSACTION + 100); + static final int TRANSACTION_freezeApp = (android.os.IBinder.FIRST_CALL_TRANSACTION + 101); + static final int TRANSACTION_unfreezeApp = (android.os.IBinder.FIRST_CALL_TRANSACTION + 102); + static final int TRANSACTION_freezeAppProcess = (android.os.IBinder.FIRST_CALL_TRANSACTION + 103); + static final int TRANSACTION_unfreezeAppProcess = (android.os.IBinder.FIRST_CALL_TRANSACTION + 104); 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 @@ -3679,7 +3896,7 @@ public static github.tornaco.android.thanos.core.app.IActivityManager getDefault public java.util.List getRunningServiceLegacy(int max) throws android.os.RemoteException; public java.util.List getRunningAppProcessLegacy() throws android.os.RemoteException; public int getRunningAppsCount() throws android.os.RemoteException; - public github.tornaco.android.thanos.core.process.ProcessRecord[] getRunningAppProcessForPackage(java.lang.String pkgName) throws android.os.RemoteException; + public github.tornaco.android.thanos.core.process.ProcessRecord[] getRunningAppProcessForPackage(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException; public boolean isPackageRunning(java.lang.String pkgName) throws android.os.RemoteException; public java.util.List getStartRecordsByPackageName(java.lang.String pkgName) throws android.os.RemoteException; public java.util.List getStartRecordBlockedPackages() throws android.os.RemoteException; @@ -3757,7 +3974,7 @@ public static github.tornaco.android.thanos.core.app.IActivityManager getDefault public boolean hasRunningServiceForPackage(java.lang.String pkgName) throws android.os.RemoteException; public android.content.pm.UserInfo getUserInfo(int userHandle) throws android.os.RemoteException; public void stopService(android.content.Intent intent) throws android.os.RemoteException; - public void killBackgroundProcesses(java.lang.String packageName) throws android.os.RemoteException; + public void killBackgroundProcesses(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException; public boolean isSmartStandByStopServiceEnabled() throws android.os.RemoteException; public void setSmartStandByStopServiceEnabled(boolean enable) throws android.os.RemoteException; public boolean isSmartStandByInactiveEnabled() throws android.os.RemoteException; @@ -3780,4 +3997,15 @@ public static github.tornaco.android.thanos.core.app.IActivityManager getDefault public boolean isNetStatTrackerEnabled() throws android.os.RemoteException; public boolean checkGetContentProvider(java.lang.String callerPkg, java.lang.String name) throws android.os.RemoteException; public java.util.List getAllStartRecordsForPackageSetWithRes(java.lang.String pkgSetId, boolean allowed, boolean blocked) throws android.os.RemoteException; + // ****************************************************************** + // CAF API + // https://source.android.com/devices/tech/perf/cached-apps-freezer + // + // ****************************************************************** + + public boolean isCachedAppsFreezerSupported() throws android.os.RemoteException; + public void freezeApp(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException; + public void unfreezeApp(github.tornaco.android.thanos.core.pm.Pkg pkg) throws android.os.RemoteException; + public void freezeAppProcess(long pid) throws android.os.RemoteException; + public void unfreezeAppProcess(long pid) throws android.os.RemoteException; } diff --git a/android/app/src/main/java/github/tornaco/android/thanos/DeveloperDiag.java b/android/app/src/main/java/github/tornaco/android/thanos/DeveloperDiag.java index f619b0588..6dbbe42a3 100644 --- a/android/app/src/main/java/github/tornaco/android/thanos/DeveloperDiag.java +++ b/android/app/src/main/java/github/tornaco/android/thanos/DeveloperDiag.java @@ -2,8 +2,14 @@ import android.app.Application; +import com.elvishew.xlog.XLog; + +import github.tornaco.android.thanos.core.app.ThanosManager; + class DeveloperDiag { static void diag(Application application) { + ThanosManager.from(application).ifServiceInstalled(thanosManager -> + XLog.w("DeveloperDiag, CachedAppsFreezer supported: " + thanosManager.getActivityManager().isCachedAppsFreezerSupported())); } } diff --git a/android/internal/Thanox-Internal b/android/internal/Thanox-Internal index 5a2e2ba50..b1f691638 160000 --- a/android/internal/Thanox-Internal +++ b/android/internal/Thanox-Internal @@ -1 +1 @@ -Subproject commit 5a2e2ba5039cf62d51fe52857f3c1226a53dbafc +Subproject commit b1f691638e5610f846008341502de5d55786aca8