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

Commit 33194bb4 authored by Weilin Xu's avatar Weilin Xu Committed by Android (Google) Code Review
Browse files

Merge "Add event logger to BroadcastRadio Service"

parents b2bed0e6 b724e39d
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2022 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.broadcastradio.hal2;

import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.Log;
import android.util.Slog;

final class RadioEventLogger {
    private final String mTag;
    private final LocalLog mEventLogger;

    RadioEventLogger(String tag, int loggerQueueSize) {
        mTag = tag;
        mEventLogger = new LocalLog(loggerQueueSize);
    }

    void logRadioEvent(String logFormat, Object... args) {
        String log = String.format(logFormat, args);
        mEventLogger.log(log);
        if (Log.isLoggable(mTag, Log.DEBUG)) {
            Slog.d(mTag, log);
        }
    }

    void dump(IndentingPrintWriter pw) {
        mEventLogger.dump(pw);
    }
}
+13 −5
Original line number Diff line number Diff line
@@ -55,12 +55,14 @@ import java.util.stream.Collectors;

class RadioModule {
    private static final String TAG = "BcRadio2Srv.module";
    private static final int RADIO_EVENT_LOGGER_QUEUE_SIZE = 25;

    @NonNull private final IBroadcastRadio mService;
    @NonNull public final RadioManager.ModuleProperties mProperties;

    private final Object mLock;
    @NonNull private final Handler mHandler;
    @NonNull private final RadioEventLogger mEventLogger;

