Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit e34b1b8

Browse files
Sarah ChinGerrit Code Review
Sarah Chin
authored and
Gerrit Code Review
committed
Merge "Expose requestModemActivityInfo"
2 parents 42d6f9b + 1c8976b commit e34b1b8

File tree

9 files changed

+259
-25
lines changed

9 files changed

+259
-25
lines changed

core/api/current.txt

+5
Original file line numberDiff line numberDiff line change
@@ -29936,6 +29936,11 @@ package android.os {
2993629936
ctor public OperationCanceledException(String);
2993729937
}
2993829938

29939+
public interface OutcomeReceiver<R, E extends java.lang.Throwable> {
29940+
method public default void onError(@NonNull E);
29941+
method public void onResult(@NonNull R);
29942+
}
29943+
2993929944
public final class Parcel {
2994029945
method public void appendFrom(android.os.Parcel, int, int);
2994129946
method @Nullable public android.os.IBinder[] createBinderArray();

core/api/system-current.txt

+9
Original file line numberDiff line numberDiff line change
@@ -10356,6 +10356,7 @@ package android.telephony {
1035610356
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
1035710357
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
1035810358
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);
10359+
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>);
1035910360
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);
1036010361
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
1036110362
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
@@ -10528,6 +10529,14 @@ package android.telephony {
1052810529
field public static final int RESULT_SUCCESS = 0; // 0x0
1052910530
}
1053010531

