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.Intent;
20import android.os.UserManager;
21import android.provider.Settings;
22import android.service.quicksettings.Tile;
23import android.widget.Switch;
24
25import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
26import com.android.systemui.Dependency;
27import com.android.systemui.R;
28import com.android.systemui.plugins.ActivityStarter;
29import com.android.systemui.qs.QSHost;
30import com.android.systemui.plugins.qs.QSTile.BooleanState;
31import com.android.systemui.qs.tileimpl.QSTileImpl;
32import com.android.systemui.statusbar.policy.KeyguardMonitor;
33import com.android.systemui.statusbar.policy.LocationController;
34import com.android.systemui.statusbar.policy.LocationController.LocationChangeCallback;
35
36/** Quick settings tile: Location **/
37public class LocationTile extends QSTileImpl<BooleanState> {
38
39    private final AnimationIcon mEnable =
40            new AnimationIcon(R.drawable.ic_signal_location_enable_animation,
41                    R.drawable.ic_signal_location_disable);
42    private final AnimationIcon mDisable =
43            new AnimationIcon(R.drawable.ic_signal_location_disable_animation,
44                    R.drawable.ic_signal_location_enable);
45
46    private final LocationController mController;
47    private final KeyguardMonitor mKeyguard;
48    private final Callback mCallback = new Callback();
49
50    public LocationTile(QSHost host) {
51        super(host);
52        mController = Dependency.get(LocationController.class);
53        mKeyguard = Dependency.get(KeyguardMonitor.class);
54    }
55
56    @Override
57    public BooleanState newTileState() {
58        return new BooleanState();
59    }
60
61    @Override
62    public void setListening(boolean listening) {
63        if (listening) {
64            mController.addCallback(mCallback);
65            mKeyguard.addCallback(mCallback);
66        } else {
67            mController.removeCallback(mCallback);
68            mKeyguard.removeCallback(mCallback);
69        }
70    }
71
72    @Override
73    public Intent getLongClickIntent() {
74        return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
75    }
76
77    @Override
78    protected void handleClick() {
79        if (mKeyguard.isSecure() && mKeyguard.isShowing()) {
80            Dependency.get(ActivityStarter.class).postQSRunnableDismissingKeyguard(() -> {
81                final boolean wasEnabled = mState.value;
82                mHost.openPanels();
83                mController.setLocationEnabled(!wasEnabled);
84            });
85            return;
86        }
87        final boolean wasEnabled = mState.value;
88        mController.setLocationEnabled(!wasEnabled);
89    }
90
91    @Override
92    public CharSequence getTileLabel() {
93        return mContext.getString(R.string.quick_settings_location_label);
94    }
95
96    @Override
97    protected void handleUpdateState(BooleanState state, Object arg) {
98        final boolean locationEnabled =  mController.isLocationEnabled();
99
100        // Work around for bug 15916487: don't show location tile on top of lock screen. After the
101        // bug is fixed, this should be reverted to only hiding it on secure lock screens:
102        // state.visible = !(mKeyguard.isSecure() && mKeyguard.isShowing());
103        state.value = locationEnabled;
104        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_SHARE_LOCATION);
105        if (locationEnabled) {
106            state.icon = mEnable;
107            state.label = mContext.getString(R.string.quick_settings_location_label);
108            state.contentDescription = mContext.getString(
109                    R.string.accessibility_quick_settings_location_on);
110        } else {
111            state.icon = mDisable;
112            state.label = mContext.getString(R.string.quick_settings_location_label);
113            state.contentDescription = mContext.getString(
114                    R.string.accessibility_quick_settings_location_off);
115        }
116        state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
117        state.expandedAccessibilityClassName = Switch.class.getName();
118    }
119
120    @Override
121    public int getMetricsCategory() {
122        return MetricsEvent.QS_LOCATION;
123    }
124
125    @Override
126    protected String composeChangeAnnouncement() {
127        if (mState.value) {
128            return mContext.getString(R.string.accessibility_quick_settings_location_changed_on);
129        } else {
130            return mContext.getString(R.string.accessibility_quick_settings_location_changed_off);
131        }
132    }
133
134    private final class Callback implements LocationChangeCallback,
135            KeyguardMonitor.Callback {
136        @Override
137        public void onLocationSettingsChanged(boolean enabled) {
138            refreshState();
139        }
140
141        @Override
142        public void onKeyguardShowingChanged() {
143            refreshState();
144        }
145    };
146}
147