Loading core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -29936,6 +29936,11 @@ package android.os { ctor public OperationCanceledException(String); } public interface OutcomeReceiver<R, E extends java.lang.Throwable> { method public default void onError(@NonNull E); method public void onResult(@NonNull R); } public final class Parcel { method public void appendFrom(android.os.Parcel, int, int); method @Nullable public android.os.IBinder[] createBinderArray(); core/api/system-current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -10356,6 +10356,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean); method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestModemActivityInfo(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.ModemActivityInfo,android.telephony.TelephonyManager.ModemActivityInfoException>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption(); Loading Loading @@ -10528,6 +10529,14 @@ package android.telephony { field public static final int RESULT_SUCCESS = 0; // 0x0 } public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception { method public int getErrorCode(); field public static final int ERROR_INVALID_INFO_RECEIVED = 2; // 0x2 field public static final int ERROR_MODEM_RESPONSE_ERROR = 3; // 0x3 field public static final int ERROR_PHONE_NOT_AVAILABLE = 1; // 0x1 field public static final int ERROR_UNKNOWN = 0; // 0x0 } public final class ThermalMitigationRequest implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.telephony.DataThrottlingRequest getDataThrottlingRequest(); core/api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -1660,6 +1660,7 @@ package android.telephony { method public long getTimestampMillis(); method public long getTransmitDurationMillisAtPowerLevel(int); method @NonNull public android.util.Range<java.lang.Integer> getTransmitPowerRange(int); method public boolean isEmpty(); method public boolean isValid(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR; Loading core/java/android/os/OutcomeReceiver.java 0 → 100644 +42 −0 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 android.os; import android.annotation.NonNull; /** * Callback interface intended for use when an asynchronous operation may result in a failure. * * This interface may be used in cases where an asynchronous API may complete either with a value * or with a {@link Throwable} that indicates an error. * @param <R> The type of the result that's being sent. * @param <E> The type of the {@link Throwable} that contains more information about the error. */ public interface OutcomeReceiver<R, E extends Throwable> { /** * Called when the asynchronous operation succeeds and delivers a result value. * @param result The value delivered by the asynchronous operation. */ void onResult(@NonNull R result); /** * Called when the asynchronous operation fails. The mode of failure is indicated by the * {@link Throwable} passed as an argument to this method. * @param error A subclass of {@link Throwable} with more details about the error that occurred. */ default void onError(@NonNull E error) {} } services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +31 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.Context; import android.net.wifi.WifiManager; import android.os.BatteryStats; import android.os.Bundle; import android.os.OutcomeReceiver; import android.os.Parcelable; import android.os.Process; import android.os.ServiceManager; Loading @@ -40,6 +41,7 @@ import com.android.internal.os.BatteryStatsImpl; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.function.pooled.PooledLambda; import java.util.concurrent.ExecutionException; import libcore.util.EmptyArray; import java.util.concurrent.CompletableFuture; Loading Loading @@ -405,7 +407,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { // We will request data from external processes asynchronously, and wait on a timeout. SynchronousResultReceiver wifiReceiver = null; SynchronousResultReceiver bluetoothReceiver = null; SynchronousResultReceiver modemReceiver = null; CompletableFuture<ModemActivityInfo> modemFuture = CompletableFuture.completedFuture(null); boolean railUpdated = false; if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) { Loading Loading @@ -460,8 +462,22 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } if (mTelephony != null) { modemReceiver = new SynchronousResultReceiver("telephony"); mTelephony.requestModemActivityInfo(modemReceiver); CompletableFuture<ModemActivityInfo> temp = new CompletableFuture<>(); mTelephony.requestModemActivityInfo(Runnable::run, new OutcomeReceiver<ModemActivityInfo, TelephonyManager.ModemActivityInfoException>() { @Override public void onResult(ModemActivityInfo result) { temp.complete(result); } @Override public void onError(TelephonyManager.ModemActivityInfoException e) { Slog.w(TAG, "error reading modem stats:" + e); temp.complete(null); } }); modemFuture = temp; } if (!railUpdated) { synchronized (mStats) { Loading @@ -472,7 +488,17 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver); final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver); ModemActivityInfo modemInfo = null; try { modemInfo = modemFuture.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); } catch (TimeoutException | InterruptedException e) { Slog.w(TAG, "timeout or interrupt reading modem stats: " + e); } catch (ExecutionException e) { Slog.w(TAG, "exception reading modem stats: " + e.getCause()); } final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); synchronized (mStats) { mStats.addHistoryEventLocked( Loading Loading @@ -519,11 +545,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } if (modemInfo != null) { if (modemInfo.isValid()) { mStats.updateMobileRadioState(modemInfo); } else { Slog.w(TAG, "modem info is invalid: " + modemInfo); } } } Loading Loading
core/api/current.txt +5 −0 Original line number Diff line number Diff line Loading @@ -29936,6 +29936,11 @@ package android.os { ctor public OperationCanceledException(String); } public interface OutcomeReceiver<R, E extends java.lang.Throwable> { method public default void onError(@NonNull E); method public void onResult(@NonNull R); } public final class Parcel { method public void appendFrom(android.os.Parcel, int, int); method @Nullable public android.os.IBinder[] createBinderArray();
core/api/system-current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -10356,6 +10356,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean); method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestModemActivityInfo(@NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.telephony.ModemActivityInfo,android.telephony.TelephonyManager.ModemActivityInfoException>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption(); Loading Loading @@ -10528,6 +10529,14 @@ package android.telephony { field public static final int RESULT_SUCCESS = 0; // 0x0 } public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception { method public int getErrorCode(); field public static final int ERROR_INVALID_INFO_RECEIVED = 2; // 0x2 field public static final int ERROR_MODEM_RESPONSE_ERROR = 3; // 0x3 field public static final int ERROR_PHONE_NOT_AVAILABLE = 1; // 0x1 field public static final int ERROR_UNKNOWN = 0; // 0x0 } public final class ThermalMitigationRequest implements android.os.Parcelable { method public int describeContents(); method @Nullable public android.telephony.DataThrottlingRequest getDataThrottlingRequest();
core/api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -1660,6 +1660,7 @@ package android.telephony { method public long getTimestampMillis(); method public long getTransmitDurationMillisAtPowerLevel(int); method @NonNull public android.util.Range<java.lang.Integer> getTransmitPowerRange(int); method public boolean isEmpty(); method public boolean isValid(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR; Loading
core/java/android/os/OutcomeReceiver.java 0 → 100644 +42 −0 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 android.os; import android.annotation.NonNull; /** * Callback interface intended for use when an asynchronous operation may result in a failure. * * This interface may be used in cases where an asynchronous API may complete either with a value * or with a {@link Throwable} that indicates an error. * @param <R> The type of the result that's being sent. * @param <E> The type of the {@link Throwable} that contains more information about the error. */ public interface OutcomeReceiver<R, E extends Throwable> { /** * Called when the asynchronous operation succeeds and delivers a result value. * @param result The value delivered by the asynchronous operation. */ void onResult(@NonNull R result); /** * Called when the asynchronous operation fails. The mode of failure is indicated by the * {@link Throwable} passed as an argument to this method. * @param error A subclass of {@link Throwable} with more details about the error that occurred. */ default void onError(@NonNull E error) {} }
services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +31 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.Context; import android.net.wifi.WifiManager; import android.os.BatteryStats; import android.os.Bundle; import android.os.OutcomeReceiver; import android.os.Parcelable; import android.os.Process; import android.os.ServiceManager; Loading @@ -40,6 +41,7 @@ import com.android.internal.os.BatteryStatsImpl; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.function.pooled.PooledLambda; import java.util.concurrent.ExecutionException; import libcore.util.EmptyArray; import java.util.concurrent.CompletableFuture; Loading Loading @@ -405,7 +407,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { // We will request data from external processes asynchronously, and wait on a timeout. SynchronousResultReceiver wifiReceiver = null; SynchronousResultReceiver bluetoothReceiver = null; SynchronousResultReceiver modemReceiver = null; CompletableFuture<ModemActivityInfo> modemFuture = CompletableFuture.completedFuture(null); boolean railUpdated = false; if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) { Loading Loading @@ -460,8 +462,22 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } if (mTelephony != null) { modemReceiver = new SynchronousResultReceiver("telephony"); mTelephony.requestModemActivityInfo(modemReceiver); CompletableFuture<ModemActivityInfo> temp = new CompletableFuture<>(); mTelephony.requestModemActivityInfo(Runnable::run, new OutcomeReceiver<ModemActivityInfo, TelephonyManager.ModemActivityInfoException>() { @Override public void onResult(ModemActivityInfo result) { temp.complete(result); } @Override public void onError(TelephonyManager.ModemActivityInfoException e) { Slog.w(TAG, "error reading modem stats:" + e); temp.complete(null); } }); modemFuture = temp; } if (!railUpdated) { synchronized (mStats) { Loading @@ -472,7 +488,17 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver); final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver); final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver); ModemActivityInfo modemInfo = null; try { modemInfo = modemFuture.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); } catch (TimeoutException | InterruptedException e) { Slog.w(TAG, "timeout or interrupt reading modem stats: " + e); } catch (ExecutionException e) { Slog.w(TAG, "exception reading modem stats: " + e.getCause()); } final long elapsedRealtime = SystemClock.elapsedRealtime(); final long uptime = SystemClock.uptimeMillis(); synchronized (mStats) { mStats.addHistoryEventLocked( Loading Loading @@ -519,11 +545,7 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { } if (modemInfo != null) { if (modemInfo.isValid()) { mStats.updateMobileRadioState(modemInfo); } else { Slog.w(TAG, "modem info is invalid: " + modemInfo); } } } Loading