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

Commit 22b821f8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add measurements for TransportClient connections"

parents e205c8d1 e5a97640
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -3525,7 +3525,10 @@ public class BackupManagerService implements BackupManagerServiceInterface {
                        dumpAgents(pw);
                        return;
                    } else if ("transportclients".equals(arg.toLowerCase())) {
                        mTransportManager.dump(pw);
                        mTransportManager.dumpTransportClients(pw);
                        return;
                    } else if ("transportstats".equals(arg.toLowerCase())) {
                        mTransportManager.dumpTransportStats(pw);
                        return;
                    }
                }
@@ -3590,7 +3593,7 @@ public class BackupManagerService implements BackupManagerServiceInterface {
                }
            }

            mTransportManager.dump(pw);
            mTransportManager.dumpTransportClients(pw);

            pw.println("Pending init: " + mPendingInits.size());
            for (String s : mPendingInits) {
+14 −2
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.server.backup.transport.TransportClientManager;
import com.android.server.backup.transport.TransportConnectionListener;
import com.android.server.backup.transport.TransportNotAvailableException;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.backup.transport.TransportStats;

import java.io.PrintWriter;
import java.util.List;
@@ -64,6 +65,7 @@ public class TransportManager {
    private final PackageManager mPackageManager;
    private final Set<ComponentName> mTransportWhitelist;
    private final TransportClientManager mTransportClientManager;
    private final TransportStats mTransportStats;
    private OnTransportRegisteredListener mOnTransportRegisteredListener = (c, n) -> {};

    /**
@@ -85,7 +87,12 @@ public class TransportManager {
    private volatile String mCurrentTransportName;

    TransportManager(Context context, Set<ComponentName> whitelist, String selectedTransport) {
        this(context, whitelist, selectedTransport, new TransportClientManager(context));
        mContext = context;
        mPackageManager = context.getPackageManager();
        mTransportWhitelist = Preconditions.checkNotNull(whitelist);
        mCurrentTransportName = selectedTransport;
        mTransportStats = new TransportStats();
        mTransportClientManager = new TransportClientManager(context, mTransportStats);
    }

    @VisibleForTesting
@@ -98,6 +105,7 @@ public class TransportManager {
        mPackageManager = context.getPackageManager();
        mTransportWhitelist = Preconditions.checkNotNull(whitelist);
        mCurrentTransportName = selectedTransport;
        mTransportStats = new TransportStats();
        mTransportClientManager = transportClientManager;
    }

@@ -650,10 +658,14 @@ public class TransportManager {
                !Thread.holdsLock(mTransportLock), "Can't call transport with transport lock held");
    }

    public void dump(PrintWriter pw) {
    public void dumpTransportClients(PrintWriter pw) {
        mTransportClientManager.dump(pw);
    }

    public void dumpTransportStats(PrintWriter pw) {
        mTransportStats.dump(pw);
    }

    private static Predicate<ComponentName> fromPackageFilter(String packageName) {
        return transportComponent -> packageName.equals(transportComponent.getPackageName());
    }
+13 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.DeadObjectException;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.format.DateFormat;
import android.util.ArrayMap;
@@ -51,6 +52,7 @@ import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -78,6 +80,7 @@ public class TransportClient {
    private static final int LOG_BUFFER_SIZE = 5;

    private final Context mContext;
    private final TransportStats mTransportStats;
    private final Intent mBindIntent;
    private final ServiceConnection mConnection;
    private final String mIdentifier;
@@ -104,12 +107,14 @@ public class TransportClient {

    TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller) {
        this(
                context,
                transportStats,
                bindIntent,
                transportComponent,
                identifier,
@@ -120,12 +125,14 @@ public class TransportClient {
    @VisibleForTesting
    TransportClient(
            Context context,
            TransportStats transportStats,
            Intent bindIntent,
            ComponentName transportComponent,
            String identifier,
            String caller,
            Handler listenerHandler) {
        mContext = context;
        mTransportStats = transportStats;
        mTransportComponent = transportComponent;
        mBindIntent = bindIntent;
        mIdentifier = identifier;
@@ -321,11 +328,16 @@ public class TransportClient {
                (requestedTransport, transportClient) ->
                        transportFuture.complete(requestedTransport);

        long requestTime = SystemClock.elapsedRealtime();
        log(Priority.DEBUG, caller, "Sync connect: calling async");
        connectAsync(requestListener, caller);

        try {
            return transportFuture.get();
            transport = transportFuture.get();
            long time = SystemClock.elapsedRealtime() - requestTime;
            mTransportStats.registerConnectionTime(mTransportComponent, time);
            log(Priority.DEBUG, caller, String.format(Locale.US, "Connect took %d ms", time));
            return transport;
        } catch (InterruptedException | ExecutionException e) {
            String error = e.getClass().getSimpleName();
            log(Priority.ERROR, caller, error + " while waiting for transport: " + e.getMessage());
+4 −1
Original line number Diff line number Diff line
@@ -37,12 +37,14 @@ public class TransportClientManager {
    private static final String TAG = "TransportClientManager";

    private final Context mContext;
    private final TransportStats mTransportStats;
    private final Object mTransportClientsLock = new Object();
    private int mTransportClientsCreated = 0;
    private Map<TransportClient, String> mTransportClientsCallerMap = new WeakHashMap<>();

    public TransportClientManager(Context context) {
    public TransportClientManager(Context context, TransportStats transportStats) {
        mContext = context;
        mTransportStats = transportStats;
    }

    /**
@@ -88,6 +90,7 @@ public class TransportClientManager {
            TransportClient transportClient =
                    new TransportClient(
                            mContext,
                            mTransportStats,
                            bindIntent,
                            transportComponent,
                            Integer.toString(mTransportClientsCreated),
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.backup.transport;

import android.annotation.Nullable;
import android.content.ComponentName;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;

/** Responsible for aggregating {@link TransportClient} relevant times. */
public class TransportStats {
    private final Object mStatsLock = new Object();
    private final Map<ComponentName, Stats> mTransportStats = new HashMap<>();

    void registerConnectionTime(ComponentName transportComponent, long timeMs) {
        synchronized (mStatsLock) {
            mTransportStats
                    .computeIfAbsent(transportComponent, name -> new Stats())
                    .register(timeMs);
        }
    }

    /** Returns {@link Stats} for transport whose host service is {@code transportComponent}. */
    @Nullable
    public Stats getStatsForTransport(ComponentName transportComponent) {
        synchronized (mStatsLock) {
            Stats stats = mTransportStats.get(transportComponent);
            if (stats == null) {
                return null;
            }
            return new Stats(stats);
        }
    }

    public void dump(PrintWriter pw) {
        synchronized (mStatsLock) {
            Optional<Stats> aggregatedStats =
                    mTransportStats.values().stream().reduce(Stats::merge);
            if (aggregatedStats.isPresent()) {
                dumpStats(pw, "", aggregatedStats.get());
            }
            if (!mTransportStats.isEmpty()) {
                pw.println("Per transport:");
                for (ComponentName transportComponent : mTransportStats.keySet()) {
                    Stats stats = mTransportStats.get(transportComponent);
                    pw.println("    " + transportComponent.flattenToShortString());
                    dumpStats(pw, "        ", stats);
                }
            }
        }
    }

    private static void dumpStats(PrintWriter pw, String prefix, Stats stats) {
        pw.println(
                String.format(
                        Locale.US, "%sAverage connection time: %.2f ms", prefix, stats.mAverage));
        pw.println(String.format(Locale.US, "%sMax connection time: %d ms", prefix, stats.mMax));
        pw.println(String.format(Locale.US, "%sMin connection time: %d ms", prefix, stats.mMin));
        pw.println(String.format(Locale.US, "%sNumber of connections: %d ", prefix, stats.mN));
    }

    public static final class Stats {
        public static Stats merge(Stats a, Stats b) {
            return new Stats(
                    a.mN + b.mN,
                    (a.mAverage * a.mN + b.mAverage * b.mN) / (a.mN + b.mN),
                    Math.max(a.mMax, b.mMax),
                    Math.min(a.mMin, b.mMin));
        }

        public int mN;
        public double mAverage;
        public long mMax;
        public long mMin;

        public Stats() {
            mN = 0;
            mAverage = 0;
            mMax = 0;
            mMin = Long.MAX_VALUE;
        }

        private Stats(Stats original) {
            mN = original.mN;
            mAverage = original.mAverage;
            mMax = original.mMax;
            mMin = original.mMin;
        }

        private Stats(int n, double average, long max, long min) {
            mN = n;
            mAverage = average;
            mMax = max;
            mMin = min;
        }

        private void register(long sample) {
            mAverage = (mAverage * mN + sample) / (mN + 1);
            mN++;
            mMax = Math.max(mMax, sample);
            mMin = Math.min(mMin, sample);
        }
    }
}
Loading