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 51 public class MobilePlanPreferenceController extends AbstractPreferenceController 52 implements PreferenceControllerMixin, LifecycleObserver, OnCreate, OnSaveInstanceState { 53 54 public interface MobilePlanPreferenceHost { showMobilePlanMessageDialog()55 void showMobilePlanMessageDialog(); 56 } 57 58 public static final int MANAGE_MOBILE_PLAN_DIALOG_ID = 1; 59 60 private static final String TAG = "MobilePlanPrefContr"; 61 private static final String KEY_MANAGE_MOBILE_PLAN = "manage_mobile_plan"; 62 private static final String SAVED_MANAGE_MOBILE_PLAN_MSG = "mManageMobilePlanMessage"; 63 64 private final UserManager mUserManager; 65 private final boolean mIsSecondaryUser; 66 private final MobilePlanPreferenceHost mHost; 67 68 private ConnectivityManager mCm; 69 private TelephonyManager mTm; 70 71 private String mMobilePlanDialogMessage; 72 MobilePlanPreferenceController(Context context, MobilePlanPreferenceHost host)73 public MobilePlanPreferenceController(Context context, 74 MobilePlanPreferenceHost host) { 75 super(context); 76 mHost = host; 77 mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 78 mTm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 79 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 80 mIsSecondaryUser = !mUserManager.isAdminUser(); 81 } 82 83 @Override handlePreferenceTreeClick(Preference preference)84 public boolean handlePreferenceTreeClick(Preference preference) { 85 if (mHost != null && KEY_MANAGE_MOBILE_PLAN.equals(preference.getKey())) { 86 mMobilePlanDialogMessage = null; 87 onManageMobilePlanClick(); 88 return true; 89 } 90 return false; 91 } 92 93 @Override onCreate(Bundle savedInstanceState)94 public void onCreate(Bundle savedInstanceState) { 95 if (savedInstanceState != null) { 96 mMobilePlanDialogMessage = savedInstanceState.getString(SAVED_MANAGE_MOBILE_PLAN_MSG); 97 } 98 Log.d(TAG, "onCreate: mMobilePlanDialogMessage=" + mMobilePlanDialogMessage); 99 } 100 101 @Override onSaveInstanceState(Bundle outState)102 public void onSaveInstanceState(Bundle outState) { 103 if (!TextUtils.isEmpty(mMobilePlanDialogMessage)) { 104 outState.putString(SAVED_MANAGE_MOBILE_PLAN_MSG, mMobilePlanDialogMessage); 105 } 106 } 107 getMobilePlanDialogMessage()108 public String getMobilePlanDialogMessage() { 109 return mMobilePlanDialogMessage; 110 } 111 setMobilePlanDialogMessage(String messasge)112 public void setMobilePlanDialogMessage(String messasge) { 113 mMobilePlanDialogMessage = messasge; 114 } 115 116 @Override isAvailable()117 public boolean isAvailable() { 118 final boolean isPrefAllowedOnDevice = mContext.getResources().getBoolean( 119 com.android.settings.R.bool.config_show_mobile_plan); 120 final boolean isPrefAllowedForUser = !mIsSecondaryUser 121 && !Utils.isWifiOnly(mContext) 122 && !hasBaseUserRestriction(mContext, DISALLOW_CONFIG_MOBILE_NETWORKS, myUserId()); 123 return isPrefAllowedForUser && isPrefAllowedOnDevice; 124 } 125 @Override getPreferenceKey()126 public String getPreferenceKey() { 127 return KEY_MANAGE_MOBILE_PLAN; 128 } 129 onManageMobilePlanClick()130 private void onManageMobilePlanClick() { 131 Resources resources = mContext.getResources(); 132 NetworkInfo ni = mCm.getActiveNetworkInfo(); 133 if (mTm.hasIccCard() && (ni != null)) { 134 // Check for carrier apps that can handle provisioning first 135 Intent provisioningIntent = new Intent(Intent.ACTION_CARRIER_SETUP); 136 List<String> carrierPackages = 137 mTm.getCarrierPackageNamesForIntent(provisioningIntent); 138 if (carrierPackages != null && !carrierPackages.isEmpty()) { 139 if (carrierPackages.size() != 1) { 140 Log.w(TAG, "Multiple matching carrier apps found, launching the first."); 141 } 142 provisioningIntent.setPackage(carrierPackages.get(0)); 143 mContext.startActivity(provisioningIntent); 144 return; 145 } 146 147 // Get provisioning URL 148 String url = mCm.getMobileProvisioningUrl(); 149 if (!TextUtils.isEmpty(url)) { 150 Intent intent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN, 151 Intent.CATEGORY_APP_BROWSER); 152 intent.setData(Uri.parse(url)); 153 intent.setFlags(FLAG_ACTIVITY_BROUGHT_TO_FRONT | FLAG_ACTIVITY_NEW_TASK); 154 try { 155 mContext.startActivity(intent); 156 } catch (ActivityNotFoundException e) { 157 Log.w(TAG, "onManageMobilePlanClick: startActivity failed" + e); 158 } 159 } else { 160 // No provisioning URL 161 String operatorName = mTm.getSimOperatorName(); 162 if (TextUtils.isEmpty(operatorName)) { 163 // Use NetworkOperatorName as second choice in case there is no 164 // SPN (Service Provider Name on the SIM). Such as with T-mobile. 165 operatorName = mTm.getNetworkOperatorName(); 166 if (TextUtils.isEmpty(operatorName)) { 167 mMobilePlanDialogMessage = 168 resources.getString(R.string.mobile_unknown_sim_operator); 169 } else { 170 mMobilePlanDialogMessage = resources.getString( 171 R.string.mobile_no_provisioning_url, operatorName); 172 } 173 } else { 174 mMobilePlanDialogMessage = 175 resources.getString(R.string.mobile_no_provisioning_url, operatorName); 176 } 177 } 178 } else if (mTm.hasIccCard() == false) { 179 // No sim card 180 mMobilePlanDialogMessage = resources.getString(R.string.mobile_insert_sim_card); 181 } else { 182 // NetworkInfo is null, there is no connection 183 mMobilePlanDialogMessage = resources.getString(R.string.mobile_connect_to_internet); 184 } 185 if (!TextUtils.isEmpty(mMobilePlanDialogMessage)) { 186 Log.d(TAG, "onManageMobilePlanClick: message=" + mMobilePlanDialogMessage); 187 if (mHost != null) { 188 mHost.showMobilePlanMessageDialog(); 189 } else { 190 Log.d(TAG, "Missing host fragment, cannot show message dialog."); 191 } 192 } 193 } 194 } 195