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

Commit ed7cf992 authored by Nathan Harold's avatar Nathan Harold Committed by Gerrit Code Review
Browse files

Merge "Abort NetworkScans when Phone Process Crashes"

parents cbbd9536 e9d38721
Loading
Loading
Loading
Loading
+67 −17
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager;
import android.util.SparseArray;
import android.util.SparseArray;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephony;
import com.android.telephony.Rlog;
import com.android.telephony.Rlog;


@@ -56,6 +57,8 @@ public final class TelephonyScanManager {
    public static final int CALLBACK_SCAN_COMPLETE = 3;
    public static final int CALLBACK_SCAN_COMPLETE = 3;
    /** @hide */
    /** @hide */
    public static final int CALLBACK_RESTRICTED_SCAN_RESULTS = 4;
    public static final int CALLBACK_RESTRICTED_SCAN_RESULTS = 4;
    /** @hide */
    public static final int CALLBACK_TELEPHONY_DIED = 5;


    /** @hide */
    /** @hide */
    public static final int INVALID_SCAN_ID = -1;
    public static final int INVALID_SCAN_ID = -1;
@@ -104,17 +107,44 @@ public final class TelephonyScanManager {
    }
    }


    private final Looper mLooper;
    private final Looper mLooper;
    private final Handler mHandler;
    private final Messenger mMessenger;
    private final Messenger mMessenger;
    private final SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>();
    private final SparseArray<NetworkScanInfo> mScanInfo = new SparseArray<NetworkScanInfo>();
    private final Binder.DeathRecipient mDeathRecipient;


    public TelephonyScanManager() {
    public TelephonyScanManager() {
        HandlerThread thread = new HandlerThread(TAG);
        HandlerThread thread = new HandlerThread(TAG);
        thread.start();
        thread.start();
        mLooper = thread.getLooper();
        mLooper = thread.getLooper();
        mMessenger = new Messenger(new Handler(mLooper) {
        mHandler = new Handler(mLooper) {
            @Override
            @Override
            public void handleMessage(Message message) {
            public void handleMessage(Message message) {
                checkNotNull(message, "message cannot be null");
                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;
                NetworkScanInfo nsi;
                synchronized (mScanInfo) {
                synchronized (mScanInfo) {
                    nsi = mScanInfo.get(message.arg2);
                    nsi = mScanInfo.get(message.arg2);
@@ -159,6 +189,9 @@ public final class TelephonyScanManager {
                                Rlog.d(TAG, "onError: " + errorCode);
                                Rlog.d(TAG, "onError: " + errorCode);
                                callback.onError(errorCode);
                                callback.onError(errorCode);
                            });
                            });
                            synchronized (mScanInfo) {
                                mScanInfo.remove(message.arg2);
                            }
                        } catch (Exception e) {
                        } catch (Exception e) {
                            Rlog.e(TAG, "Exception in networkscan callback onError", e);
                            Rlog.e(TAG, "Exception in networkscan callback onError", e);
                        }
                        }
@@ -169,7 +202,9 @@ public final class TelephonyScanManager {
                                Rlog.d(TAG, "onComplete");
                                Rlog.d(TAG, "onComplete");
                                callback.onComplete();
                                callback.onComplete();
                            });
                            });
                            synchronized (mScanInfo) {
                                mScanInfo.remove(message.arg2);
                                mScanInfo.remove(message.arg2);
                            }
                        } catch (Exception e) {
                        } catch (Exception e) {
                            Rlog.e(TAG, "Exception in networkscan callback onComplete", e);
                            Rlog.e(TAG, "Exception in networkscan callback onComplete", e);
                        }
                        }
@@ -179,7 +214,14 @@ public final class TelephonyScanManager {
                        break;
                        break;
                }
                }
            }
            }
        });
        };
        mMessenger = new Messenger(mHandler);
        mDeathRecipient = new Binder.DeathRecipient() {
            @Override
            public void binderDied() {
                mHandler.obtainMessage(CALLBACK_TELEPHONY_DIED).sendToTarget();
            }
        };
    }
    }


    /**
    /**
@@ -190,7 +232,7 @@ public final class TelephonyScanManager {
     *
     *
     * <p>
     * <p>
     * Requires Permission:
     * 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}
     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
     * Or the calling app has carrier privileges. @see #hasCarrierPrivileges
     *
     *
@@ -203,9 +245,9 @@ public final class TelephonyScanManager {
            NetworkScanRequest request, Executor executor, NetworkScanCallback callback,
            NetworkScanRequest request, Executor executor, NetworkScanCallback callback,
            String callingPackage, String callingFeatureId) {
            String callingPackage, String callingFeatureId) {
        try {
        try {
            ITelephony telephony = getITelephony();
            final ITelephony telephony = getITelephony();
            if (telephony != null) {
            if (telephony == null) return null;
                synchronized (mScanInfo) {

            int scanId = telephony.requestNetworkScan(
            int scanId = telephony.requestNetworkScan(
                    subId, request, mMessenger, new Binder(), callingPackage,
                    subId, request, mMessenger, new Binder(), callingPackage,
                    callingFeatureId);
                    callingFeatureId);
@@ -213,10 +255,17 @@ public final class TelephonyScanManager {
                Rlog.e(TAG, "Failed to initiate network scan");
                Rlog.e(TAG, "Failed to initiate network scan");
                return null;
                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);
                saveScanInfo(scanId, request, executor, callback);
                return new NetworkScan(scanId, subId);
                return new NetworkScan(scanId, subId);
            }
            }
            }
        } catch (RemoteException ex) {
        } catch (RemoteException ex) {
            Rlog.e(TAG, "requestNetworkScan RemoteException", ex);
            Rlog.e(TAG, "requestNetworkScan RemoteException", ex);
        } catch (NullPointerException ex) {
        } catch (NullPointerException ex) {
@@ -225,6 +274,7 @@ public final class TelephonyScanManager {
        return null;
        return null;
    }
    }


    @GuardedBy("mScanInfo")
    private void saveScanInfo(
    private void saveScanInfo(
            int id, NetworkScanRequest request, Executor executor, NetworkScanCallback callback) {
            int id, NetworkScanRequest request, Executor executor, NetworkScanCallback callback) {
        mScanInfo.put(id, new NetworkScanInfo(request, executor, callback));
        mScanInfo.put(id, new NetworkScanInfo(request, executor, callback));