diff options
author | Yi Kong <yikong@google.com> | 2020-06-29 20:03:55 +0800 |
---|---|---|
committer | Yi Kong <yikong@google.com> | 2020-09-11 05:57:02 +0800 |
commit | a0bd2a99eebec39da1c94776224e1f43f75b87a4 (patch) | |
tree | 699916882ec91c62f2f9d5113cb89d5c604561fd | |
parent | 4fb19f1550e9c78bd16b77737e108e30184c6d71 (diff) |
Introduce ProfcollectForwardingService
Bug: 79161490
Test: boot and observe logcat
Change-Id: I0413c52f08b930b1e42971acc7f50e2e2da52f99
Merged-In: I0413c52f08b930b1e42971acc7f50e2e2da52f99
-rw-r--r-- | services/Android.bp | 2 | ||||
-rw-r--r-- | services/java/com/android/server/SystemServer.java | 7 | ||||
-rw-r--r-- | services/profcollect/Android.bp | 35 | ||||
-rw-r--r-- | services/profcollect/OWNERS | 3 | ||||
-rw-r--r-- | services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java | 196 |
5 files changed, 243 insertions, 0 deletions
diff --git a/services/Android.bp b/services/Android.bp index f0144ac1c695..ef52c2aff002 100644 --- a/services/Android.bp +++ b/services/Android.bp @@ -30,6 +30,7 @@ filegroup { ":services.midi-sources", ":services.net-sources", ":services.print-sources", + ":services.profcollect-sources", ":services.restrictions-sources", ":services.startop.iorap-sources", ":services.systemcaptions-sources", @@ -73,6 +74,7 @@ java_library { "services.net", "services.people", "services.print", + "services.profcollect", "services.restrictions", "services.startop", "services.systemcaptions", diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index b3dcf4d4fa63..4552bc678802 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -152,6 +152,7 @@ import com.android.server.policy.role.LegacyRoleResolutionPolicy; import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; import com.android.server.power.ThermalManagerService; +import com.android.server.profcollect.ProfcollectForwardingService; import com.android.server.recoverysystem.RecoverySystemService; import com.android.server.restrictions.RestrictionsManagerService; import com.android.server.role.RoleManagerService; @@ -1219,6 +1220,12 @@ public final class SystemServer { mSystemServiceManager.startService(IorapForwardingService.class); t.traceEnd(); + if (Build.IS_DEBUGGABLE) { + t.traceBegin("ProfcollectForwardingService"); + mSystemServiceManager.startService(ProfcollectForwardingService.class); + t.traceEnd(); + } + t.traceBegin("SignedConfigService"); SignedConfigService.registerUpdateReceiver(mSystemContext); t.traceEnd(); diff --git a/services/profcollect/Android.bp b/services/profcollect/Android.bp new file mode 100644 index 000000000000..68fba5508b58 --- /dev/null +++ b/services/profcollect/Android.bp @@ -0,0 +1,35 @@ +// Copyright (C) 2020 The Android Open Source Project +// +// 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. + +filegroup { + name: "services.profcollect-javasources", + srcs: ["src/**/*.java"], + path: "src", + visibility: ["//frameworks/base/services"], +} + +filegroup { + name: "services.profcollect-sources", + srcs: [ + ":services.profcollect-javasources", + ":profcollectd_aidl", + ], + visibility: ["//frameworks/base/services:__subpackages__"], +} + +java_library_static { + name: "services.profcollect", + srcs: [":services.profcollect-sources"], + libs: ["services.core"], +} diff --git a/services/profcollect/OWNERS b/services/profcollect/OWNERS new file mode 100644 index 000000000000..b380e39529e3 --- /dev/null +++ b/services/profcollect/OWNERS @@ -0,0 +1,3 @@ +srhines@google.com +yabinc@google.com +yikong@google.com diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java new file mode 100644 index 000000000000..bc75dcd91813 --- /dev/null +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -0,0 +1,196 @@ +/** + * Copyright (C) 2020 The Android Open Source Project + * + * 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 com.android.server.profcollect; + +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder.DeathRecipient; +import android.os.Looper; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemProperties; +import android.util.Log; + +import com.android.server.IoThread; +import com.android.server.LocalServices; +import com.android.server.SystemService; +import com.android.server.wm.ActivityMetricsLaunchObserver; +import com.android.server.wm.ActivityMetricsLaunchObserverRegistry; +import com.android.server.wm.ActivityTaskManagerInternal; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * System-server-local proxy into the {@code IProfcollectd} native service. + */ +public final class ProfcollectForwardingService extends SystemService { + public static final String LOG_TAG = "ProfcollectForwardingService"; + + private IProfCollectd mIProfcollect; + private ProfcollectForwardingService mSelfService; + private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper()); + + public ProfcollectForwardingService(Context context) { + super(context); + + if (mSelfService != null) { + throw new AssertionError("only one service instance allowed"); + } + mSelfService = this; + } + + @Override + public void onStart() { + Log.i(LOG_TAG, "Profcollect forwarding service start"); + connectNativeService(); + if (mIProfcollect == null) { + return; + } + if (serviceHasSupportedTraceProvider()) { + registerObservers(); + } + } + + private boolean serviceHasSupportedTraceProvider() { + if (mIProfcollect == null) { + return false; + } + try { + return !mIProfcollect.GetSupportedProvider().isEmpty(); + } catch (RemoteException e) { + Log.e(LOG_TAG, e.getMessage()); + return false; + } + } + + private boolean tryConnectNativeService() { + if (connectNativeService()) { + return true; + } + // Cannot connect to the native service at this time, retry after a short delay. + mHandler.sendEmptyMessageDelayed(ProfcollectdHandler.MESSAGE_BINDER_CONNECT, 5000); + return false; + } + + private boolean connectNativeService() { + try { + IProfCollectd profcollectd = + IProfCollectd.Stub.asInterface( + ServiceManager.getServiceOrThrow("profcollectd")); + profcollectd.asBinder().linkToDeath(new ProfcollectdDeathRecipient(), /*flags*/0); + mIProfcollect = profcollectd; + return true; + } catch (ServiceManager.ServiceNotFoundException | RemoteException e) { + Log.w(LOG_TAG, "Failed to connect profcollectd binder service."); + return false; + } + } + + private class ProfcollectdHandler extends Handler { + public ProfcollectdHandler(Looper looper) { + super(looper); + } + + public static final int MESSAGE_BINDER_CONNECT = 0; + + @Override + public void handleMessage(android.os.Message message) { + switch (message.what) { + case MESSAGE_BINDER_CONNECT: + connectNativeService(); + break; + default: + throw new AssertionError("Unknown message: " + message.toString()); + } + } + } + + private class ProfcollectdDeathRecipient implements DeathRecipient { + @Override + public void binderDied() { + Log.w(LOG_TAG, "profcollectd has died"); + + mIProfcollect = null; + tryConnectNativeService(); + } + } + + // Event observers + private void registerObservers() { + registerAppLaunchObserver(); + } + + private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver(); + private void registerAppLaunchObserver() { + ActivityTaskManagerInternal atmInternal = + LocalServices.getService(ActivityTaskManagerInternal.class); + ActivityMetricsLaunchObserverRegistry launchObserverRegistry = + atmInternal.getLaunchObserverRegistry(); + launchObserverRegistry.registerLaunchObserver(mAppLaunchObserver); + } + + private void traceOnAppStart(String packageName) { + if (mIProfcollect == null) { + return; + } + + // Sample for a fraction of app launches. + int traceFrequency = SystemProperties.getInt("profcollectd.applaunch_trace_freq", 2); + int randomNum = ThreadLocalRandom.current().nextInt(100); + if (randomNum < traceFrequency) { + try { + Log.i(LOG_TAG, "Tracing on app launch event: " + packageName); + mIProfcollect.TraceOnce("applaunch"); + } catch (RemoteException e) { + Log.e(LOG_TAG, e.getMessage()); + } + } + } + + private class AppLaunchObserver implements ActivityMetricsLaunchObserver { + @Override + public void onIntentStarted(Intent intent, long timestampNanos) { + traceOnAppStart(intent.getPackage()); + } + + @Override + public void onIntentFailed() { + // Ignored + } + + @Override + public void onActivityLaunched(byte[] activity, int temperature) { + // Ignored + } + + @Override + public void onActivityLaunchCancelled(byte[] abortingActivity) { + // Ignored + } + + @Override + public void onActivityLaunchFinished(byte[] finalActivity, long timestampNanos) { + // Ignored + } + + @Override + public void onReportFullyDrawn(byte[] activity, long timestampNanos) { + // Ignored + } + } +} |