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

Commit 26a716c7 authored by Lalit Maganti's avatar Lalit Maganti Committed by Automerger Merge Worker
Browse files

Merge "base: add support for routing traces to reporters" am: 3a24d6bf

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1918624

Change-Id: If2c06f5698f1952c02f5b449a6ab9fac9257c9b6
parents 67105844 3a24d6bf
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ package android {
    field public static final String BIND_TELEPHONY_NETWORK_SERVICE = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
    field public static final String BIND_TEXTCLASSIFIER_SERVICE = "android.permission.BIND_TEXTCLASSIFIER_SERVICE";
    field public static final String BIND_TIME_ZONE_PROVIDER_SERVICE = "android.permission.BIND_TIME_ZONE_PROVIDER_SERVICE";
    field public static final String BIND_TRACE_REPORT_SERVICE = "android.permission.BIND_TRACE_REPORT_SERVICE";
    field public static final String BIND_TRANSLATION_SERVICE = "android.permission.BIND_TRANSLATION_SERVICE";
    field public static final String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
    field public static final String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
@@ -10120,6 +10121,22 @@ package android.service.timezone {
}
package android.service.tracing {
  public class TraceReportService extends android.app.Service {
    ctor public TraceReportService();
    method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
    method public boolean onMessage(@NonNull android.os.Message);
    method public void onReportTrace(@NonNull android.service.tracing.TraceReportService.TraceParams);
  }
  public static final class TraceReportService.TraceParams {
    method @NonNull public android.os.ParcelFileDescriptor getFd();
    method @NonNull public java.util.UUID getUuid();
  }
}
package android.service.translation {
  public abstract class TranslationService extends android.app.Service {
+5 −0
Original line number Diff line number Diff line
@@ -33,6 +33,11 @@ filegroup {
    srcs: ["android/tracing/ITracingServiceProxy.aidl"],
}

filegroup {
    name: "TraceReportParams.aidl",
    srcs: ["android/tracing/TraceReportParams.aidl"],
}

// These are subset of framework-core-sources that are needed by the
// android.test.mock library. The implementation of android.test.mock references
// private members of various components to allow mocking of classes that cannot
+165 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 android.service.tracing;

import static android.annotation.SystemApi.Client.PRIVILEGED_APPS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.tracing.TraceReportParams;
import android.util.Log;

import java.io.IOException;
import java.util.UUID;

/**
 * Service to be sub-classed and exposed by (privileged) apps which want to report
 * system traces.
 * <p>
 * Subclasses should implement the onReportTrace method to handle traces reported
 * to them.
 * </p>
 * <pre>
 *    public class SampleReportService extends TraceReportService {
 *        public void onReportTrace(TraceParams args) {
 *            // --- Implementation goes here ---
 *        }
 *    }
 * </pre>
 * <p>
 * The service declaration in the application manifest must specify
 * BIND_TRACE_REPORT_SERVICE in the permission attribute.
 * </p>
 * <pre>
 *   &lt;application>
 *        &lt;service android:name=".SampleReportService"
 *               android:permission="android.permission.BIND_TRACE_REPORT_SERVICE">
 *       &lt;/service>
 *   &lt;/application>
 * </pre>
 *
 * Moreover, the package containing this service must hold the DUMP and PACKAGE_USAGE_STATS
 * permissions.
 *
 * @hide
 */
@SystemApi(client = PRIVILEGED_APPS)
public class TraceReportService extends Service {
    private static final String TAG = "TraceReportService";
    private Messenger mMessenger = null;

    /**
     * Public to allow this to be used by TracingServiceProxy in system_server.
     *
     * @hide
     */
    public static final int MSG_REPORT_TRACE = 1;

    /**
     * Contains information about the trace which is being reported.
     *
     * @hide
     */
    @SystemApi(client = PRIVILEGED_APPS)
    public static final class TraceParams {
        private final ParcelFileDescriptor mFd;
        private final UUID mUuid;

        private TraceParams(TraceReportParams params) {
            mFd = params.fd;
            mUuid = new UUID(params.uuidMsb, params.uuidLsb);
        }

        /**
         * Returns the ParcelFileDescriptor for the collected trace.
         */
        @NonNull
        public ParcelFileDescriptor getFd() {
            return mFd;
        }

        /**
         * Returns the UUID of the trace; this is exactly the UUID created by the tracing system
         * (i.e. Perfetto) and is also present inside the trace file.
         */
        @NonNull
        public UUID getUuid() {
            return mUuid;
        }
    }

    // Methods to override.
    /**
     * Called when a trace is reported and sent to this class.
     *
     * Note: the trace file descriptor should not be persisted beyond the lifetime of this
     * function as it is owned by the framework and will be closed immediately after this function
     * returns: if future use of the fd is needed, it should be duped.
     */
    public void onReportTrace(@NonNull TraceParams args) {
    }

    // Optional methods to override.
    // Realistically, these methods are internal implementation details but since this class is
    // a SystemApi, it's better to err on the side of flexibility just in-case we need to override
    // these methods down the line.

    /**
     * Handles binder calls from system_server.
     */
    public boolean onMessage(@NonNull Message msg) {
        if (msg.what == MSG_REPORT_TRACE) {
            if (!(msg.obj instanceof TraceReportParams)) {
                Log.e(TAG, "Received invalid type for report trace message.");
                return false;
            }
            TraceParams params = new TraceParams((TraceReportParams) msg.obj);
            try {
                onReportTrace(params);
            } finally {
                try {
                    params.getFd().close();
                } catch (IOException ignored) {
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Returns an IBinder for handling binder calls from system_server.
     */
    @Nullable
    @Override
    public IBinder onBind(@NonNull Intent intent) {
        if (mMessenger == null) {
            mMessenger = new Messenger(new Handler(Looper.getMainLooper(), this::onMessage));
        }
        return mMessenger.getBinder();
    }
}
 No newline at end of file
+10 −2
Original line number Diff line number Diff line
@@ -16,17 +16,25 @@

package android.tracing;

import android.tracing.TraceReportParams;

/**
 * Binder interface for the TracingServiceProxy running in system_server.
 *
 * {@hide}
 */
interface ITracingServiceProxy
{
interface ITracingServiceProxy {
    /**
     * Notifies system tracing app that a tracing session has ended. If a session is repurposed
     * for use in a bugreport, sessionStolen can be set to indicate that tracing has ended but
     * there is no buffer available to dump.
     */
    oneway void notifyTraceSessionEnded(boolean sessionStolen);

    /**
     * Notifies the specified service that a trace has been captured. The contents of |params|
     * contains the intended recipient (package and class) of this trace as well as a file
     * descriptor to an unlinked trace |fd| (i.e. an fd opened using O_TMPFILE).
     */
    oneway void reportTrace(in TraceReportParams params);
}
+59 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2021, 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 android.tracing;

import android.os.ParcelFileDescriptor;

/*
 * Parameters for a trace report.
 *
 * See ITracingServiceProxy::reportTrace for more details.
 *
 * @hide
 */
parcelable TraceReportParams {
  // The package name containing the reporter service (see |reporterClassName|).
  String reporterPackageName;

  // The class name of the reporter service. The framework will bind to this service and pass the
  // trace fd and metadata to this class.
  // This class should be "trusted" (in practice this means being a priv_app + having DUMP and
  // USAGE_STATS permissions).
  String reporterClassName;

  // The file descriptor for the trace file. This will be an unlinked file fd (i.e. created
  // with O_TMPFILE); the intention is that reporter classes link this fd into a app-private
  // folder for reporting when conditions are right (e.g. charging, on unmetered networks etc).
  ParcelFileDescriptor fd;

  // The least-significant-bytes of the UUID of this trace.
  long uuidLsb;

  // The most-significant-bytes of the UUID of this trace.
  long uuidMsb;

  // Flag indicating whether, instead of passing the fd from the trace collector, to pass a
  // pipe fd from system_server and send the file over it.
  //
  // This flag is necessary because there is no good way to write a CTS test where a helper
  // priv_app (in terms of SELinux) is needed (this is because priv_apps are supposed to be
  // preinstalled on the system partition). By creating a pipe in system_server we work around
  // this restriction. Note that there is a maximum allowed file size if this flag is set
  // (see TracingServiceProxy). Further note that, even though SELinux may be worked around,
  // manifest (i.e. framework) permissions are still checked even if this flag is set.
  boolean usePipeForTesting;
}
 No newline at end of file
Loading