Loading core/res/AndroidManifest.xml +5 −1 Original line number Diff line number Diff line Loading @@ -8980,7 +8980,11 @@ android:permission="android.permission.BIND_JOB_SERVICE" > </service> <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ProfcollectBGJobService" <service android:name="com.android.server.profcollect.ProfcollectForwardingService$PeriodicTraceJobService" android:permission="android.permission.BIND_JOB_SERVICE" > </service> <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ReportProcessJobService" android:permission="android.permission.BIND_JOB_SERVICE" > </service> Loading services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +95 −44 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.profcollect; import static android.content.Intent.ACTION_SCREEN_OFF; import static android.content.Intent.ACTION_SCREEN_ON; import android.Manifest; import android.annotation.RequiresPermission; import android.app.job.JobInfo; Loading @@ -32,6 +35,7 @@ import android.hardware.usb.UsbManager; import android.os.Handler; import android.os.IBinder.DeathRecipient; import android.os.Looper; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; Loading Loading @@ -70,10 +74,11 @@ public final class ProfcollectForwardingService extends SystemService { private int mUsageSetting; private boolean mUploadEnabled; private static boolean sVerityEnforced; private boolean mAdbActive; static boolean sVerityEnforced; static boolean sIsInteractive; static boolean sAdbActive; private IProfCollectd mIProfcollect; private static IProfCollectd sIProfcollect; private static ProfcollectForwardingService sSelfService; private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper()); Loading @@ -86,17 +91,24 @@ public final class ProfcollectForwardingService extends SystemService { private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) { if (ACTION_SCREEN_ON.equals(intent.getAction())) { Log.d(LOG_TAG, "Received broadcast that the device became interactive, was " + sIsInteractive); sIsInteractive = true; } else if (ACTION_SCREEN_OFF.equals(intent.getAction())) { Log.d(LOG_TAG, "Received broadcast that the device became noninteractive, was " + sIsInteractive); sIsInteractive = false; } else if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) { Log.d(LOG_TAG, "Received broadcast to pack and upload reports"); createAndUploadReport(sSelfService); } if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) { } else if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) { boolean isADB = intent.getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false); if (isADB) { boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); Log.d(LOG_TAG, "Received broadcast that ADB became " + connected + ", was " + mAdbActive); mAdbActive = connected; + ", was " + sAdbActive); sAdbActive = connected; } } } Loading Loading @@ -129,6 +141,8 @@ public final class ProfcollectForwardingService extends SystemService { context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled); final IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_SCREEN_ON); filter.addAction(ACTION_SCREEN_OFF); filter.addAction(INTENT_UPLOAD_PROFILES); filter.addAction(UsbManager.ACTION_USB_STATE); context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED); Loading @@ -153,14 +167,24 @@ public final class ProfcollectForwardingService extends SystemService { if (phase == PHASE_SYSTEM_SERVICES_READY) { UsbManager usbManager = getContext().getSystemService(UsbManager.class); if (usbManager == null) { mAdbActive = false; return; sAdbActive = false; Log.d(LOG_TAG, "USBManager is not ready"); } else { sAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1); Log.d(LOG_TAG, "ADB is " + sAdbActive + " on system startup"); } PowerManager powerManager = getContext().getSystemService(PowerManager.class); if (powerManager == null) { sIsInteractive = true; Log.d(LOG_TAG, "PowerManager is not ready"); } else { sIsInteractive = powerManager.isInteractive(); Log.d(LOG_TAG, "Device is interactive " + sIsInteractive + " on system startup"); } mAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1); Log.d(LOG_TAG, "ADB is " + mAdbActive + " on system startup"); } if (phase == PHASE_BOOT_COMPLETED) { if (mIProfcollect == null) { if (sIProfcollect == null) { return; } BackgroundThread.get().getThreadHandler().post(() -> { Loading @@ -172,22 +196,22 @@ public final class ProfcollectForwardingService extends SystemService { } private void registerProviderStatusCallback() { if (mIProfcollect == null) { if (sIProfcollect == null) { return; } try { mIProfcollect.registerProviderStatusCallback(mProviderStatusCallback); sIProfcollect.registerProviderStatusCallback(mProviderStatusCallback); } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to register provider status callback: " + e.getMessage()); } } private boolean serviceHasSupportedTraceProvider() { if (mIProfcollect == null) { if (sIProfcollect == null) { return false; } try { return !mIProfcollect.get_supported_provider().isEmpty(); return !sIProfcollect.get_supported_provider().isEmpty(); } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to get supported provider: " + e.getMessage()); return false; Loading @@ -209,7 +233,7 @@ public final class ProfcollectForwardingService extends SystemService { IProfCollectd.Stub.asInterface( ServiceManager.getServiceOrThrow("profcollectd")); profcollectd.asBinder().linkToDeath(new ProfcollectdDeathRecipient(), /*flags*/0); mIProfcollect = profcollectd; sIProfcollect = profcollectd; return true; } catch (ServiceManager.ServiceNotFoundException | RemoteException e) { Log.w(LOG_TAG, "Failed to connect profcollectd binder service."); Loading @@ -233,7 +257,8 @@ public final class ProfcollectForwardingService extends SystemService { break; case MESSAGE_REGISTER_SCHEDULERS: registerObservers(); ProfcollectBGJobService.schedule(getContext()); PeriodicTraceJobService.schedule(getContext()); ReportProcessJobService.schedule(getContext()); break; default: throw new AssertionError("Unknown message: " + message); Loading @@ -246,27 +271,66 @@ public final class ProfcollectForwardingService extends SystemService { public void binderDied() { Log.w(LOG_TAG, "profcollectd has died"); mIProfcollect = null; sIProfcollect = null; tryConnectNativeService(); } } /** * Background trace process service. * Background report process and upload service. */ public static class ProfcollectBGJobService extends JobService { // Unique ID in system service private static final int JOB_IDLE_PROCESS = 260817; public static class PeriodicTraceJobService extends JobService { // Unique ID in system server private static final int PERIODIC_TRACE_JOB_ID = 241207; private static final ComponentName JOB_SERVICE_NAME = new ComponentName( "android", ProfcollectBGJobService.class.getName()); PeriodicTraceJobService.class.getName()); /** * Attach the service to the system job scheduler. */ public static void schedule(Context context) { final int interval = DeviceConfig.getInt(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, "collection_interval", 600); JobScheduler js = context.getSystemService(JobScheduler.class); js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME) js.schedule(new JobInfo.Builder(PERIODIC_TRACE_JOB_ID, JOB_SERVICE_NAME) .setPeriodic(TimeUnit.SECONDS.toMillis(interval)) // PRIORITY_DEFAULT is the highest priority we can request for a periodic job. .setPriority(JobInfo.PRIORITY_DEFAULT) .build()); } @Override public boolean onStartJob(JobParameters params) { if (sIProfcollect != null) { Utils.traceSystem(sIProfcollect, "periodic"); } jobFinished(params, false); return true; } @Override public boolean onStopJob(JobParameters params) { return false; } } /** * Background report process and upload service. */ public static class ReportProcessJobService extends JobService { // Unique ID in system server private static final int REPORT_PROCESS_JOB_ID = 260817; private static final ComponentName JOB_SERVICE_NAME = new ComponentName( "android", ReportProcessJobService.class.getName()); /** * Attach the service to the system job scheduler. */ public static void schedule(Context context) { JobScheduler js = context.getSystemService(JobScheduler.class); js.schedule(new JobInfo.Builder(REPORT_PROCESS_JOB_ID, JOB_SERVICE_NAME) .setRequiresDeviceIdle(true) .setRequiresCharging(true) .setPeriodic(BG_PROCESS_INTERVAL) Loading @@ -283,7 +347,6 @@ public final class ProfcollectForwardingService extends SystemService { @Override public boolean onStopJob(JobParameters params) { // TODO: Handle this? return false; } } Loading Loading @@ -311,14 +374,8 @@ public final class ProfcollectForwardingService extends SystemService { private class AppLaunchObserver extends ActivityMetricsLaunchObserver { @Override public void onIntentStarted(Intent intent, long timestampNanos) { if (mIProfcollect == null) { return; } if (mAdbActive) { return; } if (Utils.withFrequency("applaunch_trace_freq", 5)) { Utils.traceSystem(mIProfcollect, "applaunch"); Utils.traceSystem(sIProfcollect, "applaunch"); } } } Loading @@ -336,15 +393,9 @@ public final class ProfcollectForwardingService extends SystemService { } private void traceOnDex2oatStart() { if (mIProfcollect == null) { return; } if (mAdbActive) { return; } if (Utils.withFrequency("dex2oat_trace_freq", 25)) { // Dex2oat could take a while before it starts. Add a short delay before start tracing. Utils.traceSystem(mIProfcollect, "dex2oat", /* delayMs */ 1000); Utils.traceSystem(sIProfcollect, "dex2oat", /* delayMs */ 1000); } } Loading @@ -367,12 +418,12 @@ public final class ProfcollectForwardingService extends SystemService { private static void createAndUploadReport(ProfcollectForwardingService pfs) { BackgroundThread.get().getThreadHandler().post(() -> { if (pfs.mIProfcollect == null) { if (pfs.sIProfcollect == null) { return; } String reportName; try { reportName = pfs.mIProfcollect.report(pfs.mUsageSetting) + ".zip"; reportName = pfs.sIProfcollect.report(pfs.mUsageSetting) + ".zip"; } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to create report: " + e.getMessage()); return; Loading Loading @@ -411,7 +462,7 @@ public final class ProfcollectForwardingService extends SystemService { return; } if (Utils.withFrequency("camera_trace_freq", 10)) { Utils.traceProcess(mIProfcollect, Utils.traceProcess(sIProfcollect, "camera", "android.hardware.camera.provider", /* durationMs */ 5000); Loading services/profcollect/src/com/android/server/profcollect/Utils.java +35 −20 Original line number Diff line number Diff line Loading @@ -28,28 +28,29 @@ import com.android.internal.os.BackgroundThread; import java.time.Instant; import java.util.concurrent.ThreadLocalRandom; public final class Utils { final class Utils { private static Instant lastTraceTime = Instant.EPOCH; private static final int TRACE_COOLDOWN_SECONDS = 30; public static boolean withFrequency(String configName, int defaultFrequency) { static boolean withFrequency(String configName, int defaultFrequency) { int threshold = DeviceConfig.getInt( DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, configName, defaultFrequency); int randomNum = ThreadLocalRandom.current().nextInt(100); return randomNum < threshold; } public static boolean traceSystem(IProfCollectd mIProfcollect, String eventName) { if (mIProfcollect == null) { return false; } if (isInCooldownOrReset()) { /** * Request a system-wide trace. * Will be ignored if the device does not meet trace criteria or is being rate limited. */ static boolean traceSystem(IProfCollectd iprofcollectd, String eventName) { if (!checkPrerequisites(iprofcollectd)) { return false; } BackgroundThread.get().getThreadHandler().post(() -> { try { mIProfcollect.trace_system(eventName); iprofcollectd.trace_system(eventName); } catch (RemoteException | ServiceSpecificException e) { Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage()); } Loading @@ -57,16 +58,17 @@ public final class Utils { return true; } public static boolean traceSystem(IProfCollectd mIProfcollect, String eventName, int delayMs) { if (mIProfcollect == null) { return false; } if (isInCooldownOrReset()) { /** * Request a system-wide trace after a delay. * Will be ignored if the device does not meet trace criteria or is being rate limited. */ static boolean traceSystem(IProfCollectd iprofcollectd, String eventName, int delayMs) { if (!checkPrerequisites(iprofcollectd)) { return false; } BackgroundThread.get().getThreadHandler().postDelayed(() -> { try { mIProfcollect.trace_system(eventName); iprofcollectd.trace_system(eventName); } catch (RemoteException | ServiceSpecificException e) { Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage()); } Loading @@ -74,17 +76,18 @@ public final class Utils { return true; } public static boolean traceProcess(IProfCollectd mIProfcollect, /** * Request a single-process trace. * Will be ignored if the device does not meet trace criteria or is being rate limited. */ static boolean traceProcess(IProfCollectd iprofcollectd, String eventName, String processName, int durationMs) { if (mIProfcollect == null) { return false; } if (isInCooldownOrReset()) { if (!checkPrerequisites(iprofcollectd)) { return false; } BackgroundThread.get().getThreadHandler().post(() -> { try { mIProfcollect.trace_process(eventName, iprofcollectd.trace_process(eventName, processName, durationMs); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -105,4 +108,16 @@ public final class Utils { } return true; } private static boolean checkPrerequisites(IProfCollectd iprofcollectd) { if (iprofcollectd == null) { return false; } if (isInCooldownOrReset()) { return false; } return ProfcollectForwardingService.sVerityEnforced && !ProfcollectForwardingService.sAdbActive && ProfcollectForwardingService.sIsInteractive; } } Loading
core/res/AndroidManifest.xml +5 −1 Original line number Diff line number Diff line Loading @@ -8980,7 +8980,11 @@ android:permission="android.permission.BIND_JOB_SERVICE" > </service> <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ProfcollectBGJobService" <service android:name="com.android.server.profcollect.ProfcollectForwardingService$PeriodicTraceJobService" android:permission="android.permission.BIND_JOB_SERVICE" > </service> <service android:name="com.android.server.profcollect.ProfcollectForwardingService$ReportProcessJobService" android:permission="android.permission.BIND_JOB_SERVICE" > </service> Loading
services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +95 −44 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.profcollect; import static android.content.Intent.ACTION_SCREEN_OFF; import static android.content.Intent.ACTION_SCREEN_ON; import android.Manifest; import android.annotation.RequiresPermission; import android.app.job.JobInfo; Loading @@ -32,6 +35,7 @@ import android.hardware.usb.UsbManager; import android.os.Handler; import android.os.IBinder.DeathRecipient; import android.os.Looper; import android.os.PowerManager; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; Loading Loading @@ -70,10 +74,11 @@ public final class ProfcollectForwardingService extends SystemService { private int mUsageSetting; private boolean mUploadEnabled; private static boolean sVerityEnforced; private boolean mAdbActive; static boolean sVerityEnforced; static boolean sIsInteractive; static boolean sAdbActive; private IProfCollectd mIProfcollect; private static IProfCollectd sIProfcollect; private static ProfcollectForwardingService sSelfService; private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper()); Loading @@ -86,17 +91,24 @@ public final class ProfcollectForwardingService extends SystemService { private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) { if (ACTION_SCREEN_ON.equals(intent.getAction())) { Log.d(LOG_TAG, "Received broadcast that the device became interactive, was " + sIsInteractive); sIsInteractive = true; } else if (ACTION_SCREEN_OFF.equals(intent.getAction())) { Log.d(LOG_TAG, "Received broadcast that the device became noninteractive, was " + sIsInteractive); sIsInteractive = false; } else if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) { Log.d(LOG_TAG, "Received broadcast to pack and upload reports"); createAndUploadReport(sSelfService); } if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) { } else if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) { boolean isADB = intent.getBooleanExtra(UsbManager.USB_FUNCTION_ADB, false); if (isADB) { boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); Log.d(LOG_TAG, "Received broadcast that ADB became " + connected + ", was " + mAdbActive); mAdbActive = connected; + ", was " + sAdbActive); sAdbActive = connected; } } } Loading Loading @@ -129,6 +141,8 @@ public final class ProfcollectForwardingService extends SystemService { context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled); final IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_SCREEN_ON); filter.addAction(ACTION_SCREEN_OFF); filter.addAction(INTENT_UPLOAD_PROFILES); filter.addAction(UsbManager.ACTION_USB_STATE); context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED); Loading @@ -153,14 +167,24 @@ public final class ProfcollectForwardingService extends SystemService { if (phase == PHASE_SYSTEM_SERVICES_READY) { UsbManager usbManager = getContext().getSystemService(UsbManager.class); if (usbManager == null) { mAdbActive = false; return; sAdbActive = false; Log.d(LOG_TAG, "USBManager is not ready"); } else { sAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1); Log.d(LOG_TAG, "ADB is " + sAdbActive + " on system startup"); } PowerManager powerManager = getContext().getSystemService(PowerManager.class); if (powerManager == null) { sIsInteractive = true; Log.d(LOG_TAG, "PowerManager is not ready"); } else { sIsInteractive = powerManager.isInteractive(); Log.d(LOG_TAG, "Device is interactive " + sIsInteractive + " on system startup"); } mAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1); Log.d(LOG_TAG, "ADB is " + mAdbActive + " on system startup"); } if (phase == PHASE_BOOT_COMPLETED) { if (mIProfcollect == null) { if (sIProfcollect == null) { return; } BackgroundThread.get().getThreadHandler().post(() -> { Loading @@ -172,22 +196,22 @@ public final class ProfcollectForwardingService extends SystemService { } private void registerProviderStatusCallback() { if (mIProfcollect == null) { if (sIProfcollect == null) { return; } try { mIProfcollect.registerProviderStatusCallback(mProviderStatusCallback); sIProfcollect.registerProviderStatusCallback(mProviderStatusCallback); } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to register provider status callback: " + e.getMessage()); } } private boolean serviceHasSupportedTraceProvider() { if (mIProfcollect == null) { if (sIProfcollect == null) { return false; } try { return !mIProfcollect.get_supported_provider().isEmpty(); return !sIProfcollect.get_supported_provider().isEmpty(); } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to get supported provider: " + e.getMessage()); return false; Loading @@ -209,7 +233,7 @@ public final class ProfcollectForwardingService extends SystemService { IProfCollectd.Stub.asInterface( ServiceManager.getServiceOrThrow("profcollectd")); profcollectd.asBinder().linkToDeath(new ProfcollectdDeathRecipient(), /*flags*/0); mIProfcollect = profcollectd; sIProfcollect = profcollectd; return true; } catch (ServiceManager.ServiceNotFoundException | RemoteException e) { Log.w(LOG_TAG, "Failed to connect profcollectd binder service."); Loading @@ -233,7 +257,8 @@ public final class ProfcollectForwardingService extends SystemService { break; case MESSAGE_REGISTER_SCHEDULERS: registerObservers(); ProfcollectBGJobService.schedule(getContext()); PeriodicTraceJobService.schedule(getContext()); ReportProcessJobService.schedule(getContext()); break; default: throw new AssertionError("Unknown message: " + message); Loading @@ -246,27 +271,66 @@ public final class ProfcollectForwardingService extends SystemService { public void binderDied() { Log.w(LOG_TAG, "profcollectd has died"); mIProfcollect = null; sIProfcollect = null; tryConnectNativeService(); } } /** * Background trace process service. * Background report process and upload service. */ public static class ProfcollectBGJobService extends JobService { // Unique ID in system service private static final int JOB_IDLE_PROCESS = 260817; public static class PeriodicTraceJobService extends JobService { // Unique ID in system server private static final int PERIODIC_TRACE_JOB_ID = 241207; private static final ComponentName JOB_SERVICE_NAME = new ComponentName( "android", ProfcollectBGJobService.class.getName()); PeriodicTraceJobService.class.getName()); /** * Attach the service to the system job scheduler. */ public static void schedule(Context context) { final int interval = DeviceConfig.getInt(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, "collection_interval", 600); JobScheduler js = context.getSystemService(JobScheduler.class); js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME) js.schedule(new JobInfo.Builder(PERIODIC_TRACE_JOB_ID, JOB_SERVICE_NAME) .setPeriodic(TimeUnit.SECONDS.toMillis(interval)) // PRIORITY_DEFAULT is the highest priority we can request for a periodic job. .setPriority(JobInfo.PRIORITY_DEFAULT) .build()); } @Override public boolean onStartJob(JobParameters params) { if (sIProfcollect != null) { Utils.traceSystem(sIProfcollect, "periodic"); } jobFinished(params, false); return true; } @Override public boolean onStopJob(JobParameters params) { return false; } } /** * Background report process and upload service. */ public static class ReportProcessJobService extends JobService { // Unique ID in system server private static final int REPORT_PROCESS_JOB_ID = 260817; private static final ComponentName JOB_SERVICE_NAME = new ComponentName( "android", ReportProcessJobService.class.getName()); /** * Attach the service to the system job scheduler. */ public static void schedule(Context context) { JobScheduler js = context.getSystemService(JobScheduler.class); js.schedule(new JobInfo.Builder(REPORT_PROCESS_JOB_ID, JOB_SERVICE_NAME) .setRequiresDeviceIdle(true) .setRequiresCharging(true) .setPeriodic(BG_PROCESS_INTERVAL) Loading @@ -283,7 +347,6 @@ public final class ProfcollectForwardingService extends SystemService { @Override public boolean onStopJob(JobParameters params) { // TODO: Handle this? return false; } } Loading Loading @@ -311,14 +374,8 @@ public final class ProfcollectForwardingService extends SystemService { private class AppLaunchObserver extends ActivityMetricsLaunchObserver { @Override public void onIntentStarted(Intent intent, long timestampNanos) { if (mIProfcollect == null) { return; } if (mAdbActive) { return; } if (Utils.withFrequency("applaunch_trace_freq", 5)) { Utils.traceSystem(mIProfcollect, "applaunch"); Utils.traceSystem(sIProfcollect, "applaunch"); } } } Loading @@ -336,15 +393,9 @@ public final class ProfcollectForwardingService extends SystemService { } private void traceOnDex2oatStart() { if (mIProfcollect == null) { return; } if (mAdbActive) { return; } if (Utils.withFrequency("dex2oat_trace_freq", 25)) { // Dex2oat could take a while before it starts. Add a short delay before start tracing. Utils.traceSystem(mIProfcollect, "dex2oat", /* delayMs */ 1000); Utils.traceSystem(sIProfcollect, "dex2oat", /* delayMs */ 1000); } } Loading @@ -367,12 +418,12 @@ public final class ProfcollectForwardingService extends SystemService { private static void createAndUploadReport(ProfcollectForwardingService pfs) { BackgroundThread.get().getThreadHandler().post(() -> { if (pfs.mIProfcollect == null) { if (pfs.sIProfcollect == null) { return; } String reportName; try { reportName = pfs.mIProfcollect.report(pfs.mUsageSetting) + ".zip"; reportName = pfs.sIProfcollect.report(pfs.mUsageSetting) + ".zip"; } catch (RemoteException e) { Log.e(LOG_TAG, "Failed to create report: " + e.getMessage()); return; Loading Loading @@ -411,7 +462,7 @@ public final class ProfcollectForwardingService extends SystemService { return; } if (Utils.withFrequency("camera_trace_freq", 10)) { Utils.traceProcess(mIProfcollect, Utils.traceProcess(sIProfcollect, "camera", "android.hardware.camera.provider", /* durationMs */ 5000); Loading
services/profcollect/src/com/android/server/profcollect/Utils.java +35 −20 Original line number Diff line number Diff line Loading @@ -28,28 +28,29 @@ import com.android.internal.os.BackgroundThread; import java.time.Instant; import java.util.concurrent.ThreadLocalRandom; public final class Utils { final class Utils { private static Instant lastTraceTime = Instant.EPOCH; private static final int TRACE_COOLDOWN_SECONDS = 30; public static boolean withFrequency(String configName, int defaultFrequency) { static boolean withFrequency(String configName, int defaultFrequency) { int threshold = DeviceConfig.getInt( DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT, configName, defaultFrequency); int randomNum = ThreadLocalRandom.current().nextInt(100); return randomNum < threshold; } public static boolean traceSystem(IProfCollectd mIProfcollect, String eventName) { if (mIProfcollect == null) { return false; } if (isInCooldownOrReset()) { /** * Request a system-wide trace. * Will be ignored if the device does not meet trace criteria or is being rate limited. */ static boolean traceSystem(IProfCollectd iprofcollectd, String eventName) { if (!checkPrerequisites(iprofcollectd)) { return false; } BackgroundThread.get().getThreadHandler().post(() -> { try { mIProfcollect.trace_system(eventName); iprofcollectd.trace_system(eventName); } catch (RemoteException | ServiceSpecificException e) { Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage()); } Loading @@ -57,16 +58,17 @@ public final class Utils { return true; } public static boolean traceSystem(IProfCollectd mIProfcollect, String eventName, int delayMs) { if (mIProfcollect == null) { return false; } if (isInCooldownOrReset()) { /** * Request a system-wide trace after a delay. * Will be ignored if the device does not meet trace criteria or is being rate limited. */ static boolean traceSystem(IProfCollectd iprofcollectd, String eventName, int delayMs) { if (!checkPrerequisites(iprofcollectd)) { return false; } BackgroundThread.get().getThreadHandler().postDelayed(() -> { try { mIProfcollect.trace_system(eventName); iprofcollectd.trace_system(eventName); } catch (RemoteException | ServiceSpecificException e) { Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage()); } Loading @@ -74,17 +76,18 @@ public final class Utils { return true; } public static boolean traceProcess(IProfCollectd mIProfcollect, /** * Request a single-process trace. * Will be ignored if the device does not meet trace criteria or is being rate limited. */ static boolean traceProcess(IProfCollectd iprofcollectd, String eventName, String processName, int durationMs) { if (mIProfcollect == null) { return false; } if (isInCooldownOrReset()) { if (!checkPrerequisites(iprofcollectd)) { return false; } BackgroundThread.get().getThreadHandler().post(() -> { try { mIProfcollect.trace_process(eventName, iprofcollectd.trace_process(eventName, processName, durationMs); } catch (RemoteException | ServiceSpecificException e) { Loading @@ -105,4 +108,16 @@ public final class Utils { } return true; } private static boolean checkPrerequisites(IProfCollectd iprofcollectd) { if (iprofcollectd == null) { return false; } if (isInCooldownOrReset()) { return false; } return ProfcollectForwardingService.sVerityEnforced && !ProfcollectForwardingService.sAdbActive && ProfcollectForwardingService.sIsInteractive; } }