1 /*
2  * Copyright (C) 2018 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 
17 package com.android.settings.homepage.contextualcards.conditional;
18 
19 import android.app.settings.SettingsEnums;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.telephony.PhoneStateListener;
23 import android.telephony.PreciseDataConnectionState;
24 import android.telephony.SubscriptionManager;
25 import android.telephony.TelephonyManager;
26 import android.util.Log;
27 
28 import com.android.settings.R;
29 import com.android.settings.Settings;
30 import com.android.settings.homepage.contextualcards.ContextualCard;
31 import com.android.settings.network.GlobalSettingsChangeListener;
32 
33 import java.util.Objects;
34 
35 public class CellularDataConditionController implements ConditionalCardController {
36     private static final String TAG = "CellularDataConditionController";
37 
38     static final int ID = Objects.hash("CellularDataConditionController");
39 
40     private final Context mAppContext;
41     private final ConditionManager mConditionManager;
42     private final GlobalSettingsChangeListener mDefaultDataSubscriptionIdListener;
43 
44     private int mSubId;
45     private TelephonyManager mTelephonyManager;
46     private boolean mIsListeningConnectionChange;
47 
CellularDataConditionController(Context appContext, ConditionManager conditionManager)48     public CellularDataConditionController(Context appContext, ConditionManager conditionManager) {
49         mAppContext = appContext;
50         mConditionManager = conditionManager;
51         mSubId = getDefaultDataSubscriptionId(appContext);
52         mTelephonyManager = getTelephonyManager(appContext, mSubId);
53         mDefaultDataSubscriptionIdListener = new GlobalSettingsChangeListener(appContext,
54                 android.provider.Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION) {
55             public void onChanged(String field) {
56                 final int subId = getDefaultDataSubscriptionId(mAppContext);
57                 if (subId == mSubId) {
58                     return;
59                 }
60                 mSubId = subId;
61                 if (mIsListeningConnectionChange) {
62                     restartPhoneStateListener(mAppContext, subId);
63                 }
64             }
65         };
66     }
67 
68     @Override
getId()69     public long getId() {
70         return ID;
71     }
72 
73     @Override
isDisplayable()74     public boolean isDisplayable() {
75         if (!mTelephonyManager.isDataCapable()
76                 || mTelephonyManager.getSimState() != TelephonyManager.SIM_STATE_READY) {
77             return false;
78         }
79         return !mTelephonyManager.isDataEnabled();
80     }
81 
82     @Override
onPrimaryClick(Context context)83     public void onPrimaryClick(Context context) {
84         context.startActivity(new Intent(context,
85                 Settings.DataUsageSummaryActivity.class));
86     }
87 
88     @Override
onActionClick()89     public void onActionClick() {
90         Log.d(TAG, "setDataEnabledForReason true");
91         mTelephonyManager.setDataEnabled(true);
92     }
93 
94     @Override
buildContextualCard()95     public ContextualCard buildContextualCard() {
96         return new ConditionalContextualCard.Builder()
97                 .setConditionId(ID)
98                 .setMetricsConstant(SettingsEnums.SETTINGS_CONDITION_CELLULAR_DATA)
99                 .setActionText(mAppContext.getText(R.string.condition_turn_on))
100                 .setName(mAppContext.getPackageName() + "/"
101                         + mAppContext.getText(R.string.condition_cellular_title))
102                 .setTitleText(mAppContext.getText(R.string.condition_cellular_title).toString())
103                 .setSummaryText(mAppContext.getText(R.string.condition_cellular_summary).toString())
104                 .setIconDrawable(mAppContext.getDrawable(R.drawable.ic_cellular_off))
105                 .setViewType(ConditionContextualCardRenderer.VIEW_TYPE_HALF_WIDTH)
106                 .build();
107     }
108 
109     @Override
startMonitoringStateChange()110     public void startMonitoringStateChange() {
111         restartPhoneStateListener(mAppContext, mSubId);
112     }
113 
114     @Override
stopMonitoringStateChange()115     public void stopMonitoringStateChange() {
116         stopPhoneStateListener();
117     }
118 
getDefaultDataSubscriptionId(Context context)119     private int getDefaultDataSubscriptionId(Context context) {
120         final SubscriptionManager subscriptionManager =
121                 context.getSystemService(SubscriptionManager.class);
122         return subscriptionManager.getDefaultDataSubscriptionId();
123     }
124 
getTelephonyManager(Context context, int subId)125     private TelephonyManager getTelephonyManager(Context context, int subId) {
126         final TelephonyManager telephonyManager =
127                 context.getSystemService(TelephonyManager.class);
128         return telephonyManager.createForSubscriptionId(subId);
129     }
130 
131     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
132         @Override
133         public void onPreciseDataConnectionStateChanged(
134                 PreciseDataConnectionState dataConnectionState) {
135             mConditionManager.onConditionChanged();
136         }
137     };
138 
stopPhoneStateListener()139     private void stopPhoneStateListener() {
140         mIsListeningConnectionChange = false;
141         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
142     }
143 
144     // restart monitoring when subscription has been changed
restartPhoneStateListener(Context context, int subId)145     private void restartPhoneStateListener(Context context, int subId) {
146         stopPhoneStateListener();
147         mIsListeningConnectionChange = true;
148 
149         // switch mTelephonyManager only when subscription been updated to valid ones
150         if (SubscriptionManager.isValidSubscriptionId(subId)) {
151             mTelephonyManager = getTelephonyManager(context, subId);
152         }
153 
154         mTelephonyManager.listen(mPhoneStateListener,
155                 PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE);
156     }
157 }
158