10532+
public static class TelephonyManager.ModemActivityInfoException extends java.lang.Exception {
10533+
method public int getErrorCode();
10534+
field public static final int ERROR_INVALID_INFO_RECEIVED = 2; // 0x2
10535+
field public static final int ERROR_MODEM_RESPONSE_ERROR = 3; // 0x3
10536+
field public static final int ERROR_PHONE_NOT_AVAILABLE = 1; // 0x1
10537+
field public static final int ERROR_UNKNOWN = 0; // 0x0
10538+
}
10539+
1053110540
public final class ThermalMitigationRequest implements android.os.Parcelable {
1053210541
method public int describeContents();
1053310542
method @Nullable public android.telephony.DataThrottlingRequest getDataThrottlingRequest();

core/api/test-current.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1660,6 +1660,7 @@ package android.telephony {
16601660
method public long getTimestampMillis();
16611661
method public long getTransmitDurationMillisAtPowerLevel(int);
16621662
method @NonNull public android.util.Range<java.lang.Integer> getTransmitPowerRange(int);
1663+
method public boolean isEmpty();
16631664
method public boolean isValid();
16641665
method public void writeToParcel(@NonNull android.os.Parcel, int);
16651666
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ModemActivityInfo> CREATOR;
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2020 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package android.os;
18+
19+
import android.annotation.NonNull;
20+
21+
/**
22+
* Callback interface intended for use when an asynchronous operation may result in a failure.
23+
*
24+
* This interface may be used in cases where an asynchronous API may complete either with a value
25+
* or with a {@link Throwable} that indicates an error.
26+
* @param <R> The type of the result that's being sent.
27+
* @param <E> The type of the {@link Throwable} that contains more information about the error.
28+
*/
29+
public interface OutcomeReceiver<R, E extends Throwable> {
30+
/**
31+
* Called when the asynchronous operation succeeds and delivers a result value.
32+
* @param result The value delivered by the asynchronous operation.
33+
*/
34+
void onResult(@NonNull R result);
35+
36+
/**
37+
* Called when the asynchronous operation fails. The mode of failure is indicated by the
38+
* {@link Throwable} passed as an argument to this method.
39+
* @param error A subclass of {@link Throwable} with more details about the error that occurred.
40+
*/
41+
default void onError(@NonNull E error) {}
42+
}

services/core/java/com/android/server/am/BatteryExternalStatsWorker.java

+31-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.net.wifi.WifiManager;
2323
import android.os.BatteryStats;
2424
import android.os.Bundle;
25+
import android.os.OutcomeReceiver;
2526
import android.os.Parcelable;
2627
import android.os.Process;
2728
import android.os.ServiceManager;
@@ -40,6 +41,7 @@
4041
import com.android.internal.util.FrameworkStatsLog;
4142
import com.android.internal.util.function.pooled.PooledLambda;
4243

44+
import java.util.concurrent.ExecutionException;
4345
import libcore.util.EmptyArray;
4446

4547
import java.util.concurrent.CompletableFuture;
@@ -405,7 +407,7 @@ private void updateExternalStatsLocked(final String reason, int updateFlags,
405407
// We will request data from external processes asynchronously, and wait on a timeout.
406408
SynchronousResultReceiver wifiReceiver = null;
407409
SynchronousResultReceiver bluetoothReceiver = null;
408-
SynchronousResultReceiver modemReceiver = null;
410+
CompletableFuture<ModemActivityInfo> modemFuture = CompletableFuture.completedFuture(null);
409411
boolean railUpdated = false;
410412

411413
if ((updateFlags & BatteryStatsImpl.ExternalStatsSync.UPDATE_WIFI) != 0) {
@@ -460,8 +462,22 @@ public void execute(Runnable runnable) {
460462
}
461463

462464
if (mTelephony != null) {
463-
modemReceiver = new SynchronousResultReceiver("telephony");
464-
mTelephony.requestModemActivityInfo(modemReceiver);
465+
CompletableFuture<ModemActivityInfo> temp = new CompletableFuture<>();
466+
mTelephony.requestModemActivityInfo(Runnable::run,
467+
new OutcomeReceiver<ModemActivityInfo,
468+
TelephonyManager.ModemActivityInfoException>() {
469+
@Override
470+
public void onResult(ModemActivityInfo result) {
471+
temp.complete(result);
472+
}
473+
474+
@Override
475+
public void onError(TelephonyManager.ModemActivityInfoException e) {
476+
Slog.w(TAG, "error reading modem stats:" + e);
477+
temp.complete(null);
478+
}
479+
});
480+
modemFuture = temp;
465481
}
466482
if (!railUpdated) {
467483
synchronized (mStats) {
@@ -472,7 +488,17 @@ public void execute(Runnable runnable) {
472488

473489
final WifiActivityEnergyInfo wifiInfo = awaitControllerInfo(wifiReceiver);
474490
final BluetoothActivityEnergyInfo bluetoothInfo = awaitControllerInfo(bluetoothReceiver);
475-
final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
491+
ModemActivityInfo modemInfo = null;
492+
try {
493+
modemInfo = modemFuture.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
494+
TimeUnit.MILLISECONDS);
495+
} catch (TimeoutException | InterruptedException e) {
496+
Slog.w(TAG, "timeout or interrupt reading modem stats: " + e);
497+
} catch (ExecutionException e) {
498+
Slog.w(TAG, "exception reading modem stats: " + e.getCause());
499+
}
500+
final long elapsedRealtime = SystemClock.elapsedRealtime();
501+
final long uptime = SystemClock.uptimeMillis();
476502

477503
synchronized (mStats) {
478504
mStats.addHistoryEventLocked(
@@ -519,11 +545,7 @@ public void execute(Runnable runnable) {
519545
}
520546

521547
if (modemInfo != null) {
522-
if (modemInfo.isValid()) {
523-
mStats.updateMobileRadioState(modemInfo);
524-
} else {
525-
Slog.w(TAG, "modem info is invalid: " + modemInfo);
526-
}
548+
mStats.updateMobileRadioState(modemInfo);
527549
}
528550
}
529551

services/core/java/com/android/server/am/BatteryStatsService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,7 @@ public void noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info) {
12081208
public void noteModemControllerActivity(ModemActivityInfo info) {
12091209
enforceCallingPermission();
12101210

1211-
if (info == null || !info.isValid()) {
1211+
if (info == null) {
12121212
Slog.e(TAG, "invalid modem data given: " + info);
12131213
return;
12141214
}

services/core/java/com/android/server/stats/pull/StatsPullAtomService.java

+30-3
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
import android.os.IStoraged;
103103
import android.os.IThermalEventListener;
104104
import android.os.IThermalService;
105+
import android.os.OutcomeReceiver;
105106
import android.os.ParcelFileDescriptor;
106107
import android.os.Parcelable;
107108
import android.os.RemoteException;
@@ -172,6 +173,7 @@
172173
import com.android.server.storage.DiskStatsFileLogger;
173174
import com.android.server.storage.DiskStatsLoggingService;
174175

176+
import java.util.concurrent.ExecutionException;
175177
import libcore.io.IoUtils;
176178

177179
import org.json.JSONArray;
@@ -1731,9 +1733,34 @@ private void registerModemActivityInfo() {
17311733
int pullModemActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
17321734
long token = Binder.clearCallingIdentity();
17331735
try {
1734-
SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
1735-
mTelephony.requestModemActivityInfo(modemReceiver);
1736-
final ModemActivityInfo modemInfo = awaitControllerInfo(modemReceiver);
1736+
CompletableFuture<ModemActivityInfo> modemFuture = new CompletableFuture<>();
1737+
mTelephony.requestModemActivityInfo(Runnable::run,
1738+
new OutcomeReceiver<ModemActivityInfo,
1739+
TelephonyManager.ModemActivityInfoException>() {
1740+
@Override
1741+
public void onResult(ModemActivityInfo result) {
1742+
modemFuture.complete(result);
1743+
}
1744+
1745+
@Override
1746+
public void onError(TelephonyManager.ModemActivityInfoException e) {
1747+
Slog.w(TAG, "error reading modem stats:" + e);
1748+
modemFuture.complete(null);
1749+
}
1750+
});
1751+
1752+
ModemActivityInfo modemInfo;
1753+
try {
1754+
modemInfo = modemFuture.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
1755+
TimeUnit.MILLISECONDS);
1756+
} catch (TimeoutException | InterruptedException e) {
1757+
Slog.w(TAG, "timeout or interrupt reading modem stats: " + e);
1758+
return StatsManager.PULL_SKIP;
1759+
} catch (ExecutionException e) {
1760+
Slog.w(TAG, "exception reading modem stats: " + e.getCause());
1761+
return StatsManager.PULL_SKIP;
1762+
}
1763+
17371764
if (modemInfo == null) {
17381765
return StatsManager.PULL_SKIP;
17391766
}

telephony/java/android/telephony/ModemActivityInfo.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ public String toString() {
131131
+ " mTimestamp=" + mTimestamp
132132
+ " mSleepTimeMs=" + mSleepTimeMs
133133
+ " mIdleTimeMs=" + mIdleTimeMs
134-
+ " mTxTimeMs[]=" + mTxTimeMs
134+
+ " mTxTimeMs[]=" + Arrays.toString(mTxTimeMs)
135135
+ " mRxTimeMs=" + mRxTimeMs
136136
+ "}";
137137
}
@@ -320,8 +320,6 @@ public void setReceiveTimeMillis(long receiveTimeMillis) {
320320
*
321321
* @return {@code true} if this {@link ModemActivityInfo} record is valid,
322322
* {@code false} otherwise.
323-
* TODO: remove usages of this outside Telephony by always returning a valid (or null) result
324-
* from telephony.
325323
* @hide
326324
*/
327325
@TestApi
@@ -332,7 +330,9 @@ public boolean isValid() {
332330
&& (getReceiveTimeMillis() >= 0) && !isEmpty());
333331
}
334332

335-
private boolean isEmpty() {
333+
/** @hide */
334+
@TestApi
335+
public boolean isEmpty() {
336336
boolean isTxPowerEmpty = mTxTimeMs == null || mTxTimeMs.length == 0
337337
|| Arrays.stream(mTxTimeMs).allMatch((i) -> i == 0);
338338

0 commit comments

Comments
 (0)