Merge "Correct grammar for "unable to merge" error message."
diff --git a/res/values/config.xml b/res/values/config.xml
index 855fa92..5ad369f 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -137,7 +137,7 @@
<!-- DEPRECATED: Use CarrierConfigManager#KEY_PREFER_2G_BOOL -->
<bool name="config_prefer_2g" translatable="false">true</bool>
<!-- Show enabled lte option for lte device -->
- <bool name="config_enabled_lte" translatable="false">false</bool>
+ <bool name="config_enabled_lte" translatable="false">true</bool>
<!-- Show enabled tdscdma option for device -->
<bool name="config_support_tdscdma" translatable="false">false</bool>
<!-- Show enabled tdscdma option for device when connect roaming network -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9068c13..7fe534c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1804,4 +1804,17 @@
<!-- Message displayed to the user to indicate that a held call has been released /
disconnected. -->
<string name="supp_service_held_call_released">Held call has been released.</string>
+
+ <!-- In-call screen: error message shown when the user has attempted to place a new outgoing
+ call, but there is already a call in dialing state. -->
+ <string name="callFailed_already_dialing">Cannot place a call as another outgoing call is already dialing.</string>
+ <!-- In-call screen: error message shown when the user has attempted to place a new outgoing
+ call while there is already a call in ringing state. -->
+ <string name="callFailed_already_ringing">Cannot place a call as there is an unanswered incoming call. Answer or reject the incoming call prior to placing a new call.</string>
+ <!-- In-call screen: error message shown when the user attempts to place a call, but calling has
+ been disabled using a debug property. -->
+ <string name="callFailed_calling_disabled">Cannot place a call as calling has been disabled using the ro.telephony.disable-call system property.</string>
+ <!-- In-call screen: error message shown when the user attempts to place a call, but calling has
+ been disabled using a debug property. -->
+ <string name="callFailed_too_many_calls">Cannot place a call a there are already two calls in progress. Disconnect one of the calls or merge them into a conference prior to placing a new call.</string>
</resources>
diff --git a/src/com/android/phone/GsmUmtsOptions.java b/src/com/android/phone/GsmUmtsOptions.java
index a3f5cfb..35aab34 100644
--- a/src/com/android/phone/GsmUmtsOptions.java
+++ b/src/com/android/phone/GsmUmtsOptions.java
@@ -28,7 +28,6 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.settingslib.RestrictedLockUtils;
@@ -54,7 +53,7 @@
private PreferenceScreen mPrefScreen;
public GsmUmtsOptions(PreferenceFragment prefFragment, PreferenceScreen prefScreen,
- final int subId, INetworkQueryService queryService) {
+ final int subId) {
final Context context = prefFragment.getContext();
mPrefFragment = prefFragment;
mPrefScreen = prefScreen;
@@ -68,19 +67,17 @@
mNetworkOperator.initialize();
- update(subId, queryService);
+ update(subId);
}
- // Unlike mPrefFragment or mPrefScreen, subId or queryService may change during lifecycle of
- // GsmUmtsOptions. When that happens, we update GsmUmtsOptions with new parameters.
- protected void update(final int subId, INetworkQueryService queryService) {
+ // Unlike mPrefFragment or mPrefScreen, subId may change during lifecycle of GsmUmtsOptions.
+ // When that happens, we update GsmUmtsOptions with new parameters.
+ protected void update(final int subId) {
boolean addAPNExpand = true;
boolean addNetworkOperatorsCategory = true;
boolean addCarrierSettings = true;
final TelephonyManager telephonyManager = TelephonyManager.from(mPrefFragment.getContext())
.createForSubscriptionId(subId);
- Phone phone = PhoneGlobals.getPhone(subId);
- if (phone == null) return;
if (telephonyManager.getPhoneType() != PhoneConstants.PHONE_TYPE_GSM) {
log("Not a GSM phone");
addAPNExpand = false;
@@ -104,7 +101,7 @@
}
if (carrierConfig.getBoolean(CarrierConfigManager.KEY_CSP_ENABLED_BOOL)) {
- if (phone.isCspPlmnEnabled()) {
+ if (telephonyManager.isManualNetworkSelectionAllowed()) {
log("[CSP] Enabling Operator Selection menu.");
mNetworkOperator.setEnabled(true);
} else {
@@ -151,7 +148,7 @@
if (addNetworkOperatorsCategory) {
mPrefScreen.addPreference(mNetworkOperator);
- mNetworkOperator.update(subId, queryService);
+ mNetworkOperator.update(subId);
} else {
mPrefScreen.removePreference(mNetworkOperator);
}
diff --git a/src/com/android/phone/MobileDataPreference.java b/src/com/android/phone/MobileDataPreference.java
index 4e82f20..e1ceab0 100644
--- a/src/com/android/phone/MobileDataPreference.java
+++ b/src/com/android/phone/MobileDataPreference.java
@@ -63,6 +63,11 @@
super(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
}
+ // Must be called to avoid binder leakage.
+ void dispose() {
+ mListener.setListener(false, mSubId, getContext());
+ }
+
@Override
protected void onRestoreInstanceState(Parcelable s) {
CellDataState state = (CellDataState) s;
diff --git a/src/com/android/phone/MobileNetworkSettings.java b/src/com/android/phone/MobileNetworkSettings.java
index 148d1ad..3d37c4d 100644
--- a/src/com/android/phone/MobileNetworkSettings.java
+++ b/src/com/android/phone/MobileNetworkSettings.java
@@ -24,12 +24,10 @@
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
@@ -38,7 +36,6 @@
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.SystemProperties;
@@ -469,53 +466,6 @@
private final PhoneCallStateListener mPhoneStateListener = new PhoneCallStateListener();
- /**
- * Service connection code for the NetworkQueryService.
- * Handles the work of binding to a local object so that we can make
- * the appropriate service calls.
- */
-
- /** Local service interface */
- private INetworkQueryService mNetworkQueryService = null;
-
- private void setNetworkQueryService() {
- mButtonNetworkSelect = (NetworkSelectListPreference) getPreferenceScreen()
- .findPreference(NetworkOperators.BUTTON_NETWORK_SELECT_KEY);
- if (mButtonNetworkSelect != null) {
- mButtonNetworkSelect.setNetworkQueryService(mNetworkQueryService);
- }
-
- }
- /** Service connection */
- private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
-
- /** Handle the task of binding the local object to the service */
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) log("connection created, binding local service.");
- mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
- setNetworkQueryService();
- }
-
- /** Handle the task of cleaning up the local binding */
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) log("connection disconnected, cleaning local binding.");
- mNetworkQueryService = null;
- setNetworkQueryService();
- }
- };
-
- private void bindNetworkQueryService() {
- getContext().startService(new Intent(getContext(), NetworkQueryService.class));
- getContext().bindService(new Intent(getContext(), NetworkQueryService.class).setAction(
- NetworkQueryService.ACTION_LOCAL_BINDER),
- mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
- }
-
- private void unbindNetworkQueryService() {
- // unbind the service.
- getContext().unbindService(mNetworkQueryServiceConnection);
- }
-
@Override
public void onPositiveButtonClick(DialogFragment dialog) {
mTelephonyManager.setDataRoamingEnabled(true);
@@ -843,8 +793,6 @@
mExpandAdvancedFields = true;
}
- bindNetworkQueryService();
-
addPreferencesFromResource(R.xml.network_setting_fragment);
mButton4glte = (SwitchPreference)findPreference(BUTTON_4G_LTE_KEY);
@@ -947,8 +895,10 @@
@Override
public void onDestroy() {
- unbindNetworkQueryService();
super.onDestroy();
+ if (mMobileDataPref != null) {
+ mMobileDataPref.dispose();
+ }
}
@Override
@@ -1120,7 +1070,7 @@
if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
updateCdmaOptions(this, prefSet, mSubId);
} else if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
- updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
+ updateGsmUmtsOptions(this, prefSet, phoneSubId);
} else {
throw new IllegalStateException("Unexpected phone type: " + phoneType);
}
@@ -1136,7 +1086,7 @@
mButtonPreferredNetworkMode.setOnPreferenceChangeListener(this);
updateCdmaOptions(this, prefSet, mSubId);
- updateGsmUmtsOptions(this, prefSet, phoneSubId, mNetworkQueryService);
+ updateGsmUmtsOptions(this, prefSet, phoneSubId);
} else {
prefSet.removePreference(mButtonPreferredNetworkMode);
updateEnabledNetworksEntries();
@@ -1350,8 +1300,7 @@
mButtonEnabledNetworks.setEntryValues(
R.array.enabled_networks_values);
}
- updateGsmUmtsOptions(this, getPreferenceScreen(), mSubId,
- mNetworkQueryService);
+ updateGsmUmtsOptions(this, getPreferenceScreen(), mSubId);
} else {
throw new IllegalStateException("Unexpected phone type: " + phoneType);
}
@@ -2095,7 +2044,7 @@
return;
}
- updateGsmUmtsOptions(this, prefSet, mSubId, mNetworkQueryService);
+ updateGsmUmtsOptions(this, prefSet, mSubId);
PreferenceCategory networkOperatorCategory =
(PreferenceCategory) prefSet.findPreference(
@@ -2248,14 +2197,14 @@
}
private void updateGsmUmtsOptions(PreferenceFragment prefFragment,
- PreferenceScreen prefScreen, final int subId, INetworkQueryService queryService) {
+ PreferenceScreen prefScreen, final int subId) {
// We don't want to re-create GsmUmtsOptions if already exists. Otherwise, the
// preferences inside it will also be re-created which causes unexpected behavior.
// For example, the open dialog gets dismissed or detached after pause / resume.
if (mGsmUmtsOptions == null) {
- mGsmUmtsOptions = new GsmUmtsOptions(prefFragment, prefScreen, subId, queryService);
+ mGsmUmtsOptions = new GsmUmtsOptions(prefFragment, prefScreen, subId);
} else {
- mGsmUmtsOptions.update(subId, queryService);
+ mGsmUmtsOptions.update(subId);
}
}
diff --git a/src/com/android/phone/NetworkOperators.java b/src/com/android/phone/NetworkOperators.java
index 6d798b0..938ca34 100644
--- a/src/com/android/phone/NetworkOperators.java
+++ b/src/com/android/phone/NetworkOperators.java
@@ -94,12 +94,11 @@
}
/**
- * Update NetworkOperators instance if like subId or queryService are updated.
+ * Update NetworkOperators instance if like subId is updated.
*
* @param subId Corresponding subscription ID of this network.
- * @param queryService The service to do network queries.
*/
- protected void update(final int subId, INetworkQueryService queryService) {
+ protected void update(final int subId) {
mSubId = subId;
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
@@ -118,7 +117,7 @@
}
} else {
if (mNetworkSelect != null) {
- mNetworkSelect.initialize(mSubId, queryService, this, mProgressDialog);
+ mNetworkSelect.initialize(mSubId, this, mProgressDialog);
}
}
getNetworkSelectionMode();
diff --git a/src/com/android/phone/NetworkSelectListPreference.java b/src/com/android/phone/NetworkSelectListPreference.java
index 5b841c9..9af1c77 100644
--- a/src/com/android/phone/NetworkSelectListPreference.java
+++ b/src/com/android/phone/NetworkSelectListPreference.java
@@ -24,7 +24,6 @@
import android.os.Message;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.RemoteException;
import android.preference.ListPreference;
import android.preference.Preference;
import android.telephony.CellInfo;
@@ -39,15 +38,19 @@
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
+import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.OperatorInfo;
+import com.android.phone.NetworkScanHelper.NetworkScanCallback;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/**
@@ -65,16 +68,20 @@
private static final int EVENT_MANUALLY_NETWORK_SELECTION_DONE = 1;
private static final int EVENT_NETWORK_SCAN_RESULTS = 2;
private static final int EVENT_NETWORK_SCAN_COMPLETED = 3;
+ private static final int EVENT_NETWORK_SCAN_ERROR = 4;
//dialog ids
private static final int DIALOG_NETWORK_SELECTION = 100;
private static final int DIALOG_NETWORK_LIST_LOAD = 200;
+ private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
+
private List<CellInfo> mCellInfoList;
private CellInfo mCellInfo;
private int mSubId;
private TelephonyManager mTelephonyManager;
+ private NetworkScanHelper mNetworkScanHelper;
private NetworkOperators mNetworkOperators;
private List<String> mForbiddenPlmns;
@@ -113,11 +120,7 @@
switch (msg.what) {
case EVENT_MANUALLY_NETWORK_SELECTION_DONE:
if (DBG) logd("hideProgressPanel");
- try {
- dismissProgressBar();
- } catch (IllegalArgumentException e) {
- }
- setEnabled(true);
+ dismissProgressDialog();
boolean isSuccessed = (boolean) msg.obj;
if (isSuccessed) {
@@ -138,72 +141,51 @@
results.removeIf(cellInfo -> cellInfo == null);
mCellInfoList = new ArrayList<>(results);
if (DBG) logd("CALLBACK_SCAN_RESULTS" + mCellInfoList.toString());
-
break;
case EVENT_NETWORK_SCAN_COMPLETED:
- try {
- if (mNetworkQueryService != null) {
- mNetworkQueryService.unregisterCallback(mCallback);
- }
- } catch (RemoteException e) {
- loge("onComplete: exception from unregisterCallback " + e);
- }
if (DBG) logd("scan complete, load the cellInfosList");
- // Modify UI to indicate users that the scan has completed.
+ dismissProgressDialog();
networksListLoaded();
+ break;
+ case EVENT_NETWORK_SCAN_ERROR:
+ dismissProgressDialog();
+ displayNetworkQueryFailed();
+ mNetworkOperators.getNetworkSelectionMode();
+ break;
}
return;
}
};
- INetworkQueryService mNetworkQueryService = null;
- /**
- * This implementation of INetworkQueryServiceCallback is used to receive
- * callback notifications from the network query service.
- */
- private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
-
- /** Returns the scan results to the user, this callback will be called only one time. */
+ private final NetworkScanHelper.NetworkScanCallback mCallback = new NetworkScanCallback() {
public void onResults(List<CellInfo> results) {
if (DBG) logd("get scan results: " + results.toString());
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
msg.sendToTarget();
}
- /**
- * Informs the user that the scan has stopped.
- *
- * This callback will be called when the scan is finished or cancelled by the user.
- * The related NetworkScanRequest will be deleted after this callback.
- */
public void onComplete() {
if (DBG) logd("network scan completed.");
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
msg.sendToTarget();
}
- /**
- * This callback will not be called, since the old Scan API won't send this callback.
- */
- public void onError(int error) {}
+ public void onError(int error) {
+ if (DBG) logd("network scan error.");
+ Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR);
+ msg.sendToTarget();
+ }
};
@Override
//implemented for DialogInterface.OnCancelListener
public void onCancel(DialogInterface dialog) {
if (DBG) logd("user manually close the dialog");
- // request that the service stop the query with this callback object.
- try {
- if (mNetworkQueryService != null) {
- mNetworkQueryService.stopNetworkQuery();
- mNetworkQueryService.unregisterCallback(mCallback);
- }
- // If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
- mNetworkOperators.getNetworkSelectionMode();
- } catch (RemoteException e) {
- loge("onCancel: exception from stopNetworkQuery " + e);
- }
+ mNetworkScanHelper.stopNetworkQuery();
+
+ // If cancelled, we query NetworkSelectMode and update states of AutoSelect button.
+ mNetworkOperators.getNetworkSelectionMode();
}
@Override
@@ -215,23 +197,17 @@
}
}
- // This method is provided besides initialize() because bind to network query service
- // may be binded after initialize(). In that case this method needs to be called explicitly
- // to set mNetworkQueryService. Otherwise mNetworkQueryService will remain null.
- public void setNetworkQueryService(INetworkQueryService queryService) {
- mNetworkQueryService = queryService;
- }
-
// This initialize method needs to be called for this preference to work properly.
- protected void initialize(int subId, INetworkQueryService queryService,
- NetworkOperators networkOperators, ProgressDialog progressDialog) {
+ protected void initialize(int subId, NetworkOperators networkOperators,
+ ProgressDialog progressDialog) {
mSubId = subId;
- mNetworkQueryService = queryService;
mNetworkOperators = networkOperators;
// This preference should share the same progressDialog with networkOperators category.
mProgressDialog = progressDialog;
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+ mNetworkScanHelper = new NetworkScanHelper(
+ mTelephonyManager, mCallback, mNetworkScanExecutor);
setSummary(mTelephonyManager.getNetworkOperatorName());
@@ -245,79 +221,32 @@
}
private void destroy() {
- try {
- dismissProgressBar();
- } catch (IllegalArgumentException e) {
- loge("onDestroy: exception from dismissProgressBar " + e);
+ dismissProgressDialog();
+
+ if (mNetworkScanHelper != null) {
+ mNetworkScanHelper.stopNetworkQuery();
}
- try {
- if (mNetworkQueryService != null) {
- // used to un-register callback
- mNetworkQueryService.unregisterCallback(mCallback);
- }
- } catch (RemoteException e) {
- loge("onDestroy: exception from unregisterCallback " + e);
- }
+ mNetworkScanExecutor.shutdown();
}
private void displayEmptyNetworkList() {
- String status = getContext().getResources().getString(R.string.empty_networks_list);
-
- final PhoneGlobals app = PhoneGlobals.getInstance();
- app.notificationMgr.postTransientNotification(
- NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+ Toast.makeText(getContext(), R.string.empty_networks_list, Toast.LENGTH_LONG).show();
}
- private void displayNetworkSelectionInProgress() {
- showProgressDialog(DIALOG_NETWORK_SELECTION);
- }
-
- private void displayNetworkQueryFailed(int error) {
- String status = getContext().getResources().getString(R.string.network_query_error);
-
- try {
- dismissProgressBar();
- } catch (IllegalArgumentException e1) {
- // do nothing
- }
-
- final PhoneGlobals app = PhoneGlobals.getInstance();
- app.notificationMgr.postTransientNotification(
- NotificationMgr.NETWORK_SELECTION_NOTIFICATION, status);
+ private void displayNetworkQueryFailed() {
+ Toast.makeText(getContext(), R.string.network_query_error, Toast.LENGTH_LONG).show();
}
private void loadNetworksList() {
if (DBG) logd("load networks list...");
- try {
- if (mNetworkQueryService != null) {
- mNetworkQueryService.startNetworkQuery(
- mCallback, mSubId, false /* isIncrementalResult */);
- } else {
- displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
- }
- } catch (RemoteException e) {
- loge("loadNetworksList: exception from startNetworkQuery " + e);
- displayNetworkQueryFailed(NetworkQueryService.QUERY_EXCEPTION);
- }
+ mNetworkScanHelper.startNetworkScan(
+ NetworkScanHelper.NETWORK_SCAN_TYPE_WAIT_FOR_ALL_RESULTS);
}
private void networksListLoaded() {
if (DBG) logd("networks list loaded");
- // update the state of the preferences.
- if (DBG) logd("hideProgressPanel");
-
- // Always try to dismiss the dialog because activity may
- // be moved to background after dialog is shown.
- try {
- dismissProgressBar();
- } catch (IllegalArgumentException e) {
- // It's not a error in following scenario, we just ignore it.
- // "Load list" dialog will not show, if NetworkQueryService is
- // connected after this activity is moved to background.
- loge("Fail to dismiss network load list dialog " + e);
- }
mNetworkOperators.getNetworkSelectionMode();
if (mCellInfoList != null) {
// create a preference for each item in the list.
@@ -345,9 +274,13 @@
}
}
- private void dismissProgressBar() {
+ private void dismissProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
- mProgressDialog.dismiss();
+ try {
+ mProgressDialog.dismiss();
+ } catch (IllegalArgumentException ex) {
+ loge("Can't close the progress dialog " + ex);
+ }
}
}
@@ -356,7 +289,7 @@
mProgressDialog = new ProgressDialog(getContext());
} else {
// Dismiss progress bar if it's showing now.
- dismissProgressBar();
+ dismissProgressDialog();
}
switch (id) {
diff --git a/src/com/android/phone/NetworkSelectSetting.java b/src/com/android/phone/NetworkSelectSetting.java
index c8a29ce..66cd8a1 100644
--- a/src/com/android/phone/NetworkSelectSetting.java
+++ b/src/com/android/phone/NetworkSelectSetting.java
@@ -17,17 +17,12 @@
import android.app.ActionBar;
import android.app.Activity;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
-import android.os.RemoteException;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
@@ -47,6 +42,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.telephony.OperatorInfo;
+import com.android.phone.NetworkScanHelper.NetworkScanCallback;
import com.android.settingslib.utils.ThreadUtils;
import java.util.ArrayList;
@@ -54,6 +50,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
/**
* "Choose network" settings UI for the Phone app.
@@ -86,6 +84,8 @@
private TelephonyManager mTelephonyManager;
private List<String> mForbiddenPlmns;
private boolean mShow4GForLTE;
+ private NetworkScanHelper mNetworkScanHelper;
+ private final ExecutorService mNetworkScanExecutor = Executors.newFixedThreadPool(1);
private final Runnable mUpdateNetworkOperatorsRunnable = () -> {
updateNetworkOperatorsPreferenceCategory();
@@ -118,6 +118,8 @@
mStatusMessagePreference = new Preference(getContext());
mSelectedNetworkOperatorPreference = null;
mTelephonyManager = TelephonyManager.from(getContext()).createForSubscriptionId(mSubId);
+ mNetworkScanHelper = new NetworkScanHelper(
+ mTelephonyManager, mCallback, mNetworkScanExecutor);
try {
Context con = getActivity().createPackageContext("com.android.systemui", 0);
int id = con.getResources().getIdentifier("config_show4GForLTE",
@@ -172,7 +174,7 @@
@Override
protected void onPostExecute(List<String> result) {
mForbiddenPlmns = result;
- bindNetworkQueryService();
+ loadNetworksList();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -260,8 +262,6 @@
if (DBG) logd("onStop");
getView().removeCallbacks(mUpdateNetworkOperatorsRunnable);
stopNetworkQuery();
- // Unbind the NetworkQueryService
- unbindNetworkQueryService();
}
private final Handler mHandler = new Handler() {
@@ -320,52 +320,23 @@
private void loadNetworksList() {
if (DBG) logd("load networks list...");
setProgressBarVisible(true);
- try {
- if (mNetworkQueryService != null) {
- if (DBG) logd("start network query");
- mNetworkQueryService
- .startNetworkQuery(mCallback, mSubId, true /* is incremental result */);
- } else {
- if (DBG) logd("unable to start network query, mNetworkQueryService is null");
- addMessagePreference(R.string.network_query_error);
- }
- } catch (RemoteException e) {
- loge("loadNetworksList: exception from startNetworkQuery " + e);
- addMessagePreference(R.string.network_query_error);
- }
+ mNetworkScanHelper.startNetworkScan(
+ NetworkScanHelper.NETWORK_SCAN_TYPE_INCREMENTAL_RESULTS);
}
- /**
- * This implementation of INetworkQueryServiceCallback is used to receive
- * callback notifications from the network query service.
- */
- private final INetworkQueryServiceCallback mCallback = new INetworkQueryServiceCallback.Stub() {
-
- /** Returns the scan results to the user, this callback will be called at lease one time. */
+ private final NetworkScanHelper.NetworkScanCallback mCallback = new NetworkScanCallback() {
public void onResults(List<CellInfo> results) {
if (DBG) logd("get scan results.");
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_RESULTS, results);
msg.sendToTarget();
}
- /**
- * Informs the user that the scan has stopped.
- *
- * This callback will be called when the scan is finished or cancelled by the user.
- * The related NetworkScanRequest will be deleted after this callback.
- */
public void onComplete() {
if (DBG) logd("network scan completed.");
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_COMPLETED);
msg.sendToTarget();
}
- /**
- * Informs the user that there is some error about the scan.
- *
- * This callback will be called whenever there is any error about the scan, and the scan
- * will be terminated. onComplete() will NOT be called.
- */
public void onError(int error) {
if (DBG) logd("get onError callback with error code: " + error);
Message msg = mHandler.obtainMessage(EVENT_NETWORK_SCAN_ERROR, error, 0 /* arg2 */);
@@ -373,9 +344,6 @@
}
};
- /**
- * Updates network operators from {@link INetworkQueryServiceCallback#onResults()}.
- */
private void updateNetworkOperators() {
if (DBG) logd("updateNetworkOperators");
if (getActivity() != null) {
@@ -580,66 +548,18 @@
return new ArrayList<>(map.values());
}
- /**
- * Service connection code for the NetworkQueryService.
- * Handles the work of binding to a local object so that we can make
- * the appropriate service calls.
- */
-
- /** Local service interface */
- private INetworkQueryService mNetworkQueryService = null;
- /** Flag indicating whether we have called bind on the service. */
- boolean mShouldUnbind;
-
- /** Service connection */
- private final ServiceConnection mNetworkQueryServiceConnection = new ServiceConnection() {
-
- /** Handle the task of binding the local object to the service */
- public void onServiceConnected(ComponentName className, IBinder service) {
- if (DBG) logd("connection created, binding local service.");
- mNetworkQueryService = ((NetworkQueryService.LocalBinder) service).getService();
- // Load the network list only when the service is well connected.
- loadNetworksList();
- }
-
- /** Handle the task of cleaning up the local binding */
- public void onServiceDisconnected(ComponentName className) {
- if (DBG) logd("connection disconnected, cleaning local binding.");
- mNetworkQueryService = null;
- }
- };
-
- private void bindNetworkQueryService() {
- if (DBG) logd("bindNetworkQueryService");
- getContext().bindService(new Intent(getContext(), NetworkQueryService.class).setAction(
- NetworkQueryService.ACTION_LOCAL_BINDER),
- mNetworkQueryServiceConnection, Context.BIND_AUTO_CREATE);
- mShouldUnbind = true;
- }
-
- private void unbindNetworkQueryService() {
- if (DBG) logd("unbindNetworkQueryService");
- if (mShouldUnbind) {
- if (DBG) logd("mShouldUnbind is true");
- // unbind the service.
- getContext().unbindService(mNetworkQueryServiceConnection);
- mShouldUnbind = false;
- }
- }
-
private void stopNetworkQuery() {
- // Stop the network query process
- try {
- if (mNetworkQueryService != null) {
- if (DBG) logd("Stop network query");
- mNetworkQueryService.stopNetworkQuery();
- mNetworkQueryService.unregisterCallback(mCallback);
- }
- } catch (RemoteException e) {
- loge("Exception from stopNetworkQuery " + e);
+ if (mNetworkScanHelper != null) {
+ mNetworkScanHelper.stopNetworkQuery();
}
}
+ @Override
+ public void onDestroy() {
+ mNetworkScanExecutor.shutdown();
+ super.onDestroy();
+ }
+
private void logd(String msg) {
Log.d(TAG, msg);
}
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index cef0e53..8866d30 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -4980,6 +4980,23 @@
}
@Override
+ public boolean isManualNetworkSelectionAllowed(int subId) {
+ boolean isAllowed = true;
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ TelephonyPermissions.enforeceCallingOrSelfReadPhoneStatePermissionOrCarrierPrivilege(
+ mApp, subId, "isManualNetworkSelectionAllowed");
+ Phone phone = getPhone(subId);
+ if (phone != null) {
+ isAllowed = phone.isCspPlmnEnabled();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ return isAllowed;
+ }
+
+ @Override
public UiccSlotInfo[] getUiccSlotsInfo() {
enforceReadPrivilegedPermission();
diff --git a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
index 670f98d..d891da9 100644
--- a/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
+++ b/src/com/android/phone/settings/PhoneAccountSettingsFragment.java
@@ -18,6 +18,7 @@
import android.telecom.TelecomManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
+import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -76,6 +77,15 @@
private SwitchPreference mSipReceiveCallsPreference;
private SipPreferences mSipPreferences;
+ private final SubscriptionManager.OnSubscriptionsChangedListener
+ mOnSubscriptionsChangeListener =
+ new SubscriptionManager.OnSubscriptionsChangedListener() {
+ @Override
+ public void onSubscriptionsChanged() {
+ updateAccounts();
+ }
+ };
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -122,34 +132,8 @@
*/
mAccountList = (PreferenceCategory) getPreferenceScreen().findPreference(
ACCOUNTS_LIST_CATEGORY_KEY);
- List<PhoneAccountHandle> allNonSimAccounts =
- getCallingAccounts(false /* includeSims */, true /* includeDisabled */);
- // Check to see if we should show the entire section at all.
- if (shouldShowConnectionServiceList(allNonSimAccounts)) {
- List<PhoneAccountHandle> enabledAccounts =
- getCallingAccounts(true /* includeSims */, false /* includeDisabled */);
- // Initialize the account list with the set of enabled & SIM accounts.
- initAccountList(enabledAccounts);
- mDefaultOutgoingAccount = (AccountSelectionPreference)
- getPreferenceScreen().findPreference(DEFAULT_OUTGOING_ACCOUNT_KEY);
- mDefaultOutgoingAccount.setListener(this);
-
- // Only show the 'Make Calls With..." option if there are multiple accounts.
- if (enabledAccounts.size() > 1) {
- updateDefaultOutgoingAccountsModel();
- } else {
- mAccountList.removePreference(mDefaultOutgoingAccount);
- }
-
- Preference allAccounts = getPreferenceScreen().findPreference(ALL_CALLING_ACCOUNTS_KEY);
- // If there are no third party (nonSim) accounts, then don't show enable/disable dialog.
- if (allNonSimAccounts.isEmpty() && allAccounts != null) {
- mAccountList.removePreference(allAccounts);
- }
- } else {
- getPreferenceScreen().removePreference(mAccountList);
- }
+ updateAccounts();
if (isPrimaryUser() && SipUtil.isVoipSupported(getActivity())) {
mSipPreferences = new SipPreferences(getActivity());
@@ -183,6 +167,16 @@
getPreferenceScreen().removePreference(
getPreferenceScreen().findPreference(SIP_SETTINGS_CATEGORY_PREF_KEY));
}
+
+ SubscriptionManager.from(getActivity()).addOnSubscriptionsChangedListener(
+ mOnSubscriptionsChangeListener);
+ }
+
+ @Override
+ public void onPause() {
+ SubscriptionManager.from(getActivity()).removeOnSubscriptionsChangedListener(
+ mOnSubscriptionsChangeListener);
+ super.onPause();
}
/**
@@ -391,6 +385,40 @@
return mTelephonyManager.isMultiSimEnabled() || allNonSimAccounts.size() > 0;
}
+ private void updateAccounts() {
+ if (mAccountList != null) {
+ mAccountList.removeAll();
+ List<PhoneAccountHandle> allNonSimAccounts =
+ getCallingAccounts(false /* includeSims */, true /* includeDisabled */);
+ // Check to see if we should show the entire section at all.
+ if (shouldShowConnectionServiceList(allNonSimAccounts)) {
+ List<PhoneAccountHandle> enabledAccounts =
+ getCallingAccounts(true /* includeSims */, false /* includeDisabled */);
+ // Initialize the account list with the set of enabled & SIM accounts.
+ initAccountList(enabledAccounts);
+
+ mDefaultOutgoingAccount = (AccountSelectionPreference)
+ getPreferenceScreen().findPreference(DEFAULT_OUTGOING_ACCOUNT_KEY);
+ mDefaultOutgoingAccount.setListener(this);
+
+ // Only show the 'Make Calls With..." option if there are multiple accounts.
+ if (enabledAccounts.size() > 1) {
+ updateDefaultOutgoingAccountsModel();
+ } else {
+ mAccountList.removePreference(mDefaultOutgoingAccount);
+ }
+
+ Preference allAccounts = getPreferenceScreen().findPreference(ALL_CALLING_ACCOUNTS_KEY);
+ // If there are no third party (nonSim) accounts, then don't show enable/disable dialog.
+ if (allNonSimAccounts.isEmpty() && allAccounts != null) {
+ mAccountList.removePreference(allAccounts);
+ }
+ } else {
+ getPreferenceScreen().removePreference(mAccountList);
+ }
+ }
+ }
+
private List<PhoneAccountHandle> getCallingAccounts(
boolean includeSims, boolean includeDisabledAccounts) {
PhoneAccountHandle emergencyAccountHandle = getEmergencyPhoneAccount();
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 7d6a86f..a82c346 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -169,6 +169,10 @@
case android.telephony.DisconnectCause.SERVER_ERROR:
case android.telephony.DisconnectCause.SERVER_UNREACHABLE:
case android.telephony.DisconnectCause.TIMED_OUT:
+ case android.telephony.DisconnectCause.ALREADY_DIALING:
+ case android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING:
+ case android.telephony.DisconnectCause.CALLING_DISABLED:
+ case android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS:
case android.telephony.DisconnectCause.UNOBTAINABLE_NUMBER:
case android.telephony.DisconnectCause.VOICEMAIL_NUMBER_MISSING:
case android.telephony.DisconnectCause.DIAL_MODIFIED_TO_USSD:
@@ -320,6 +324,18 @@
case android.telephony.DisconnectCause.DATA_LIMIT_REACHED:
resourceId = R.string.callFailed_data_limit_reached;
break;
+ case android.telephony.DisconnectCause.ALREADY_DIALING:
+ resourceId = R.string.callFailed_already_dialing;
+ break;
+ case android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING:
+ resourceId = R.string.callFailed_already_ringing;
+ break;
+ case android.telephony.DisconnectCause.CALLING_DISABLED:
+ resourceId = R.string.callFailed_calling_disabled;
+ break;
+ case android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS:
+ resourceId = R.string.callFailed_too_many_calls;
+ break;
default:
break;
@@ -684,6 +700,18 @@
case android.telephony.DisconnectCause.WIFI_LOST:
resourceId = R.string.callFailed_wifi_lost;
break;
+ case android.telephony.DisconnectCause.ALREADY_DIALING:
+ resourceId = R.string.callFailed_already_dialing;
+ break;
+ case android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING:
+ resourceId = R.string.callFailed_already_ringing;
+ break;
+ case android.telephony.DisconnectCause.CALLING_DISABLED:
+ resourceId = R.string.callFailed_calling_disabled;
+ break;
+ case android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS:
+ resourceId = R.string.callFailed_too_many_calls;
+ break;
default:
break;
diff --git a/src/com/android/services/telephony/TelephonyConnection.java b/src/com/android/services/telephony/TelephonyConnection.java
index 3192c75..8f46ecf 100644
--- a/src/com/android/services/telephony/TelephonyConnection.java
+++ b/src/com/android/services/telephony/TelephonyConnection.java
@@ -892,7 +892,7 @@
if (originalConnection.isRttEnabledForCall()) {
originalConnection.setCurrentRttTextStream(textStream);
} else {
- originalConnection.sendRttModifyRequest(textStream);
+ originalConnection.startRtt(textStream);
}
} else {
Log.w(this, "onStartRtt - not in IMS, so RTT cannot be enabled.");
@@ -901,7 +901,16 @@
@Override
public void onStopRtt() {
- Log.i(this, "Stopping RTT currently not supported. Doing nothing.");
+ if (isImsConnection()) {
+ ImsPhoneConnection originalConnection = (ImsPhoneConnection) mOriginalConnection;
+ if (originalConnection.isRttEnabledForCall()) {
+ originalConnection.stopRtt();
+ } else {
+ Log.w(this, "onStopRtt - not in RTT call, ignoring");
+ }
+ } else {
+ Log.w(this, "onStopRtt - not in IMS, ignoring");
+ }
}
@Override
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 3ec00b9..16be893 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -1120,10 +1120,25 @@
} catch (CallStateException e) {
Log.e(this, e, "placeOutgoingConnection, phone.dial exception: " + e);
int cause = android.telephony.DisconnectCause.OUTGOING_FAILURE;
- if (e.getError() == CallStateException.ERROR_OUT_OF_SERVICE) {
- cause = android.telephony.DisconnectCause.OUT_OF_SERVICE;
- } else if (e.getError() == CallStateException.ERROR_POWER_OFF) {
- cause = android.telephony.DisconnectCause.POWER_OFF;
+ switch (e.getError()) {
+ case CallStateException.ERROR_OUT_OF_SERVICE:
+ cause = android.telephony.DisconnectCause.OUT_OF_SERVICE;
+ break;
+ case CallStateException.ERROR_POWER_OFF:
+ cause = android.telephony.DisconnectCause.POWER_OFF;
+ break;
+ case CallStateException.ERROR_ALREADY_DIALING:
+ cause = android.telephony.DisconnectCause.ALREADY_DIALING;
+ break;
+ case CallStateException.ERROR_CALL_RINGING:
+ cause = android.telephony.DisconnectCause.CANT_CALL_WHILE_RINGING;
+ break;
+ case CallStateException.ERROR_CALLING_DISABLED:
+ cause = android.telephony.DisconnectCause.CALLING_DISABLED;
+ break;
+ case CallStateException.ERROR_TOO_MANY_CALLS:
+ cause = android.telephony.DisconnectCause.TOO_MANY_ONGOING_CALLS;
+ break;
}
connection.setDisconnected(DisconnectCauseUtil.toTelecomDisconnectCause(
cause, e.getMessage(), phone.getPhoneId()));