diff options
Diffstat (limited to 'src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java')
-rw-r--r-- | src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java | 170 |
1 files changed, 123 insertions, 47 deletions
diff --git a/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java index 9a75b43aa4..f5cf9501d2 100644 --- a/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java +++ b/src/java/com/android/internal/telephony/domainselection/DomainSelectionConnection.java @@ -21,10 +21,13 @@ import android.annotation.Nullable; import android.os.AsyncResult; import android.os.CancellationSignal; import android.os.Handler; -import android.os.HandlerThread; import android.os.Looper; import android.os.Message; +import android.telephony.AccessNetworkConstants; +import android.telephony.AccessNetworkConstants.AccessNetworkType; import android.telephony.AccessNetworkConstants.RadioAccessNetworkType; +import android.telephony.AccessNetworkConstants.TransportType; +import android.telephony.Annotation.ApnType; import android.telephony.Annotation.DisconnectCauses; import android.telephony.DomainSelectionService; import android.telephony.DomainSelectionService.EmergencyScanType; @@ -33,19 +36,19 @@ import android.telephony.EmergencyRegResult; import android.telephony.NetworkRegistrationInfo; import android.telephony.TransportSelectorCallback; import android.telephony.WwanSelectorCallback; +import android.telephony.data.ApnSetting; import android.util.LocalLog; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AndroidFuture; import com.android.internal.telephony.Phone; +import com.android.internal.telephony.data.AccessNetworksManager.QualifiedNetworks; import com.android.internal.telephony.util.TelephonyUtils; import java.io.PrintWriter; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.concurrent.Executors; import java.util.function.Consumer; @@ -74,42 +77,63 @@ public class DomainSelectionConnection { private final class TransportSelectorCallbackWrapper implements TransportSelectorCallback { @Override public void onCreated(@NonNull DomainSelector selector) { - mDomainSelector = selector; - DomainSelectionConnection.this.onCreated(); + synchronized (mLock) { + mDomainSelector = selector; + if (mDisposed) { + mDomainSelector.cancelSelection(); + return; + } + DomainSelectionConnection.this.onCreated(); + } } @Override public void onWlanSelected(boolean useEmergencyPdn) { - DomainSelectionConnection.this.onWlanSelected(useEmergencyPdn); + synchronized (mLock) { + if (mDisposed) return; + DomainSelectionConnection.this.onWlanSelected(useEmergencyPdn); + } } @Override public @NonNull WwanSelectorCallback onWwanSelected() { - if (mWwanSelectorCallback == null) { - mWwanSelectorCallback = new WwanSelectorCallbackWrapper(); + synchronized (mLock) { + if (mWwanSelectorCallback == null) { + mWwanSelectorCallback = new WwanSelectorCallbackWrapper(); + } + if (mDisposed) { + return mWwanSelectorCallback; + } + DomainSelectionConnection.this.onWwanSelected(); + return mWwanSelectorCallback; } - DomainSelectionConnection.this.onWwanSelected(); - return mWwanSelectorCallback; } @Override public void onWwanSelected(final Consumer<WwanSelectorCallback> consumer) { - if (mWwanSelectorCallback == null) { - mWwanSelectorCallback = new WwanSelectorCallbackWrapper(); + synchronized (mLock) { + if (mDisposed) return; + if (mWwanSelectorCallback == null) { + mWwanSelectorCallback = new WwanSelectorCallbackWrapper(); + } + initHandler(); + mHandler.post(() -> { + synchronized (mLock) { + if (mDisposed) return; + DomainSelectionConnection.this.onWwanSelected(); + consumer.accept(mWwanSelectorCallback); + } + }); } - if (mWwanSelectedExecutor == null) { - mWwanSelectedExecutor = Executors.newSingleThreadExecutor(); - } - mWwanSelectedExecutor.execute(() -> { - DomainSelectionConnection.this.onWwanSelected(); - consumer.accept(mWwanSelectorCallback); - }); } @Override public void onSelectionTerminated(int cause) { - DomainSelectionConnection.this.onSelectionTerminated(cause); - dispose(); + synchronized (mLock) { + if (mDisposed) return; + DomainSelectionConnection.this.onSelectionTerminated(cause); + dispose(); + } } } @@ -120,22 +144,38 @@ public class DomainSelectionConnection { public void onRequestEmergencyNetworkScan(@NonNull List<Integer> preferredNetworks, @EmergencyScanType int scanType, @NonNull CancellationSignal signal, @NonNull Consumer<EmergencyRegResult> consumer) { - if (signal != null) signal.setOnCancelListener(this); - mResultCallback = consumer; - initHandler(); - DomainSelectionConnection.this.onRequestEmergencyNetworkScan( - preferredNetworks.stream().mapToInt(Integer::intValue).toArray(), scanType); + synchronized (mLock) { + if (mDisposed) return; + if (signal != null) signal.setOnCancelListener(this); + mResultCallback = consumer; + initHandler(); + mHandler.post(() -> { + synchronized (mLock) { + DomainSelectionConnection.this.onRequestEmergencyNetworkScan( + preferredNetworks.stream().mapToInt(Integer::intValue).toArray(), + scanType); + } + }); + } } @Override public void onDomainSelected(@NetworkRegistrationInfo.Domain int domain, boolean useEmergencyPdn) { - DomainSelectionConnection.this.onDomainSelected(domain, useEmergencyPdn); + synchronized (mLock) { + if (mDisposed) return; + DomainSelectionConnection.this.onDomainSelected(domain, useEmergencyPdn); + } } @Override public void onCancel() { - DomainSelectionConnection.this.onCancel(); + synchronized (mLock) { + if (mDisposed || mHandler == null) return; + mHandler.post(() -> { + DomainSelectionConnection.this.onCancel(); + }); + } } } @@ -156,10 +196,15 @@ public class DomainSelectionConnection { if (DBG) logd("EVENT_EMERGENCY_NETWORK_SCAN_RESULT result=" + regResult); CompletableFuture.runAsync( () -> mResultCallback.accept(regResult), - mController.getDomainSelectionServiceExecutor()).join(); + mController.getDomainSelectionServiceExecutor()); break; case EVENT_QUALIFIED_NETWORKS_CHANGED: - onQualifiedNetworksChanged(); + ar = (AsyncResult) msg.obj; + if (ar == null || ar.result == null) { + loge("handleMessage EVENT_QUALIFIED_NETWORKS_CHANGED null result"); + break; + } + onQualifiedNetworksChanged((List<QualifiedNetworks>) ar.result); break; default: loge("handleMessage unexpected msg=" + msg.what); @@ -170,6 +215,8 @@ public class DomainSelectionConnection { protected String mTag = "DomainSelectionConnection"; + private boolean mDisposed = false; + private final Object mLock = new Object(); private final LocalLog mLocalLog = new LocalLog(30); private final @NonNull TransportSelectorCallback mTransportSelectorCallback; @@ -196,15 +243,13 @@ public class DomainSelectionConnection { /** The attributes required to determine the domain. */ private @Nullable DomainSelectionService.SelectionAttributes mSelectionAttributes; - private @Nullable Looper mLooper; + private final @NonNull Looper mLooper; protected @Nullable DomainSelectionConnectionHandler mHandler; private boolean mRegisteredRegistrant; private boolean mIsWaitingForScanResult; private @NonNull AndroidFuture<Integer> mOnComplete; - private @Nullable Executor mWwanSelectedExecutor; - /** * Creates an instance. * @@ -220,6 +265,7 @@ public class DomainSelectionConnection { mPhone = phone; mSelectorType = selectorType; mIsEmergency = isEmergency; + mLooper = Looper.getMainLooper(); mTransportSelectorCallback = new TransportSelectorCallbackWrapper(); mOnComplete = new AndroidFuture<>(); @@ -323,6 +369,8 @@ public class DomainSelectionConnection { public void onRequestEmergencyNetworkScan( @NonNull @RadioAccessNetworkType int[] preferredNetworks, @EmergencyScanType int scanType) { + if (mHandler == null) return; + // Can be overridden if required if (!mRegisteredRegistrant) { mPhone.registerForEmergencyNetworkScan(mHandler, @@ -376,9 +424,12 @@ public class DomainSelectionConnection { * to clean up all ongoing operations with the framework. */ public void cancelSelection() { - if (mDomainSelector == null) return; - mDomainSelector.cancelSelection(); - dispose(); + synchronized (mLock) { + if (mDomainSelector != null) { + mDomainSelector.cancelSelection(); + } + dispose(); + } } /** @@ -400,9 +451,12 @@ public class DomainSelectionConnection { * Finishes the selection procedure and cleans everything up. */ public void finishSelection() { - if (mDomainSelector == null) return; - mDomainSelector.finishSelection(); - dispose(); + synchronized (mLock) { + if (mDomainSelector != null) { + mDomainSelector.finishSelection(); + } + dispose(); + } } /** Indicates that the service connection has been removed. */ @@ -412,30 +466,25 @@ public class DomainSelectionConnection { } private void dispose() { + mDisposed = true; if (mRegisteredRegistrant) { mPhone.unregisterForEmergencyNetworkScan(mHandler); mRegisteredRegistrant = false; } onCancel(true); mController.removeConnection(this); - if (mLooper != null) mLooper.quitSafely(); - mLooper = null; + if (mHandler != null) mHandler.removeCallbacksAndMessages(null); mHandler = null; } protected void initHandler() { - if (mLooper == null) { - HandlerThread handlerThread = new HandlerThread(mTag); - handlerThread.start(); - mLooper = handlerThread.getLooper(); - } if (mHandler == null) mHandler = new DomainSelectionConnectionHandler(mLooper); } /** * Notifies the change of qualified networks. */ - protected void onQualifiedNetworksChanged() { + protected void onQualifiedNetworksChanged(List<QualifiedNetworks> networksList) { if (mIsEmergency && (mSelectorType == DomainSelectionService.SELECTOR_TYPE_CALLING)) { // DomainSelectionConnection for emergency calls shall override this. @@ -445,6 +494,33 @@ public class DomainSelectionConnection { } /** + * Get the preferred transport. + * + * @param apnType APN type. + * @return The preferred transport. + */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) + public int getPreferredTransport(@ApnType int apnType, + List<QualifiedNetworks> networksList) { + for (QualifiedNetworks networks : networksList) { + if (networks.qualifiedNetworks.length > 0) { + if (networks.apnType == apnType) { + return getTransportFromAccessNetwork(networks.qualifiedNetworks[0]); + } + } + } + + loge("getPreferredTransport no network found for " + ApnSetting.getApnTypeString(apnType)); + return AccessNetworkConstants.TRANSPORT_TYPE_WWAN; + } + + private static @TransportType int getTransportFromAccessNetwork(int accessNetwork) { + return accessNetwork == AccessNetworkType.IWLAN + ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN + : AccessNetworkConstants.TRANSPORT_TYPE_WWAN; + } + + /** * Dumps local log. */ public void dump(@NonNull PrintWriter printWriter) { |