CarrierServiceStateTracker.java revision 149f0d5d1ce3cebe17479d61454c33f700c3584b
1149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar/*
2149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Copyright (C) 2016 The Android Open Source Project
3149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *
4149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Licensed under the Apache License, Version 2.0 (the "License");
5149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * you may not use this file except in compliance with the License.
6149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * You may obtain a copy of the License at
7149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *
8149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *      http://www.apache.org/licenses/LICENSE-2.0
9149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *
10149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Unless required by applicable law or agreed to in writing, software
11149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * distributed under the License is distributed on an "AS IS" BASIS,
12149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * See the License for the specific language governing permissions and
14149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * limitations under the License.
15149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */
16149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
17149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarpackage com.android.internal.telephony;
18149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
19149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.PendingIntent;
20149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.Notification;
21149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.NotificationManager;
22149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.BroadcastReceiver;
23149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.Context;
24149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.Intent;
25149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.IntentFilter;
26149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.Handler;
27149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.Message;
28149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.PersistableBundle;
29149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.provider.Settings;
30149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.telephony.CarrierConfigManager;
31149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.telephony.Rlog;
32149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
33149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar/**
34149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * This contains Carrier specific logic based on the states/events
35149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * managed in ServiceStateTracker.
36149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * {@hide}
37149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */
38149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarpublic class CarrierServiceStateTracker extends Handler {
39149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final String LOG_TAG = "CSST";
40149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_BASE = 100;
41149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_VOICE_REGISTRATION = CARRIER_EVENT_BASE + 1;
42149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_VOICE_DEREGISTRATION = CARRIER_EVENT_BASE + 2;
43149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_DATA_REGISTRATION = CARRIER_EVENT_BASE + 3;
44149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_DATA_DEREGISTRATION = CARRIER_EVENT_BASE + 4;
45149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final int SHOW_NOTIFICATION = 200;
46149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final int NOTIFICATION_ID = 1000;
47149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final int UNINITIALIZED_DELAY_VALUE = -1;
48149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private int mDelay = UNINITIALIZED_DELAY_VALUE;
49149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private Phone mPhone;
50149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private boolean mIsPhoneRegistered = false;
51149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private ServiceStateTracker mSST;
52149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
53149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) {
54149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        this.mPhone = phone;
55149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        this.mSST = sst;
56149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter(
57149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
58149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
59149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
60149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    @Override
61149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    public void handleMessage(Message msg) {
62149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        switch (msg.what) {
63149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_VOICE_REGISTRATION:
64149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_DATA_REGISTRATION:
65149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                mIsPhoneRegistered = true;
66149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                handleConfigChanges();
67149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
68149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_VOICE_DEREGISTRATION:
69149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_DATA_DEREGISTRATION:
70149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                if (isGlobalModeOrRadioOffOrAirplaneMode()) {
71149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    break;
72149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                }
73149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                mIsPhoneRegistered = false;
74149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                handleConfigChanges();
75149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
76149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case SHOW_NOTIFICATION:
77149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                sendNotification();
78149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
79149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
80149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
81149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
82149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
83149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Returns true if the preferred network is set to 'Global' or the radio is off or in
84149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Airplane Mode else returns false.
85149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
86149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private boolean isGlobalModeOrRadioOffOrAirplaneMode() {
87149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
88149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        int preferredNetworkSetting = -1;
89149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        int airplaneMode = -1;
90149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        int subId = mPhone.getSubId();
91149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        try {
92149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            preferredNetworkSetting =
93149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    android.provider.Settings.Global.getInt(context.getContentResolver(),
94149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId,
95149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                            Phone.PREFERRED_NT_MODE);
96149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            airplaneMode = Settings.Global.getInt(context.getContentResolver(),
97149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    Settings.Global.AIRPLANE_MODE_ON, 0);
98149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        } catch (Exception e) {
99149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.e(LOG_TAG, "Unable to get PREFERRED_NETWORK_MODE.");
100149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            return true;
101149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
102149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        return ((preferredNetworkSetting == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) ||
103149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                !mSST.isRadioOn() || (airplaneMode != 0));
104149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
105149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
106149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
107149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Contains logic to decide when to create/cancel notifications.
108149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
109149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private void handleConfigChanges() {
110149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
111149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        if (mDelay == UNINITIALIZED_DELAY_VALUE) {
112149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            cancelNotification();
113149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            return;
114149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
115149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        // send a notification if the device is registerd to a network.
116149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        if (mIsPhoneRegistered) {
117149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            cancelNotification();
118149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.i(LOG_TAG, "canceling all notifications. ");
119149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        } else {
120149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Message notificationMsg;
121149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            notificationMsg = obtainMessage(SHOW_NOTIFICATION, null);
122149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.i(LOG_TAG, "starting timer for notifications. ");
123149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            sendMessageDelayed(notificationMsg, mDelay);
124149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
125149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
126149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
127149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
128149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        @Override
129149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        public void onReceive(Context context, Intent intent) {
130149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
131149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
132149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            PersistableBundle b = carrierConfigManager.getConfig();
133149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            mDelay = b.getInt(CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT);
134149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.i(LOG_TAG, "reading time to delay notification: " + mDelay);
135149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            handleConfigChanges();
136149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
137149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    };
138149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
139149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
140149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Post a notification to the NotificationManager for changing network type.
141149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
142149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private void sendNotification() {
143149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
144149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
145149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Rlog.i(LOG_TAG, "w/values: " + "," + mIsPhoneRegistered + "," + mDelay
146149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                + "," + isGlobalModeOrRadioOffOrAirplaneMode() + "," + mSST.isRadioOn());
147149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
148149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        // exit if the network preference is set to Global or if the phone is registered.
149149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        if (isGlobalModeOrRadioOffOrAirplaneMode() || mIsPhoneRegistered) {
150149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            return;
151149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
152149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
153149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        NotificationManager notificationManager = (NotificationManager)
154149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getSystemService(Context.NOTIFICATION_SERVICE);
155149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
156149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
157149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
158149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent,
159149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                PendingIntent.FLAG_ONE_SHOT);
160149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
161149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        CharSequence title =
162149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getText(com.android.internal.R.string.NetworkPreferenceSwitchTitle);
163149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        CharSequence details =
164149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getText(com.android.internal.R.string.NetworkPreferenceSwitchSummary);
165149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
166149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
167149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Notification mNotification = new Notification.Builder(context)
168149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setWhen(System.currentTimeMillis())
169149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setAutoCancel(true)
170149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
171149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setContentTitle(title)
172149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setColor(context.getResources().getColor(
173149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                        com.android.internal.R.color.system_notification_accent_color))
174149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setStyle(new Notification.BigTextStyle().bigText(details))
175149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setContentText(details)
176149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setContentIntent(settingsIntent)
177149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .build();
178149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
179149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        notificationManager.notify(NOTIFICATION_ID, mNotification);
180149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
181149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
182149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
183149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Cancel notifications if a registration is pending or has been sent.
184149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
185149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private void cancelNotification() {
186149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
187149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        mIsPhoneRegistered = true;
188149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        NotificationManager notificationManager = (NotificationManager)
189149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getSystemService(Context.NOTIFICATION_SERVICE);
190149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        notificationManager.cancel(NOTIFICATION_ID);
191149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
192149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar}