Show ProgressDialog when waiting for radio to turn on when provisioning.
Paul Jensen [Wed, 15 Oct 2014 01:02:05 +0000 (21:02 -0400)]
Turning on the cellular radio when user selects the provisioning notification
can take 30-60s so a UI is needed to keep the user informed that the radio is
coming up.  This is only for provisioning APN support (only AT&T tablets now).

bug:15990642
Change-Id: I1e77c3a1b1a24be7acc7cb3c925c002e5fa2d1a9

src/java/com/android/internal/telephony/dataconnection/DcTracker.java

index 218b8f7..9792668 100644 (file)
@@ -18,6 +18,7 @@ package com.android.internal.telephony.dataconnection;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
+import android.app.ProgressDialog;
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -59,6 +60,7 @@ import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 import android.util.EventLog;
+import android.view.WindowManager;
 import android.telephony.Rlog;
 
 import com.android.internal.telephony.cdma.CDMALTEPhone;
@@ -129,6 +131,8 @@ public final class DcTracker extends DcTrackerBase {
 
     private static final int POLL_PDP_MILLIS = 5 * 1000;
 
+    private static final int PROVISIONING_SPINNER_TIMEOUT_MILLIS = 120 * 1000;
+
     static final Uri PREFERAPN_NO_UPDATE_URI =
                         Uri.parse("content://telephony/carriers/preferapn_no_update");
     static final String APN_ID = "apn_id";
@@ -142,6 +146,7 @@ public final class DcTracker extends DcTrackerBase {
 
     private final String mProvisionActionName;
     private BroadcastReceiver mProvisionBroadcastReceiver;
+    private ProgressDialog mProvisioningSpinner;
 
     /** Used to send us NetworkRequests from ConnectivityService.  Remeber it so we can
      * unregister on dispose. */
@@ -241,6 +246,10 @@ public final class DcTracker extends DcTrackerBase {
             mPhone.getContext().unregisterReceiver(mProvisionBroadcastReceiver);
             mProvisionBroadcastReceiver = null;
         }
+        if (mProvisioningSpinner != null) {
+            mProvisioningSpinner.dismiss();
+            mProvisioningSpinner = null;
+        }
 
         ConnectivityManager cm = (ConnectivityManager)mPhone.getContext().getSystemService(
                 Context.CONNECTIVITY_SERVICE);
@@ -395,12 +404,14 @@ public final class DcTracker extends DcTrackerBase {
     // Class to handle Intent dispatched with user selects the "Sign-in to network"
     // notification.
     private class ProvisionNotificationBroadcastReceiver extends BroadcastReceiver {
+        private final String mNetworkOperator;
         // Mobile provisioning URL.  Valid while provisioning notification is up.
         // Set prior to notification being posted as URL contains ICCID which
         // disappears when radio is off (which is the case when notification is up).
         private final String mProvisionUrl;
 
-        public ProvisionNotificationBroadcastReceiver(String provisionUrl) {
+        public ProvisionNotificationBroadcastReceiver(String provisionUrl, String networkOperator) {
+            mNetworkOperator = networkOperator;
             mProvisionUrl = provisionUrl;
         }
 
@@ -416,6 +427,23 @@ public final class DcTracker extends DcTrackerBase {
 
         @Override
         public void onReceive(Context context, Intent intent) {
+            // Turning back on the radio can take time on the order of a minute, so show user a
+            // spinner so they know something is going on.
+            mProvisioningSpinner = new ProgressDialog(context);
+            mProvisioningSpinner.setTitle(mNetworkOperator);
+            mProvisioningSpinner.setMessage(
+                    // TODO: Don't borrow "Connecting..." i18n string; give Telephony a version.
+                    context.getText(com.android.internal.R.string.media_route_status_connecting));
+            mProvisioningSpinner.setIndeterminate(true);
+            mProvisioningSpinner.setCancelable(true);
+            // Allow non-Activity Service Context to create a View.
+            mProvisioningSpinner.getWindow().setType(
+                    WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+            mProvisioningSpinner.show();
+            // After timeout, hide spinner so user can at least use their device.
+            // TODO: Indicate to user that it is taking an unusually long time to connect?
+            sendMessageDelayed(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
+                    mProvisioningSpinner), PROVISIONING_SPINNER_TIMEOUT_MILLIS);
             // This code is almost identical to the old
             // ConnectivityService.handleMobileProvisioningAction code.
             setRadio(true);
@@ -1808,6 +1836,10 @@ public final class DcTracker extends DcTrackerBase {
         }
         mIsProvisioning = false;
         mProvisioningUrl = null;
+        if (mProvisioningSpinner != null) {
+            sendMessage(obtainMessage(DctConstants.CMD_CLEAR_PROVISIONING_SPINNER,
+                    mProvisioningSpinner));
+        }
 
         mPhone.notifyDataConnection(apnContext.getReason(), apnContext.getApnType());
         startNetStatPoll();
@@ -1919,7 +1951,8 @@ public final class DcTracker extends DcTrackerBase {
                     // While radio is up, grab provisioning URL.  The URL contains ICCID which
                     // disappears when radio is off.
                     mProvisionBroadcastReceiver = new ProvisionNotificationBroadcastReceiver(
-                            cm.getMobileProvisioningUrl());
+                            cm.getMobileProvisioningUrl(),
+                            TelephonyManager.getDefault().getNetworkOperatorName());
                     mPhone.getContext().registerReceiver(mProvisionBroadcastReceiver,
                             new IntentFilter(mProvisionActionName));
                     // Put up user notification that sign-in is required.
@@ -2658,6 +2691,14 @@ public final class DcTracker extends DcTrackerBase {
                 setupDataOnConnectableApns(Phone.REASON_NW_TYPE_CHANGED);
                 break;
 
+            case DctConstants.CMD_CLEAR_PROVISIONING_SPINNER:
+                // Check message sender intended to clear the current spinner.
+                if (mProvisioningSpinner == msg.obj) {
+                    mProvisioningSpinner.dismiss();
+                    mProvisioningSpinner = null;
+                }
+                break;
+
             default:
                 // handle the message in the super class DataConnectionTracker
                 super.handleMessage(msg);