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.os.Bundle;
20 import android.telephony.ServiceState;
21 import android.telephony.SubscriptionInfo;
22 import android.telephony.TelephonyManager;
23 import android.view.View;
24 
25 import com.android.keyguard.KeyguardUpdateMonitor;
26 import com.android.keyguard.KeyguardUpdateMonitorCallback;
27 import com.android.systemui.demomode.DemoModeCommandReceiver;
28 import com.android.systemui.plugins.DarkIconDispatcher;
29 import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
30 import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor;
31 import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy;
32 import com.android.systemui.tuner.TunerService;
33 import com.android.systemui.util.CarrierConfigTracker;
34 import com.android.systemui.util.ViewController;
35 import com.android.systemui.util.kotlin.JavaAdapter;
36 
37 import kotlinx.coroutines.Job;
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 TunerService mTunerService;
47     private final TelephonyManager mTelephonyManager;
48     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
49     private final CarrierConfigTracker mCarrierConfigTracker;
50     private final AirplaneModeInteractor mAirplaneModeInteractor;
51     private final SubscriptionManagerProxy mSubscriptionManagerProxy;
52     private final JavaAdapter mJavaAdapter;
53 
54     private Job mAirplaneModeJob;
55 
OperatorNameViewController(OperatorNameView view, DarkIconDispatcher darkIconDispatcher, TunerService tunerService, TelephonyManager telephonyManager, KeyguardUpdateMonitor keyguardUpdateMonitor, CarrierConfigTracker carrierConfigTracker, AirplaneModeInteractor airplaneModeInteractor, SubscriptionManagerProxy subscriptionManagerProxy, JavaAdapter javaAdapter)56     private OperatorNameViewController(OperatorNameView view,
57             DarkIconDispatcher darkIconDispatcher,
58             TunerService tunerService,
59             TelephonyManager telephonyManager,
60             KeyguardUpdateMonitor keyguardUpdateMonitor,
61             CarrierConfigTracker carrierConfigTracker,
62             AirplaneModeInteractor airplaneModeInteractor,
63             SubscriptionManagerProxy subscriptionManagerProxy,
64             JavaAdapter javaAdapter) {
65         super(view);
66         mDarkIconDispatcher = darkIconDispatcher;
67         mTunerService = tunerService;
68         mTelephonyManager = telephonyManager;
69         mKeyguardUpdateMonitor = keyguardUpdateMonitor;
70         mCarrierConfigTracker = carrierConfigTracker;
71         mAirplaneModeInteractor = airplaneModeInteractor;
72         mSubscriptionManagerProxy = subscriptionManagerProxy;
73         mJavaAdapter = javaAdapter;
74     }
75 
76     @Override
onViewAttached()77     protected void onViewAttached() {
78         mDarkIconDispatcher.addDarkReceiver(mDarkReceiver);
79         mAirplaneModeJob =
80                 mJavaAdapter.alwaysCollectFlow(
81                         mAirplaneModeInteractor.isAirplaneMode(),
82                         (isAirplaneMode) -> update());
83         mTunerService.addTunable(mTunable, KEY_SHOW_OPERATOR_NAME);
84         mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
85     }
86 
87     @Override
onViewDetached()88     protected void onViewDetached() {
89         mDarkIconDispatcher.removeDarkReceiver(mDarkReceiver);
90         mAirplaneModeJob.cancel(null);
91         mTunerService.removeTunable(mTunable);
92         mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback);
93     }
94 
update()95     private void update() {
96         SubInfo defaultSubInfo = getDefaultSubInfo();
97         boolean showOperatorName =
98                 mCarrierConfigTracker
99                         .getShowOperatorNameInStatusBarConfig(defaultSubInfo.getSubId())
100                         && (mTunerService.getValue(KEY_SHOW_OPERATOR_NAME, 1) != 0);
101         mView.update(
102                 showOperatorName,
103                 mTelephonyManager.isDataCapable(),
104                 mAirplaneModeInteractor.isAirplaneMode().getValue(),
105                 getDefaultSubInfo()
106         );
107     }
108 
getDefaultSubInfo()109     private SubInfo getDefaultSubInfo() {
110         int defaultSubId = mSubscriptionManagerProxy.getDefaultDataSubscriptionId();
111 
112         SubscriptionInfo sI = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(defaultSubId);
113         return new SubInfo(
114                 sI.getSubscriptionId(),
115                 sI.getCarrierName(),
116                 mKeyguardUpdateMonitor.getSimState(defaultSubId),
117                 mKeyguardUpdateMonitor.getServiceState(defaultSubId));
118     }
119 
120     /** Factory for constructing an {@link OperatorNameViewController}. */
121     public static class Factory {
122         private final DarkIconDispatcher mDarkIconDispatcher;
123         private final TunerService mTunerService;
124         private final TelephonyManager mTelephonyManager;
125         private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
126         private final CarrierConfigTracker mCarrierConfigTracker;
127         private final AirplaneModeInteractor mAirplaneModeInteractor;
128         private final SubscriptionManagerProxy mSubscriptionManagerProxy;
129         private final JavaAdapter mJavaAdapter;
130 
131         @Inject
Factory(DarkIconDispatcher darkIconDispatcher, TunerService tunerService, TelephonyManager telephonyManager, KeyguardUpdateMonitor keyguardUpdateMonitor, CarrierConfigTracker carrierConfigTracker, AirplaneModeInteractor airplaneModeInteractor, SubscriptionManagerProxy subscriptionManagerProxy, JavaAdapter javaAdapter)132         public Factory(DarkIconDispatcher darkIconDispatcher,
133                 TunerService tunerService,
134                 TelephonyManager telephonyManager,
135                 KeyguardUpdateMonitor keyguardUpdateMonitor,
136                 CarrierConfigTracker carrierConfigTracker,
137                 AirplaneModeInteractor airplaneModeInteractor,
138                 SubscriptionManagerProxy subscriptionManagerProxy,
139                 JavaAdapter javaAdapter) {
140             mDarkIconDispatcher = darkIconDispatcher;
141             mTunerService = tunerService;
142             mTelephonyManager = telephonyManager;
143             mKeyguardUpdateMonitor = keyguardUpdateMonitor;
144             mCarrierConfigTracker = carrierConfigTracker;
145             mAirplaneModeInteractor = airplaneModeInteractor;
146             mSubscriptionManagerProxy = subscriptionManagerProxy;
147             mJavaAdapter = javaAdapter;
148         }
149 
150         /** Create an {@link OperatorNameViewController}. */
create(OperatorNameView view)151         public OperatorNameViewController create(OperatorNameView view) {
152             return new OperatorNameViewController(view,
153                     mDarkIconDispatcher,
154                     mTunerService,
155                     mTelephonyManager,
156                     mKeyguardUpdateMonitor,
157                     mCarrierConfigTracker,
158                     mAirplaneModeInteractor,
159                     mSubscriptionManagerProxy,
160                     mJavaAdapter);
161         }
162     }
163 
164     /**
165      * Needed because of how {@link CollapsedStatusBarFragment} works.
166      *
167      * Ideally this can be done internally.
168      **/
getView()169     public View getView() {
170         return mView;
171     }
172 
173     private final DarkIconDispatcher.DarkReceiver mDarkReceiver =
174             (area, darkIntensity, tint) ->
175                     mView.setTextColor(DarkIconDispatcher.getTint(area, mView, tint));
176 
177     private final TunerService.Tunable mTunable = (key, newValue) -> update();
178 
179 
180     private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback =
181             new KeyguardUpdateMonitorCallback() {
182         @Override
183         public void onRefreshCarrierInfo() {
184             mView.updateText(getDefaultSubInfo());
185         }
186     };
187 
188     // TODO: do we even register this anywhere?
189     private final DemoModeCommandReceiver mDemoModeCommandReceiver = new DemoModeCommandReceiver() {
190         @Override
191         public void onDemoModeStarted() {
192             mView.setDemoMode(true);
193         }
194 
195         @Override
196         public void onDemoModeFinished() {
197             mView.setDemoMode(false);
198             update();
199         }
200 
201         @Override
202         public void dispatchDemoCommand(String command, Bundle args) {
203             mView.setText(args.getString("name"));
204         }
205     };
206 
207     static class SubInfo {
208         private final int mSubId;
209         private final CharSequence mCarrierName;
210         private final int mSimState;
211         private final ServiceState mServiceState;
212 
SubInfo( int subId, CharSequence carrierName, int simState, ServiceState serviceState)213         private SubInfo(
214                 int subId,
215                 CharSequence carrierName,
216                 int simState,
217                 ServiceState serviceState) {
218             mSubId = subId;
219             mCarrierName = carrierName;
220             mSimState = simState;
221             mServiceState = serviceState;
222         }
223 
getSubId()224         int getSubId() {
225             return mSubId;
226         }
227 
simReady()228         boolean simReady() {
229             return mSimState == TelephonyManager.SIM_STATE_READY;
230         }
231 
getCarrierName()232         CharSequence getCarrierName() {
233             return mCarrierName;
234         }
235 
stateInService()236         boolean stateInService() {
237             return mServiceState != null
238                     && mServiceState.getState() == ServiceState.STATE_IN_SERVICE;
239         }
240     }
241 }
242