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

Commit 63696c00 authored by Adam Lesinski's avatar Adam Lesinski Committed by android-build-merger
Browse files

Merge "BatteryStats: Introduce Async external stats requests" into nyc-dev

am: 0d47f4b6

* commit '0d47f4b6':
  BatteryStats: Introduce Async external stats requests

Change-Id: I7319535a0210e38a6bc3731a9f0ec42a4485924f
parents a7fcaabb 0d47f4b6
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -156,8 +156,8 @@ public final class BluetoothActivityEnergyInfo implements Parcelable {
     * @return if the record is valid
     */
    public boolean isValid() {
        return ((mControllerTxTimeMs !=0) ||
                (mControllerRxTimeMs !=0) ||
                (mControllerIdleTimeMs !=0));
        return ((mControllerTxTimeMs >=0) &&
                (mControllerRxTimeMs >=0) &&
                (mControllerIdleTimeMs >=0));
    }
}
+43 −10
Original line number Diff line number Diff line
@@ -31,11 +31,14 @@ import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.SynchronousResultReceiver;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;
@@ -53,6 +56,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeoutException;

/**
 * Represents the local device Bluetooth adapter. The {@link BluetoothAdapter}
@@ -1369,33 +1373,62 @@ public final class BluetoothAdapter {
     *
     * @return a record with {@link BluetoothActivityEnergyInfo} or null if
     * report is unavailable or unsupported
     * @deprecated use the asynchronous
     * {@link #requestControllerActivityEnergyInfo(int, ResultReceiver)} instead.
     * @hide
     */
    @Deprecated
    public BluetoothActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
        if (getState() != STATE_ON) return null;
        SynchronousResultReceiver receiver = new SynchronousResultReceiver();
        requestControllerActivityEnergyInfo(updateType, receiver);
        try {
            BluetoothActivityEnergyInfo record;
            if (!mService.isActivityAndEnergyReportingSupported()) {
            SynchronousResultReceiver.Result result = receiver.awaitResult(1000);
            if (result.bundle != null) {
                return result.bundle.getParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY);
            }
        } catch (TimeoutException e) {
            Log.e(TAG, "getControllerActivityEnergyInfo timed out");
        }
        return null;
    }

    /**
     * Request the record of {@link BluetoothActivityEnergyInfo} object that
     * has the activity and energy info. This can be used to ascertain what
     * the controller has been up to, since the last sample.
     *
     * A null value for the activity info object may be sent if the bluetooth service is
     * unreachable or the device does not support reporting such information.
     *
     * @param updateType Type of info, cached vs refreshed.
     * @param result The callback to which to send the activity info.
     * @hide
     */
    public void requestControllerActivityEnergyInfo(int updateType, ResultReceiver result) {
        if (getState() != STATE_ON) {
            result.send(0, null);
            return;
        }

        try {
            if (!mService.isActivityAndEnergyReportingSupported()) {
                result.send(0, null);
                return;
            }
            synchronized(this) {
                if (updateType == ACTIVITY_ENERGY_INFO_REFRESHED) {
                    mService.getActivityEnergyInfoFromController();
                    wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS);
                }
                record = mService.reportActivityInfo();
                if (record.isValid()) {
                    return record;
                } else {
                    return null;
                }
                mService.requestActivityInfo(result);
            }
        } catch (InterruptedException e) {
            Log.e(TAG, "getControllerActivityEnergyInfoCallback wait interrupted: " + e);
            result.send(0, null);
        } catch (RemoteException e) {
            Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
            result.send(0, null);
        }
        return null;
    }

    /**
+10 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.OobData;
import android.os.ParcelUuid;
import android.os.ParcelFileDescriptor;
import android.os.ResultReceiver;

/**
 * System private API for talking with the Bluetooth service.
@@ -104,6 +105,15 @@ interface IBluetooth
    void getActivityEnergyInfoFromController();
    BluetoothActivityEnergyInfo reportActivityInfo();

    /**
     * Requests the controller activity info asynchronously.
     * The implementor is expected to reply with the
     * {@link android.bluetooth.BluetoothActivityEnergyInfo} object placed into the Bundle with the
     * key {@link android.os.BatteryStats#RESULT_RECEIVER_CONTROLLER_KEY}.
     * The result code is ignored.
     */
    oneway void requestActivityInfo(in ResultReceiver result);

    void onLeServiceUp();
    void onBrEdrDown();
}
+2 −0
Original line number Diff line number Diff line
@@ -242,6 +242,8 @@ public abstract class BatteryStats implements Parcelable {
    private static final String VIDEO_DATA = "vid";
    private static final String AUDIO_DATA = "aud";

    public static final String RESULT_RECEIVER_CONTROLLER_KEY = "controller_activity";

    private final StringBuilder mFormatBuilder = new StringBuilder(32);
    private final Formatter mFormatter = new Formatter(mFormatBuilder);

+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.os;

import android.annotation.NonNull;
import android.annotation.Nullable;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * Extends ResultReceiver to allow the server end of the ResultReceiver to synchronously wait
 * on the response from the client. This enables an RPC like system but with the ability to
 * timeout and discard late results.
 *
 * NOTE: Can only be used for one response. Subsequent responses on the same instance are ignored.
 * {@hide}
 */
public class SynchronousResultReceiver extends ResultReceiver {
    public static class Result {
        public int resultCode;
        @Nullable public Bundle bundle;

        public Result(int resultCode, @Nullable Bundle bundle) {
            this.resultCode = resultCode;
            this.bundle = bundle;
        }
    }

    private final CompletableFuture<Result> mFuture = new CompletableFuture<>();

    public SynchronousResultReceiver() {
        super((Handler) null);
    }

    @Override
    final protected void onReceiveResult(int resultCode, Bundle resultData) {
        super.onReceiveResult(resultCode, resultData);
        mFuture.complete(new Result(resultCode, resultData));
    }

    /**
     * Blocks waiting for the result from the remote client.
     *
     * @return the Result
     * @throws TimeoutException if the timeout in milliseconds expired.
     */
    public @NonNull Result awaitResult(long timeoutMillis) throws TimeoutException {
        final long deadline = System.currentTimeMillis() + timeoutMillis;
        while (timeoutMillis >= 0) {
            try {
                return mFuture.get(timeoutMillis, TimeUnit.MILLISECONDS);
            } catch (ExecutionException e) {
                // This will NEVER happen.
                throw new AssertionError("Error receiving response", e);
            } catch (InterruptedException e) {
                // The thread was interrupted, try and get the value again, this time
                // with the remaining time until the deadline.
                timeoutMillis -= deadline - System.currentTimeMillis();
            }
        }
        throw new TimeoutException();
    }

}
Loading