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