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