summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nathan Harold <nharold@google.com> 2020-06-26 22:40:21 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2020-06-26 22:40:21 +0000
commit5bbd69c45f6a1c1919bb91ba962d18ecfba712a4 (patch)
tree738ffa97734721e609cdd16e62f38ac252f7ce3a
parenta01d41d37dbb559d59c567ac1faca29fec319cfe (diff)
parente78ea75efef20bed0c91bff9a766db069f406f92 (diff)
Merge "Abort NetworkScans when Phone Process Crashes" am: ed7cf992a0 am: e78ea75efe
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1312940 Change-Id: Ie2ea3b06adb42f8ea7f595907950a5019f7cd5c5
-rw-r--r--telephony/java/android/telephony/TelephonyScanManager.java84
1 files changed, 67 insertions, 17 deletions
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index cdff651c9c3d..e890acb36b48 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -30,6 +30,7 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.telephony.ITelephony;
import com.android.telephony.Rlog;
@@ -55,6 +56,8 @@ public final class TelephonyScanManager {
public static final int CALLBACK_SCAN_COMPLETE = 3;
/** @hide */
public static final int CALLBACK_RESTRICTED_SCAN_RESULTS = 4;
+ /** @hide */
+ public static final int CALLBACK_TELEPHONY_DIED = 5;
/** @hide */
public static final int INVALID_SCAN_ID = -1;
@@ -103,17 +106,44 @@ public final class TelephonyScanManager {
}
private final Looper mLooper;
+ private final Handler mHandler;
private final Messenger mMessenger;
private final SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>();
+ private final Binder.DeathRecipient mDeathRecipient;
public TelephonyScanManager() {
HandlerThread thread = new HandlerThread(TAG);
thread.start();
mLooper = thread.getLooper();
- mMessenger = new Messenger(new Handler(mLooper) {
+ mHandler = new Handler(mLooper) {
@Override
public void handleMessage(Message message) {
checkNotNull(message, "message cannot be null");
+ if (message.what == CALLBACK_TELEPHONY_DIED) {
+ // If there are no objects in mScanInfo then binder death will simply return.
+ synchronized (mScanInfo) {
+ for (int i = 0; i < mScanInfo.size(); i++) {
+ NetworkScanInfo nsi = mScanInfo.valueAt(i);
+ // At this point we go into panic mode and ignore errors that would
+ // normally stop the show in order to try and clean up as gracefully
+ // as possible.
+ if (nsi == null) continue; // shouldn't be possible
+ Executor e = nsi.mExecutor;
+ NetworkScanCallback cb = nsi.mCallback;
+ if (e == null || cb == null) continue;
+ try {
+ e.execute(
+ () -> cb.onError(NetworkScan.ERROR_MODEM_UNAVAILABLE));
+ } catch (java.util.concurrent.RejectedExecutionException ignore) {
+ // ignore so that we can continue
+ }
+ }
+
+ mScanInfo.clear();
+ }
+ return;
+ }
+
NetworkScanInfo nsi;
synchronized (mScanInfo) {
nsi = mScanInfo.get(message.arg2);
@@ -158,6 +188,9 @@ public final class TelephonyScanManager {
Rlog.d(TAG, "onError: " + errorCode);
callback.onError(errorCode);
});
+ synchronized (mScanInfo) {
+ mScanInfo.remove(message.arg2);
+ }
} catch (Exception e) {
Rlog.e(TAG, "Exception in networkscan callback onError", e);
}
@@ -168,7 +201,9 @@ public final class TelephonyScanManager {
Rlog.d(TAG, "onComplete");
callback.onComplete();
});
- mScanInfo.remove(message.arg2);
+ synchronized (mScanInfo) {
+ mScanInfo.remove(message.arg2);
+ }
} catch (Exception e) {
Rlog.e(TAG, "Exception in networkscan callback onComplete", e);
}
@@ -178,7 +213,14 @@ public final class TelephonyScanManager {
break;
}
}
- });
+ };
+ mMessenger = new Messenger(mHandler);
+ mDeathRecipient = new Binder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ mHandler.obtainMessage(CALLBACK_TELEPHONY_DIED).sendToTarget();
+ }
+ };
}
/**
@@ -189,7 +231,7 @@ public final class TelephonyScanManager {
*
* <p>
* Requires Permission:
- * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
* Or the calling app has carrier privileges. @see #hasCarrierPrivileges
*
@@ -204,19 +246,26 @@ public final class TelephonyScanManager {
NetworkScanRequest request, Executor executor, NetworkScanCallback callback,
String callingPackage, @Nullable String callingFeatureId) {
try {
- ITelephony telephony = getITelephony();
- if (telephony != null) {
- synchronized (mScanInfo) {
- int scanId = telephony.requestNetworkScan(
- subId, request, mMessenger, new Binder(), callingPackage,
- callingFeatureId);
- if (scanId == INVALID_SCAN_ID) {
- Rlog.e(TAG, "Failed to initiate network scan");
- return null;
- }
- saveScanInfo(scanId, request, executor, callback);
- return new NetworkScan(scanId, subId);
- }
+ final ITelephony telephony = getITelephony();
+ if (telephony == null) return null;
+
+ int scanId = telephony.requestNetworkScan(
+ subId, request, mMessenger, new Binder(), callingPackage,
+ callingFeatureId);
+ if (scanId == INVALID_SCAN_ID) {
+ Rlog.e(TAG, "Failed to initiate network scan");
+ return null;
+ }
+ synchronized (mScanInfo) {
+ // We link to death whenever a scan is started to ensure that we are linked
+ // at the point that phone process death might matter.
+ // We never unlink because:
+ // - Duplicate links to death with the same callback do not result in
+ // extraneous callbacks (the tracking de-dupes).
+ // - Receiving binderDeath() when no scans are active is a no-op.
+ telephony.asBinder().linkToDeath(mDeathRecipient, 0);
+ saveScanInfo(scanId, request, executor, callback);
+ return new NetworkScan(scanId, subId);
}
} catch (RemoteException ex) {
Rlog.e(TAG, "requestNetworkScan RemoteException", ex);
@@ -226,6 +275,7 @@ public final class TelephonyScanManager {
return null;
}
+ @GuardedBy("mScanInfo")
private void saveScanInfo(
int id, NetworkScanRequest request, Executor executor, NetworkScanCallback callback) {
mScanInfo.put(id, new NetworkScanInfo(request, executor, callback));