    @GuardedBy("mLock")
    private ITunerSession mHalTunerSession;
@@ -138,6 +140,7 @@ class RadioModule {
        mService = Objects.requireNonNull(service);
        mLock = Objects.requireNonNull(lock);
        mHandler = new Handler(Looper.getMainLooper());
        mEventLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE);
    }

    public static @Nullable RadioModule tryLoadingModule(int idx, @NonNull String fqName,
@@ -176,13 +179,14 @@ class RadioModule {

    public @NonNull TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb)
            throws RemoteException {
        Slog.i(TAG, "Open TunerSession");
        mEventLogger.logRadioEvent("Open TunerSession");
        synchronized (mLock) {
            if (mHalTunerSession == null) {
                Mutable<ITunerSession> hwSession = new Mutable<>();
                mService.openSession(mHalTunerCallback, (result, session) -> {
                    Convert.throwOnError("openSession", result);
                    hwSession.value = session;
                    mEventLogger.logRadioEvent("New HIDL 2.0 tuner session is opened");
                });
                mHalTunerSession = Objects.requireNonNull(hwSession.value);
            }
@@ -207,7 +211,7 @@ class RadioModule {
        // Copy the contents of mAidlTunerSessions into a local array because TunerSession.close()
        // must be called without mAidlTunerSessions locked because it can call
        // onTunerSessionClosed().
        Slog.i(TAG, "Close TunerSessions");
        mEventLogger.logRadioEvent("Close TunerSessions");
        TunerSession[] tunerSessions;
        synchronized (mLock) {
            tunerSessions = new TunerSession[mAidlTunerSessions.size()];
@@ -320,7 +324,7 @@ class RadioModule {
        }
        onTunerSessionProgramListFilterChanged(null);
        if (mAidlTunerSessions.isEmpty() && mHalTunerSession != null) {
            Slog.i(TAG, "Closing HAL tuner session");
            mEventLogger.logRadioEvent("Closing HAL tuner session");
            try {
                mHalTunerSession.close();
            } catch (RemoteException ex) {
@@ -372,7 +376,7 @@ class RadioModule {

    public android.hardware.radio.ICloseHandle addAnnouncementListener(@NonNull int[] enabledTypes,
            @NonNull android.hardware.radio.IAnnouncementListener listener) throws RemoteException {
        Slog.i(TAG, "Add AnnouncementListener");
        mEventLogger.logRadioEvent("Add AnnouncementListener");
        ArrayList<Byte> enabledList = new ArrayList<>();
        for (int type : enabledTypes) {
            enabledList.add((byte)type);
@@ -409,7 +413,7 @@ class RadioModule {
    }

    Bitmap getImage(int id) {
        Slog.i(TAG, "Get image for id " + id);
        mEventLogger.logRadioEvent("Get image for id %d", id);
        if (id == 0) throw new IllegalArgumentException("Image ID is missing");

        byte[] rawImage;
@@ -449,6 +453,10 @@ class RadioModule {
            }
            pw.decreaseIndent();
        }
        pw.printf("Radio module events:\n");
        pw.increaseIndent();
        mEventLogger.dump(pw);
        pw.decreaseIndent();
        pw.decreaseIndent();
    }
}
+19 −23
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.os.RemoteException;
import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.MutableBoolean;
import android.util.MutableInt;
import android.util.Slog;
@@ -41,8 +40,10 @@ import java.util.Objects;
class TunerSession extends ITuner.Stub {
    private static final String TAG = "BcRadio2Srv.session";
    private static final String kAudioDeviceName = "Radio tuner source";
    private static final int TUNER_EVENT_LOGGER_QUEUE_SIZE = 25;

    private final Object mLock;
    @NonNull private final RadioEventLogger mEventLogger;

    private final RadioModule mModule;
    private final ITunerSession mHwSession;
@@ -61,15 +62,12 @@ class TunerSession extends ITuner.Stub {
        mHwSession = Objects.requireNonNull(hwSession);
        mCallback = Objects.requireNonNull(callback);
        mLock = Objects.requireNonNull(lock);
    }

    private boolean isDebugEnabled() {
        return Log.isLoggable(TAG, Log.DEBUG);
        mEventLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
    }

    @Override
    public void close() {
        if (isDebugEnabled()) Slog.d(TAG, "Close");
        mEventLogger.logRadioEvent("Close");
        close(null);
    }

@@ -81,7 +79,7 @@ class TunerSession extends ITuner.Stub {
     * @param error Optional error to send to client before session is closed.
     */
    public void close(@Nullable Integer error) {
        if (isDebugEnabled()) Slog.d(TAG, "Close on error " + error);
        mEventLogger.logRadioEvent("Close on error %d", error);
        synchronized (mLock) {
            if (mIsClosed) return;
            if (error != null) {
@@ -145,10 +143,8 @@ class TunerSession extends ITuner.Stub {

    @Override
    public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException {
        if (isDebugEnabled()) {
            Slog.d(TAG, "Step with directionDown " + directionDown
                    + " skipSubChannel " + skipSubChannel);
        }
        mEventLogger.logRadioEvent("Step with direction %s, skipSubChannel?  %s",
                directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
        synchronized (mLock) {
            checkNotClosedLocked();
            int halResult = mHwSession.step(!directionDown);
@@ -158,10 +154,8 @@ class TunerSession extends ITuner.Stub {

    @Override
    public void scan(boolean directionDown, boolean skipSubChannel) throws RemoteException {
        if (isDebugEnabled()) {
            Slog.d(TAG, "Scan with directionDown " + directionDown
                    + " skipSubChannel " + skipSubChannel);
        }
        mEventLogger.logRadioEvent("Scan with direction %s, skipSubChannel? %s",
                directionDown ? "down" : "up", skipSubChannel ? "yes" : "no");
        synchronized (mLock) {
            checkNotClosedLocked();
            int halResult = mHwSession.scan(!directionDown, skipSubChannel);
@@ -171,7 +165,7 @@ class TunerSession extends ITuner.Stub {

    @Override
    public void tune(ProgramSelector selector) throws RemoteException {
        if (isDebugEnabled()) Slog.d(TAG, "Tune with selector " + selector);
        mEventLogger.logRadioEvent("Tune with selector %s", selector);
        synchronized (mLock) {
            checkNotClosedLocked();
            int halResult = mHwSession.tune(Convert.programSelectorToHal(selector));
@@ -195,7 +189,7 @@ class TunerSession extends ITuner.Stub {

    @Override
    public Bitmap getImage(int id) {
        if (isDebugEnabled()) Slog.d(TAG, "Get image for " + id);
        mEventLogger.logRadioEvent("Get image for %d", id);
        return mModule.getImage(id);
    }

@@ -208,7 +202,7 @@ class TunerSession extends ITuner.Stub {

    @Override
    public void startProgramListUpdates(ProgramList.Filter filter) throws RemoteException {
        if (isDebugEnabled()) Slog.d(TAG, "start programList updates " + filter);
        mEventLogger.logRadioEvent("start programList updates %s", filter);
        // If the AIDL client provides a null filter, it wants all updates, so use the most broad
        // filter.
        if (filter == null) {
@@ -267,7 +261,7 @@ class TunerSession extends ITuner.Stub {

    @Override
    public void stopProgramListUpdates() throws RemoteException {
        if (isDebugEnabled()) Slog.d(TAG, "Stop programList updates");
        mEventLogger.logRadioEvent("Stop programList updates");
        synchronized (mLock) {
            checkNotClosedLocked();
            mProgramInfoCache = null;
@@ -291,7 +285,7 @@ class TunerSession extends ITuner.Stub {

    @Override
    public boolean isConfigFlagSet(int flag) {
        if (isDebugEnabled()) Slog.d(TAG, "Is ConfigFlagSet for " + ConfigFlag.toString(flag));
        mEventLogger.logRadioEvent("Is ConfigFlagSet for %s", ConfigFlag.toString(flag));
        synchronized (mLock) {
            checkNotClosedLocked();

@@ -313,9 +307,7 @@ class TunerSession extends ITuner.Stub {

    @Override
    public void setConfigFlag(int flag, boolean value) throws RemoteException {
        if (isDebugEnabled()) {
            Slog.d(TAG, "Set ConfigFlag " + ConfigFlag.toString(flag) + " = " + value);
        }
        mEventLogger.logRadioEvent("Set ConfigFlag  %s = %b", ConfigFlag.toString(flag), value);
        synchronized (mLock) {
            checkNotClosedLocked();
            int halResult = mHwSession.setConfigFlag(flag, value);
@@ -351,6 +343,10 @@ class TunerSession extends ITuner.Stub {
            pw.printf("ProgramInfoCache: %s\n", mProgramInfoCache);
            pw.printf("Config: %s\n", mDummyConfig);
        }
        pw.printf("Tuner session events:\n");
        pw.increaseIndent();
        mEventLogger.dump(pw);
        pw.decreaseIndent();
        pw.decreaseIndent();
    }
}