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

Commit 45f31664 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "stats: Add PrinterDiscovery event" into main

parents 64f3da00 8e9e8e5c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import java.util.Map;
 */
public final class PrintAttributes implements Parcelable {
    /** @hide */
    // LINT.IfChange
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, prefix = { "COLOR_MODE_" }, value = {
            COLOR_MODE_MONOCHROME,
@@ -62,9 +63,12 @@ public final class PrintAttributes implements Parcelable {

    private static final int VALID_COLOR_MODES =
            COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR;
    // Update BuiltInPrintService stats logger too.
    // LINT.ThenChange(/packages/PrintSpooler/src/com/android/printspooler/stats/StatsAsyncLogger.kt)

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    // LINT.IfChange
    @IntDef(flag = true, prefix = { "DUPLEX_MODE_" }, value = {
            DUPLEX_MODE_NONE,
            DUPLEX_MODE_LONG_EDGE,
@@ -81,6 +85,8 @@ public final class PrintAttributes implements Parcelable {

    private static final int VALID_DUPLEX_MODES =
            DUPLEX_MODE_NONE | DUPLEX_MODE_LONG_EDGE | DUPLEX_MODE_SHORT_EDGE;
    // Update BuiltInPrintService stats logger too.
    // LINT.ThenChange(/packages/PrintSpooler/src/com/android/printspooler/stats/StatsAsyncLogger.kt)

    private @Nullable MediaSize mMediaSize;
    private @Nullable Resolution mResolution;
@@ -462,6 +468,7 @@ public final class PrintAttributes implements Parcelable {
        private static final Map<String, MediaSize> sIdToMediaSizeMap =
                new ArrayMap<>();

        // LINT.IfChange
        /**
         * Unknown media size in portrait mode.
         * <p>
@@ -840,6 +847,8 @@ public final class PrintAttributes implements Parcelable {
        public static final @NonNull MediaSize JPN_OE_PHOTO_L =
                new MediaSize("JPN_OE_PHOTO_L", "android",
                        R.string.mediasize_japanese_l, 3500, 5000);
        // Update BuiltInPrintService stats logger too.
        // LINT.ThenChange(/packages/PrintSpooler/src/com/android/printspooler/stats/StatsAsyncLogger.kt)

        private final @NonNull String mId;
        /**@hide */
+594 −0

File changed.

Preview size limit exceeded, changes collapsed.

+19 −0
Original line number Diff line number Diff line
@@ -49,4 +49,23 @@ open class StatsLogWrapper {
            printServiceCount,
        )
    }

    open fun internalPrinterDiscovery(
        @UserIdInt printServiceId: Int,
        supportedColors: Set<StatsAsyncLogger.InternalColorModePrinterDiscoveryEvent>,
        supportedSizes: Set<StatsAsyncLogger.InternalMediaSizePrinterDiscoveryEvent>,
        supportedDuplexModes: Set<StatsAsyncLogger.InternalDuplexModePrinterDiscoveryEvent>,
    ) {
        val colorBits = supportedColors.map { it.rawValue }.toIntArray()
        val mediaSizes = supportedSizes.map { it.rawValue }.toIntArray()
        val duplexModes = supportedDuplexModes.map { it.rawValue }.toIntArray()

        PrintSpoolerStatsLog.write(
            PrintSpoolerStatsLog.FRAMEWORK_PRINTER_DISCOVERY,
            printServiceId,
            colorBits,
            mediaSizes,
            duplexModes,
        )
    }
}
+25 −0
Original line number Diff line number Diff line
@@ -2663,6 +2663,31 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
                }
            }

            if (Flags.printingTelemetry()) {
                for (final PrinterInfo printer : newPrintersMap.values()) {
                    final PrinterCapabilitiesInfo caps = printer.getCapabilities();
                    int colorModesMask = 0;
                    int duplexModesMask = 0;
                    Set<MediaSize> mediaSizes = new HashSet<>();
                    if (caps != null) {
                        colorModesMask = caps.getColorModes();
                        duplexModesMask = caps.getDuplexModes();
                        mediaSizes = new HashSet<>(caps.getMediaSizes());
                    }
                    final String serviceName = printer.getId().getServiceName().getPackageName();
                    try {
                        final int serviceUId =
                                getPackageManager().getApplicationInfo(serviceName, 0).uid;
                        StatsAsyncLogger.INSTANCE
                                .PrinterDiscovery(serviceUId,
                                                  colorModesMask,
                                                  duplexModesMask,
                                                  mediaSizes);
                    } catch (NameNotFoundException e) {
                        Log.e(LOG_TAG, "Failed to get uid for service");
                    }
                }
            }
            // Add the rest of the new printers, i.e. what is left.
            addPrinters(newPrinterHolders, newPrintersMap.values());

+89 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.printspooler.stats

import android.os.Handler
import android.print.PrintAttributes
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Semaphore
@@ -61,6 +62,90 @@ open class StatsAsyncLoggerTest {
        StatsAsyncLogger.stopLogging()
    }

    @Test
    fun printerDiscoverySuccessfullyLoggedTest() {
        val logWrapperInOrder = inOrder(mStatsLogWrapper)
        val handlerInOrder = inOrder(mHandler)
        val semaphoreInOrder = inOrder(mSemaphore)
        val timeCaptor = argumentCaptor<Long>()
        val runnableCaptor = argumentCaptor<Runnable>()

        StatsAsyncLogger.startLogging()
        StatsAsyncLogger.testSetSemaphore(mSemaphore)
        StatsAsyncLogger.testSetHandler(mHandler)
        StatsAsyncLogger.testSetStatsLogWrapper(mStatsLogWrapper)

        // "foo" printer service: Generally arbitrary arguments focusing more on creating non-empty
        // lists.
        val printServiceFoo = 42
        val colorsMaskFoo =
            (PrintAttributes.COLOR_MODE_COLOR or PrintAttributes.COLOR_MODE_MONOCHROME)
        val supportedMediaSizesFoo =
            setOf<PrintAttributes.MediaSize>(
                PrintAttributes.MediaSize.NA_LETTER,
                PrintAttributes.MediaSize.JPN_HAGAKI,
            )
        val duplexModeMaskFoo =
            (PrintAttributes.DUPLEX_MODE_LONG_EDGE or PrintAttributes.DUPLEX_MODE_SHORT_EDGE)

        assertThat(
                StatsAsyncLogger.PrinterDiscovery(
                    printServiceFoo,
                    colorsMaskFoo,
                    duplexModeMaskFoo,
                    supportedMediaSizesFoo,
                )
            )
            .isTrue()

        // "bar" printer service: Generally arbitrary arguments focusing more on empty/default
        // values.
        val printServiceBar = 1337
        assertThat(StatsAsyncLogger.PrinterDiscovery(printServiceBar, 0, 0, setOf())).isTrue()

        handlerInOrder
            .verify(mHandler, times(2))
            .postAtTime(runnableCaptor.capture(), timeCaptor.capture())
        handlerInOrder.verifyNoMoreInteractions()

        // Validate delay args
        val firstTime = timeCaptor.firstValue
        val secondTime = timeCaptor.secondValue
        assertThat(secondTime - firstTime)
            .isAtLeast(StatsAsyncLogger.EVENT_REPORTED_MIN_INTERVAL.inWholeMilliseconds)
        assertThat(secondTime - firstTime)
            .isAtMost(2 * StatsAsyncLogger.EVENT_REPORTED_MIN_INTERVAL.inWholeMilliseconds)

        // Validate Runnable logic
        runnableCaptor.firstValue.run()
        runnableCaptor.secondValue.run()
        logWrapperInOrder
            .verify(mStatsLogWrapper)
            .internalPrinterDiscovery(
                printServiceFoo,
                setOf(
                    StatsAsyncLogger.InternalColorModePrinterDiscoveryEvent.COLOR,
                    StatsAsyncLogger.InternalColorModePrinterDiscoveryEvent.MONOCHROME,
                ),
                setOf(
                    StatsAsyncLogger.InternalMediaSizePrinterDiscoveryEvent.NA_LETTER,
                    StatsAsyncLogger.InternalMediaSizePrinterDiscoveryEvent.JPN_HAGAKI,
                ),
                setOf(
                    StatsAsyncLogger.InternalDuplexModePrinterDiscoveryEvent.LONG_EDGE,
                    StatsAsyncLogger.InternalDuplexModePrinterDiscoveryEvent.SHORT_EDGE,
                ),
            )
        logWrapperInOrder
            .verify(mStatsLogWrapper)
            .internalPrinterDiscovery(printServiceBar, setOf(), setOf(), setOf())
        logWrapperInOrder.verifyNoMoreInteractions()

        // Validate Semaphore logic
        semaphoreInOrder.verify(mSemaphore, times(2)).tryAcquire()
        semaphoreInOrder.verify(mSemaphore, times(2)).release()
    }

    @Test
    fun mainPrintUiLaunchedSuccessfullyLoggedTest() {
        val logWrapperInOrder = inOrder(mStatsLogWrapper)
@@ -155,6 +240,7 @@ open class StatsAsyncLoggerTest {
        // Arbitrary Arguments
        assertThat(StatsAsyncLogger.AdvancedOptionsUiLaunched(42)).isFalse()
        assertThat(StatsAsyncLogger.MainPrintUiLaunched(setOf(1, 2, 3), 42)).isFalse()
        assertThat(StatsAsyncLogger.PrinterDiscovery(1337, 0, 0, setOf())).isFalse()
        verifyNoInteractions(mHandler)
    }

@@ -168,7 +254,8 @@ open class StatsAsyncLoggerTest {
        // Arbitrary Arguments
        assertThat(StatsAsyncLogger.AdvancedOptionsUiLaunched(42)).isFalse()
        assertThat(StatsAsyncLogger.MainPrintUiLaunched(setOf(1, 2, 3), 42)).isFalse()
        verify(mSemaphore, times(2)).release()
        assertThat(StatsAsyncLogger.PrinterDiscovery(1337, 0, 0, setOf())).isFalse()
        verify(mSemaphore, times(3)).release()
    }

    @Test
@@ -201,6 +288,7 @@ open class StatsAsyncLoggerTest {
        // Arbitrary Arguments
        assertThat(StatsAsyncLogger.AdvancedOptionsUiLaunched(42)).isFalse()
        assertThat(StatsAsyncLogger.MainPrintUiLaunched(setOf(1, 2, 3), 42)).isFalse()
        assertThat(StatsAsyncLogger.PrinterDiscovery(1337, 0, 0, setOf())).isFalse()
        verifyNoInteractions(mHandler)
        verifyNoInteractions(mSemaphore)
        verifyNoInteractions(mStatsLogWrapper)