Loading telephony/java/android/telephony/TelephonyScanManager.java +67 −17 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); } } Loading @@ -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); } } Loading @@ -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(); } }; } } /** /** Loading @@ -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 * * Loading @@ -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); Loading @@ -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) { Loading @@ -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)); Loading Loading
telephony/java/android/telephony/TelephonyScanManager.java +67 −17 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); } } Loading @@ -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); } } Loading @@ -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(); } }; } } /** /** Loading @@ -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 * * Loading @@ -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); Loading @@ -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) { Loading @@ -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)); Loading