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

Commit a2e12619 authored by Robert Luo's avatar Robert Luo Committed by Android (Google) Code Review
Browse files

Merge "Migrate media output switcher metrics - 3/n" into rvc-qpr-dev-plus-aosp

parents 04e97d44 8da41d2e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -396,7 +396,7 @@ public class MediaOutputSlice implements CustomSliceable {

    @Override
    public Class getBackgroundWorkerClass() {
        return MediaOutputSliceWorker.class;
        return MediaDeviceUpdateWorker.class;
    }

    private boolean isVisible() {
+0 −211
Original line number Diff line number Diff line
/*
 * 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.settings.media;

import static android.media.MediaRoute2ProviderService.REASON_INVALID_COMMAND;
import static android.media.MediaRoute2ProviderService.REASON_NETWORK_ERROR;
import static android.media.MediaRoute2ProviderService.REASON_REJECTED;
import static android.media.MediaRoute2ProviderService.REASON_ROUTE_NOT_AVAILABLE;
import static android.media.MediaRoute2ProviderService.REASON_UNKNOWN_ERROR;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.net.Uri;
import android.util.Log;

import com.android.settings.core.instrumentation.SettingsStatsLog;
import com.android.settingslib.media.MediaDevice;

/**
 * SliceBackgroundWorker for the MediaOutputSlice class.
 * It inherits from MediaDeviceUpdateWorker and add metrics logging.
 */
public class MediaOutputSliceWorker extends MediaDeviceUpdateWorker {

    private static final String TAG = "MediaOutputSliceWorker";
    private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);

    private MediaDevice mSourceDevice, mTargetDevice;
    private int mWiredDeviceCount;
    private int mConnectedBluetoothDeviceCount;
    private int mRemoteDeviceCount;
    private int mAppliedDeviceCountWithinRemoteGroup;

    public MediaOutputSliceWorker(Context context, Uri uri) {
        super(context, uri);
    }

    @Override
    public void connectDevice(MediaDevice device) {
        mSourceDevice = mLocalMediaManager.getCurrentConnectedDevice();
        mTargetDevice = device;

        if (DBG) {
            Log.d(TAG, "connectDevice -"
                    + " source:" + mSourceDevice.toString()
                    + " target:" + mTargetDevice.toString());
        }

        super.connectDevice(device);
    }

    private int getLoggingDeviceType(MediaDevice device, boolean isSourceDevice) {
        switch (device.getDeviceType()) {
            case MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE:
                return isSourceDevice
                        ? SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SOURCE__BUILTIN_SPEAKER
                        : SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__TARGET__BUILTIN_SPEAKER;
            case MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE:
                return isSourceDevice
                        ? SettingsStatsLog
                        .MEDIA_OUTPUT_OP_SWITCH_REPORTED__SOURCE__WIRED_3POINT5_MM_AUDIO
                        : SettingsStatsLog
                                .MEDIA_OUTPUT_OP_SWITCH_REPORTED__TARGET__WIRED_3POINT5_MM_AUDIO;
            case MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE:
                return isSourceDevice
                        ? SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SOURCE__USB_C_AUDIO
                        : SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__TARGET__USB_C_AUDIO;
            case MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE:
                return isSourceDevice
                        ? SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SOURCE__BLUETOOTH
                        : SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__TARGET__BLUETOOTH;
            case MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE:
                return isSourceDevice
                        ? SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SOURCE__REMOTE_SINGLE
                        : SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__TARGET__REMOTE_SINGLE;
            case MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE:
                return isSourceDevice
                        ? SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SOURCE__REMOTE_GROUP
                        : SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__TARGET__REMOTE_GROUP;
            default:
                return isSourceDevice
                        ? SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SOURCE__UNKNOWN_TYPE
                        : SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__TARGET__UNKNOWN_TYPE;
        }
    }

    private int getLoggingSwitchOpSubResult(int reason) {
        switch (reason) {
            case REASON_REJECTED:
                return SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SUBRESULT__REJECTED;
            case REASON_NETWORK_ERROR:
                return SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SUBRESULT__NETWORK_ERROR;
            case REASON_ROUTE_NOT_AVAILABLE:
                return SettingsStatsLog
                        .MEDIA_OUTPUT_OP_SWITCH_REPORTED__SUBRESULT__ROUTE_NOT_AVAILABLE;
            case REASON_INVALID_COMMAND:
                return SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SUBRESULT__INVALID_COMMAND;
            case REASON_UNKNOWN_ERROR:
            default:
                return SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SUBRESULT__UNKNOWN_ERROR;
        }
    }

    private String getLoggingPackageName() {
        final String packageName = getPackageName();
        if (packageName != null && !packageName.isEmpty()) {
            try {
                final ApplicationInfo applicationInfo = mContext.getPackageManager()
                        .getApplicationInfo(packageName, /* default flag */ 0);
                if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
                        || (applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                    return packageName;
                }
            } catch (Exception ex) {
                Log.e(TAG, packageName + "is invalid.");
            }
        }

        return "";
    }

    private void updateLoggingDeviceCount() {
        mWiredDeviceCount = mConnectedBluetoothDeviceCount = mRemoteDeviceCount = 0;
        mAppliedDeviceCountWithinRemoteGroup = 0;

        for (MediaDevice mediaDevice : mMediaDevices) {
            if (mediaDevice.isConnected()) {
                switch (mediaDevice.getDeviceType()) {
                    case MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE:
                    case MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE:
                        mWiredDeviceCount++;
                        break;
                    case MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE:
                        mConnectedBluetoothDeviceCount++;
                        break;
                    case MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE:
                    case MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE:
                        mRemoteDeviceCount++;
                        break;
                    default:
                }
            }
        }

        if (DBG) {
            Log.d(TAG, "connected devices:" + " wired: " + mWiredDeviceCount
                    + " bluetooth: " + mConnectedBluetoothDeviceCount
                    + " remote: " + mRemoteDeviceCount);
        }
    }

    @Override
    public void onSelectedDeviceStateChanged(MediaDevice device, int state) {
        if (DBG) {
            Log.d(TAG, "onSelectedDeviceStateChanged - " + device.toString());
        }

        updateLoggingDeviceCount();

        SettingsStatsLog.write(
                SettingsStatsLog.MEDIAOUTPUT_OP_SWITCH_REPORTED,
                getLoggingDeviceType(mSourceDevice, true),
                getLoggingDeviceType(mTargetDevice, false),
                SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__RESULT__OK,
                SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SUBRESULT__NO_ERROR,
                getLoggingPackageName(),
                mWiredDeviceCount,
                mConnectedBluetoothDeviceCount,
                mRemoteDeviceCount,
                mAppliedDeviceCountWithinRemoteGroup);

        super.onSelectedDeviceStateChanged(device, state);
    }

    @Override
    public void onRequestFailed(int reason) {
        if (DBG) {
            Log.e(TAG, "onRequestFailed - " + reason);
        }

        updateLoggingDeviceCount();

        SettingsStatsLog.write(
                SettingsStatsLog.MEDIAOUTPUT_OP_SWITCH_REPORTED,
                getLoggingDeviceType(mSourceDevice, true),
                getLoggingDeviceType(mTargetDevice, false),
                SettingsStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__RESULT__ERROR,
                getLoggingSwitchOpSubResult(reason),
                getLoggingPackageName(),
                mWiredDeviceCount,
                mConnectedBluetoothDeviceCount,
                mRemoteDeviceCount,
                mAppliedDeviceCountWithinRemoteGroup);

        super.onRequestFailed(reason);
    }
}