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