1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.settings.network; 17 18 import static android.content.Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT; 19 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; 20 import static android.os.UserHandle.myUserId; 21 import static android.os.UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS; 22 23 import static com.android.settingslib.RestrictedLockUtilsInternal.hasBaseUserRestriction; 24 25 import android.content.ActivityNotFoundException; 26 import android.content.Context; 27 import android.content.Intent; 28 import android.content.res.Resources; 29 import android.net.ConnectivityManager; 30 import android.net.NetworkInfo; 31 import android.net.Uri; 32 import android.os.Bundle; 33 import android.os.UserManager; 34 import android.telephony.TelephonyManager; 35 import android.text.TextUtils; 36 import android.util.Log; 37 38 import androidx.preference.Preference; 39 40 import com.android.settings.R; 41 import com.android.settings.core.PreferenceControllerMixin; 42 import com.android.settingslib.Utils; 43 import com.android.settingslib.core.AbstractPreferenceController; 44 import com.android.settingslib.core.lifecycle.LifecycleObserver; 45 import com.android.settingslib.core.lifecycle.events.OnCreate; 46 import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; 47 48 import java.util.List; 49 50 public class MobilePlanPreferenceController extends AbstractPreferenceController 51 implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnSaveInstanceState { 52 53 public interface MobilePlanPreferenceHost { showMobilePlanMessageDialog()54 void showMobilePlanMessageDialog(); 55 } 56 57 public static final int MANAGE_MOBILE_PLAN_DIALOG_ID = 1; 58 59 private static final String TAG = "MobilePlanPrefContr"; 60 private static final String KEY_MANAGE_MOBILE_PLAN = "manage_mobile_plan"; 61 private static final String SAVED_MANAGE_MOBILE_PLAN_MSG = "mManageMobilePlanMessage"; 62 63 private final UserManager mUserManager; 64 private final boolean mIsSecondaryUser; 65 private final MobilePlanPreferenceHost mHost; 66 67 private ConnectivityManager mCm; 68 private TelephonyManager mTm; 69 70 private String mMobilePlanDialogMessage; 71 MobilePlanPreferenceController(Context context, MobilePlanPreferenceHost host)72 public MobilePlanPreferenceController(Context context, 73 MobilePlanPreferenceHost host) { 74 super(context); 75 mHost = host; 76 mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 77 mTm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 78 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 79 mIsSecondaryUser = !mUserManager.isAdminUser(); 80 } 81 82 @Override handlePreferenceTreeClick(Preference preference)83 public boolean handlePreferenceTreeClick(Preference preference) { 84 if (mHost != null && KEY_MANAGE_MOBILE_PLAN.equals(preference.getKey())) { 85 mMobilePlanDialogMessage = null; 86 onManageMobilePlanClick(); 87 return true; 88 } 89 return false; 90 } 91 92 @Override onCreate(Bundle savedInstanceState)93 public void onCreate(Bundle savedInstanceState) { 94 if (savedInstanceState != null) { 95 mMobilePlanDialogMessage = savedInstanceState.getString(SAVED_MANAGE_MOBILE_PLAN_MSG); 96 } 97 Log.d(TAG, "onCreate: mMobilePlanDialogMessage=" + mMobilePlanDialogMessage); 98 } 99 100 @Override onSaveInstanceState(Bundle outState)101 public void onSaveInstanceState(Bundle outState) { 102 if (!TextUtils.isEmpty(mMobilePlanDialogMessage)) { 103 outState.putString(SAVED_MANAGE_MOBILE_PLAN_MSG, mMobilePlanDialogMessage); 104 } 105 } 106 getMobilePlanDialogMessage()107 public String getMobilePlanDialogMessage() { 108 return mMobilePlanDialogMessage; 109 } 110 setMobilePlanDialogMessage(String messasge)111 public void setMobilePlanDialogMessage(String messasge) { 112 mMobilePlanDialogMessage = messasge; 113 } 114 115 @Override isAvailable()116 public boolean isAvailable() { 117 final boolean isPrefAllowedOnDevice = mContext.getResources().getBoolean( 118 com.android.settings.R.bool.config_show_mobile_plan); 119 final boolean isPrefAllowedForUser = !mIsSecondaryUser 120 && !Utils.isWifiOnly(mContext) 121 && !hasBaseUserRestriction(mContext, DISALLOW_CONFIG_MOBILE_NETWORKS, myUserId()); 122 return isPrefAllowedForUser && isPrefAllowedOnDevice; 123 } 124 @Override getPreferenceKey()125 public String getPreferenceKey() { 126 return KEY_MANAGE_MOBILE_PLAN; 127 } 128 onManageMobilePlanClick()129 private void onManageMobilePlanClick() { 130 Resources resources = mContext.getResources(); 131 NetworkInfo ni = mCm.getActiveNetworkInfo(); 132 if (mTm.hasIccCard() && (ni != null)) { 133 // Check for carrier apps that can handle provisioning first 134 Intent provisioningIntent = new Intent(Intent.ACTION_CARRIER_SETUP); 135 List<String> carrierPackages = 136 mTm.getCarrierPackageNamesForIntent(provisioningIntent); 137 if (carrierPackages != null && !carrierPackages.isEmpty()) { 138 if (carrierPackages.size() != 1) { 139 Log.w(TAG, "Multiple matching carrier apps found, launching the first."); 140 } 141 provisioningIntent.setPackage(carrierPackages.get(0)); 142 mContext.startActivity(provisioningIntent); 143 return; 144 } 145 146 // Get provisioning URL 147 String url = mTm.getMobileProvisioningUrl(); 148 if (!TextUtils.isEmpty(url)) { 149 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, 150 Intent.CATEGORY_APP_BROWSER); 151 intent.setData(Uri.parse(url)); 152 intent.setFlags(FLAG_ACTIVITY_BROUGHT_TO_FRONT | FLAG_ACTIVITY_NEW_TASK); 153 try { 154 mContext.startActivity(intent); 155 } catch (ActivityNotFoundException e) { 156 Log.w(TAG, "onManageMobilePlanClick: startActivity failed" + e); 157 } 158 } else { 159 // No provisioning URL 160 String operatorName = mTm.getSimOperatorName(); 161 if (TextUtils.isEmpty(operatorName)) { 162 // Use NetworkOperatorName as second choice in case there is no 163 // SPN (Service Provider Name on the SIM). Such as with T-mobile. 164 operatorName = mTm.getNetworkOperatorName(); 165 if (TextUtils.isEmpty(operatorName)) { 166 mMobilePlanDialogMessage = 167 resources.getString(R.string.mobile_unknown_sim_operator); 168 } else { 169 mMobilePlanDialogMessage = resources.getString( 170 R.string.mobile_no_provisioning_url, operatorName); 171 } 172 } else { 173 mMobilePlanDialogMessage = 174 resources.getString(R.string.mobile_no_provisioning_url, operatorName); 175 } 176 } 177 } else if (mTm.hasIccCard() == false) { 178 // No sim card 179 mMobilePlanDialogMessage = resources.getString(R.string.mobile_insert_sim_card); 180 } else { 181 // NetworkInfo is null, there is no connection 182 mMobilePlanDialogMessage = resources.getString(R.string.mobile_connect_to_internet); 183 } 184 if (!TextUtils.isEmpty(mMobilePlanDialogMessage)) { 185 Log.d(TAG, "onManageMobilePlanClick: message=" + mMobilePlanDialogMessage); 186 if (mHost != null) { 187 mHost.showMobilePlanMessageDialog(); 188 } else { 189 Log.d(TAG, "Missing host fragment, cannot show message dialog."); 190 } 191 } 192 } 193 } 194