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

Commit 21bc03d9 authored by Jiakai Zhang's avatar Jiakai Zhang
Browse files

Get ART optimization info from the app process.

System server reports app startup metrics along with ART optimization
info. Before this change, this information is computed by system server
itself, by using OatFileAssistant to check the optimization status of
the files on disk, through a JNI call.

After this change, this informaition is obtained from the app process.
During the initialization of the app process, the process makes a binder
call, to pass its optimization info to ActivityManagerService (AMS). AMS
then records this information in ProcessRecord's
WindowProcessController. During metrics reporting, Window Manager (WM)
retrives this information from WindowProcessController.

Bug: 422941949
Test: Start an app and see stats logged to statsd_testdrive.
Flag: android.app.get_optimization_info_from_app_process
Change-Id: Ia59788ef889ad7d67e4067ae6e6ac2bc1bef3bfd
parent c2f7c341
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1042,4 +1042,10 @@ interface IActivityManager {
     */
    @EnforcePermission("INTERACT_ACROSS_USERS_FULL")
    IBinder refreshIntentCreatorToken(in Intent intent);

    /**
     * Reports ART optimization info.
     */
    oneway void reportOptimizationInfo(in IBinder app, in String compilerFilter,
            in String compilationReason);
}
+15 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.app;

import static dalvik.system.DexFile.OptimizationInfo;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
@@ -62,8 +64,10 @@ import android.view.DisplayAdjustments;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.DebugStore;
import com.android.internal.os.RuntimeInit;
import com.android.internal.util.ArrayUtils;

import dalvik.system.ApplicationRuntime;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.VMRuntime;

@@ -1195,6 +1199,17 @@ public final class LoadedApk {
        // help deciding whether or not a dex file is the primary apk or a
        // secondary dex.
        DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);

        IBinder app = RuntimeInit.getApplicationObject();
        if (android.app.Flags.getOptimizationInfoFromAppProcess() && app != null) {
            OptimizationInfo info = ApplicationRuntime.getBaseApkOptimizationInfo();
            try {
                ActivityManager.getService().reportOptimizationInfo(
                        app, info.getStatus(), info.getReason());
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

    /**
+8 −0
Original line number Diff line number Diff line
@@ -8,3 +8,11 @@ flag {
     description: "Controls whether to report memory metrics post GC cleanup"
     bug: "331243037"
}

flag {
     namespace: "art_mainline"
     name: "get_optimization_info_from_app_process"
     is_exported: false
     description: "Controls whether to get ART optimization info from the app process for metrics reporting"
     bug: "422941949"
}
+10 −0
Original line number Diff line number Diff line
@@ -19680,4 +19680,14 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        });
    }
    @Override
    public void reportOptimizationInfo(@NonNull IBinder app, @NonNull String compilerFilter,
            @NonNull String compilationReason) {
        final ProcessRecord r = findAppProcess(app, "reportOptimizationInfo");
        if (r == null) {
            return;
        }
        r.getWindowProcessController().setOptimizationInfo(compilerFilter, compilationReason);
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -552,6 +552,14 @@ class ActivityMetricsLogger {
        }

        PackageOptimizationInfo getPackageOptimizationInfo(ArtManagerInternal artManagerInternal) {
            if (android.app.Flags.getOptimizationInfoFromAppProcess()
                    && com.android.art.flags.Flags.updatableFilterAndReason()) {
                if (processRecord == null) {
                    return PackageOptimizationInfo.createWithNoInfo();
                }
                PackageOptimizationInfo info = processRecord.getOptimizationInfo();
                return info != null ? info : PackageOptimizationInfo.createWithNoInfo();
            }
            return artManagerInternal == null || launchedActivityAppRecordRequiredAbi == null
                    ? PackageOptimizationInfo.createWithNoInfo()
                    : artManagerInternal.getPackageOptimizationInfo(applicationInfo,
Loading