1/*
2 * Copyright (C) 2014 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
17package com.android.systemui.qs.tiles;
18
19import android.content.BroadcastReceiver;
20import android.content.Context;
21import android.content.Intent;
22import android.content.IntentFilter;
23import android.os.UserManager;
24
25import android.provider.Settings;
26import android.provider.Settings.Global;
27import android.text.SpannableStringBuilder;
28import android.text.style.ForegroundColorSpan;
29import android.widget.Switch;
30
31import com.android.internal.logging.MetricsLogger;
32import com.android.internal.logging.MetricsProto.MetricsEvent;
33import com.android.systemui.R;
34import com.android.systemui.qs.GlobalSetting;
35import com.android.systemui.qs.QSTile;
36import com.android.systemui.statusbar.policy.HotspotController;
37
38/** Quick settings tile: Hotspot **/
39public class HotspotTile extends QSTile<QSTile.AirplaneBooleanState> {
40    private final AnimationIcon mEnable =
41            new AnimationIcon(R.drawable.ic_hotspot_enable_animation,
42                    R.drawable.ic_hotspot_disable);
43    private final AnimationIcon mDisable =
44            new AnimationIcon(R.drawable.ic_hotspot_disable_animation,
45                    R.drawable.ic_hotspot_enable);
46    private final Icon mDisableNoAnimation = ResourceIcon.get(R.drawable.ic_hotspot_enable);
47    private final Icon mUnavailable = ResourceIcon.get(R.drawable.ic_hotspot_unavailable);
48
49    private final HotspotController mController;
50    private final Callback mCallback = new Callback();
51    private final GlobalSetting mAirplaneMode;
52    private boolean mListening;
53
54    public HotspotTile(Host host) {
55        super(host);
56        mController = host.getHotspotController();
57        mAirplaneMode = new GlobalSetting(mContext, mHandler, Global.AIRPLANE_MODE_ON) {
58            @Override
59            protected void handleValueChanged(int value) {
60                refreshState();
61            }
62        };
63    }
64
65    @Override
66    public boolean isAvailable() {
67        return mController.isHotspotSupported();
68    }
69
70    @Override
71    protected void handleDestroy() {
72        super.handleDestroy();
73    }
74
75    @Override
76    public AirplaneBooleanState newTileState() {
77        return new AirplaneBooleanState();
78    }
79
80    @Override
81    public void setListening(boolean listening) {
82        if (mListening == listening) return;
83        mListening = listening;
84        if (listening) {
85            mController.addCallback(mCallback);
86            final IntentFilter filter = new IntentFilter();
87            filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
88            refreshState();
89        } else {
90            mController.removeCallback(mCallback);
91        }
92        mAirplaneMode.setListening(listening);
93    }
94
95    @Override
96    public Intent getLongClickIntent() {
97        return new Intent(Settings.ACTION_WIRELESS_SETTINGS);
98    }
99
100    @Override
101    protected void handleClick() {
102        final boolean isEnabled = (Boolean) mState.value;
103        if (!isEnabled && mAirplaneMode.getValue() != 0) {
104            return;
105        }
106        MetricsLogger.action(mContext, getMetricsCategory(), !isEnabled);
107        mController.setHotspotEnabled(!isEnabled);
108    }
109
110    @Override
111    public CharSequence getTileLabel() {
112        return mContext.getString(R.string.quick_settings_hotspot_label);
113    }
114
115    @Override
116    protected void handleUpdateState(AirplaneBooleanState state, Object arg) {
117        state.label = mContext.getString(R.string.quick_settings_hotspot_label);
118
119        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_CONFIG_TETHERING);
120        if (arg instanceof Boolean) {
121            state.value = (boolean) arg;
122        } else {
123            state.value = mController.isHotspotEnabled();
124        }
125        state.icon = state.value ? mEnable : mDisable;
126        boolean wasAirplane = state.isAirplaneMode;
127        state.isAirplaneMode = mAirplaneMode.getValue() != 0;
128        if (state.isAirplaneMode) {
129            final int disabledColor = mHost.getContext().getColor(R.color.qs_tile_tint_unavailable);
130            state.label = new SpannableStringBuilder().append(state.label,
131                    new ForegroundColorSpan(disabledColor),
132                    SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE);
133            state.icon = mUnavailable;
134        } else if (wasAirplane) {
135            state.icon = mDisableNoAnimation;
136        }
137        state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
138                = Switch.class.getName();
139        state.contentDescription = state.label;
140    }
141
142    @Override
143    public int getMetricsCategory() {
144        return MetricsEvent.QS_HOTSPOT;
145    }
146
147    @Override
148    protected String composeChangeAnnouncement() {
149        if (mState.value) {
150            return mContext.getString(R.string.accessibility_quick_settings_hotspot_changed_on);
151        } else {
152            return mContext.getString(R.string.accessibility_quick_settings_hotspot_changed_off);
153        }
154    }
155
156    private final class Callback implements HotspotController.Callback {
157        @Override
158        public void onHotspotChanged(boolean enabled) {
159            refreshState(enabled);
160        }
161    };
162}
163