1 /*
2  * Copyright (C) 2021 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.systemui.statusbar;
18 
19 import android.annotation.NonNull;
20 import android.os.Bundle;
21 import android.telephony.ServiceState;
22 import android.telephony.SubscriptionInfo;
23 import android.telephony.TelephonyManager;
24 import android.view.View;
25 
26 import com.android.keyguard.KeyguardUpdateMonitor;
27 import com.android.keyguard.KeyguardUpdateMonitorCallback;
28 import com.android.systemui.demomode.DemoModeCommandReceiver;
29 import com.android.systemui.plugins.DarkIconDispatcher;
30 import com.android.systemui.statusbar.connectivity.IconState;
31 import com.android.systemui.statusbar.connectivity.NetworkController;
32 import com.android.systemui.statusbar.connectivity.SignalCallback;
33 import com.android.systemui.tuner.TunerService;
34 import com.android.systemui.util.ViewController;
35 
36 import java.util.ArrayList;
37 import java.util.List;
38 
39 import javax.inject.Inject;
40 
41 /** Controller for {@link OperatorNameView}. */
42 public class OperatorNameViewController extends ViewController<OperatorNameView> {
43     private static final String KEY_SHOW_OPERATOR_NAME = "show_operator_name";
44 
45     private final DarkIconDispatcher mDarkIconDispatcher;
46     private final NetworkController mNetworkController;
47     private final TunerService mTunerService;
48     private final TelephonyManager mTelephonyManager;
49     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
50 
OperatorNameViewController(OperatorNameView view, DarkIconDispatcher darkIconDispatcher, NetworkController networkController, TunerService tunerService, TelephonyManager telephonyManager, KeyguardUpdateMonitor keyguardUpdateMonitor)51     private OperatorNameViewController(OperatorNameView view,
52             DarkIconDispatcher darkIconDispatcher,
53             NetworkController networkController,
54             TunerService tunerService,
55             TelephonyManager telephonyManager,
56             KeyguardUpdateMonitor keyguardUpdateMonitor) {
57         super(view);
58         mDarkIconDispatcher = darkIconDispatcher;
59         mNetworkController = networkController;
60         mTunerService = tunerService;
61         mTelephonyManager = telephonyManager;
62         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
63     }
64 
65     @Override
onViewAttached()66     protected void onViewAttached() {
67         mDarkIconDispatcher.addDarkReceiver(mDarkReceiver);
68         mNetworkController.addCallback(mSignalCallback);
69         mTunerService.addTunable(mTunable, KEY_SHOW_OPERATOR_NAME);
70         mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
71     }
72 
73     @Override
onViewDetached()74     protected void onViewDetached() {
75         mDarkIconDispatcher.removeDarkReceiver(mDarkReceiver);
76         mNetworkController.removeCallback(mSignalCallback);
77         mTunerService.removeTunable(mTunable);
78         mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
79     }
80 
update()81     private void update() {
82         mView.update(mTunerService.getValue(KEY_SHOW_OPERATOR_NAME, 1) != 0,
83                 mTelephonyManager.isDataCapable(), getSubInfos());
84     }
85 
getSubInfos()86     private List<SubInfo> getSubInfos() {
87         List<SubInfo> result = new ArrayList<>();
88         List<SubscriptionInfo> subscritionInfos =
89                 mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
90 
91         for (SubscriptionInfo subscriptionInfo : subscritionInfos) {
92             int subId = subscriptionInfo.getSubscriptionId();
93             result.add(new SubInfo(
94                     subscriptionInfo.getCarrierName(),
95                     mKeyguardUpdateMonitor.getSimState(subId),
96                     mKeyguardUpdateMonitor.getServiceState(subId)));
97         }
98 
99         return result;
100     }
101 
102     /** Factory for constructing an {@link OperatorNameViewController}. */
103     public static class Factory {
104         private final DarkIconDispatcher mDarkIconDispatcher;
105         private final NetworkController mNetworkController;
106         private final TunerService mTunerService;
107         private final TelephonyManager mTelephonyManager;
108         private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
109 
110         @Inject
Factory(DarkIconDispatcher darkIconDispatcher, NetworkController networkController, TunerService tunerService, TelephonyManager telephonyManager, KeyguardUpdateMonitor keyguardUpdateMonitor)111         public Factory(DarkIconDispatcher darkIconDispatcher, NetworkController networkController,
112                 TunerService tunerService, TelephonyManager telephonyManager,
113                 KeyguardUpdateMonitor keyguardUpdateMonitor) {
114             mDarkIconDispatcher = darkIconDispatcher;
115             mNetworkController = networkController;
116             mTunerService = tunerService;
117             mTelephonyManager = telephonyManager;
118             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
119         }
120 
121         /** Create an {@link OperatorNameViewController}. */
create(OperatorNameView view)122         public OperatorNameViewController create(OperatorNameView view) {
123             return new OperatorNameViewController(view, mDarkIconDispatcher, mNetworkController,
124                     mTunerService, mTelephonyManager, mKeyguardUpdateMonitor);
125         }
126     }
127 
128     /**
129      * Needed because of how {@link CollapsedStatusBarFragment} works.
130      *
131      * Ideally this can be done internally.
132      **/
getView()133     public View getView() {
134         return mView;
135     }
136 
137     private final DarkIconDispatcher.DarkReceiver mDarkReceiver =
138             (area, darkIntensity, tint) ->
139                     mView.setTextColor(DarkIconDispatcher.getTint(area, mView, tint));
140 
141     private final SignalCallback mSignalCallback = new SignalCallback() {
142         @Override
143         public void setIsAirplaneMode(@NonNull IconState icon) {
144             update();
145         }
146     };
147 
148     private final TunerService.Tunable mTunable = (key, newValue) -> update();
149 
150 
151     private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
152             new KeyguardUpdateMonitorCallback() {
153         @Override
154         public void onRefreshCarrierInfo() {
155             mView.updateText(getSubInfos());
156         }
157     };
158 
159     // TODO: do we even register this anywhere?
160     private final DemoModeCommandReceiver mDemoModeCommandReceiver = new DemoModeCommandReceiver() {
161         @Override
162         public void onDemoModeStarted() {
163             mView.setDemoMode(true);
164         }
165 
166         @Override
167         public void onDemoModeFinished() {
168             mView.setDemoMode(false);
169             update();
170         }
171 
172         @Override
173         public void dispatchDemoCommand(String command, Bundle args) {
174             mView.setText(args.getString("name"));
175         }
176     };
177 
178     static class SubInfo {
179         private final CharSequence mCarrierName;
180         private final int mSimState;
181         private final ServiceState mServiceState;
182 
SubInfo(CharSequence carrierName, int simState, ServiceState serviceState)183         private SubInfo(CharSequence carrierName,
184                 int simState, ServiceState serviceState) {
185             mCarrierName = carrierName;
186             mSimState = simState;
187             mServiceState = serviceState;
188         }
189 
simReady()190         boolean simReady() {
191             return mSimState == TelephonyManager.SIM_STATE_READY;
192         }
193 
getCarrierName()194         CharSequence getCarrierName() {
195             return mCarrierName;
196         }
197 
stateInService()198         boolean stateInService() {
199             return mServiceState != null
200                     && mServiceState.getState() == ServiceState.STATE_IN_SERVICE;
201         }
202     }
203 }
204