1b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos/* 2b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * Copyright (C) 2014 The Android Open Source Project 3b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * 4b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 5b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * you may not use this file except in compliance with the License. 6b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * You may obtain a copy of the License at 7b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * 8b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * http://www.apache.org/licenses/LICENSE-2.0 9b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * 10b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * Unless required by applicable law or agreed to in writing, software 11b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 12b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * See the License for the specific language governing permissions and 14b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos * limitations under the License 15b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos */ 16b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 17b83777ba5c12295224cd566bba59a44b8860e449Adrian Roospackage com.android.systemui.qs.tiles; 18b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 19bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.app.ActivityManager; 20bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlockimport android.os.SystemClock; 21bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 22b83777ba5c12295224cd566bba59a44b8860e449Adrian Roosimport com.android.systemui.R; 23b83777ba5c12295224cd566bba59a44b8860e449Adrian Roosimport com.android.systemui.qs.QSTile; 24b83777ba5c12295224cd566bba59a44b8860e449Adrian Roosimport com.android.systemui.statusbar.policy.FlashlightController; 25b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 26b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos/** Quick settings tile: Control flashlight **/ 27b83777ba5c12295224cd566bba59a44b8860e449Adrian Roospublic class FlashlightTile extends QSTile<QSTile.BooleanState> implements 28b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos FlashlightController.FlashlightListener { 29b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 30034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos /** Grace period for which we consider the flashlight 31034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos * still available because it was recently on. */ 32034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos private static final long RECENTLY_ON_DURATION_MILLIS = 500; 33034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos 34c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock private final AnimationIcon mEnable 35c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock = new AnimationIcon(R.drawable.ic_signal_flashlight_enable_animation); 36c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock private final AnimationIcon mDisable 37c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock = new AnimationIcon(R.drawable.ic_signal_flashlight_disable_animation); 38b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos private final FlashlightController mFlashlightController; 39034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos private long mWasLastOn; 40b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 41b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos public FlashlightTile(Host host) { 42b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos super(host); 43b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos mFlashlightController = host.getFlashlightController(); 44b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos mFlashlightController.addListener(this); 45b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 46b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 47b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 48bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock protected void handleDestroy() { 49bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock super.handleDestroy(); 50bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock mFlashlightController.removeListener(this); 51bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock } 52bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock 53bceed060f0090a4f86418c4515128d5ec8ebdd4aJohn Spurlock @Override 54b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos protected BooleanState newTileState() { 55b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos return new BooleanState(); 56b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 57b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 58b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 59b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos public void setListening(boolean listening) { 60b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 61b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 62b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 63b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos protected void handleUserSwitch(int newUserId) { 64b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 65b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 66b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 67b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos protected void handleClick() { 682649f6b22a2dbaed6faea4aba25020bd55a14c18Guang Zhu if (ActivityManager.isUserAMonkey()) { 692649f6b22a2dbaed6faea4aba25020bd55a14c18Guang Zhu return; 702649f6b22a2dbaed6faea4aba25020bd55a14c18Guang Zhu } 71b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos boolean newState = !mState.value; 72b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos mFlashlightController.setFlashlight(newState); 73c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE); 74b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 75b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 76b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 77b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos protected void handleUpdateState(BooleanState state, Object arg) { 78034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos if (state.value) { 79034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos mWasLastOn = SystemClock.uptimeMillis(); 80034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos } 81034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos 82c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock if (arg instanceof UserBoolean) { 83c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock state.value = ((UserBoolean) arg).value; 84b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 85034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos 86034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos if (!state.value && mWasLastOn != 0) { 87034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos if (SystemClock.uptimeMillis() > mWasLastOn + RECENTLY_ON_DURATION_MILLIS) { 88034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos mWasLastOn = 0; 89034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos } else { 90034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos mHandler.removeCallbacks(mRecentlyOnTimeout); 91034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos mHandler.postAtTime(mRecentlyOnTimeout, mWasLastOn + RECENTLY_ON_DURATION_MILLIS); 92034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos } 93034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos } 94034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos 95034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos // Always show the tile when the flashlight is or was recently on. This is needed because 96930aaa717eee0f5a578ba2cf68da95e725914609Adrian Roos // the camera is not available while it is being used for the flashlight. 97034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos state.visible = mWasLastOn != 0 || mFlashlightController.isAvailable(); 98b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label); 99c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock final AnimationIcon icon = state.value ? mEnable : mDisable; 100c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated); 101c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock state.icon = icon; 1024fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek int onOrOffId = state.value 1034fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek ? R.string.accessibility_quick_settings_flashlight_on 1044fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek : R.string.accessibility_quick_settings_flashlight_off; 1054fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek state.contentDescription = mContext.getString(onOrOffId); 1064fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek } 1074fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek 1084fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek @Override 1094fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek protected String composeChangeAnnouncement() { 1104fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek if (mState.value) { 1114fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek return mContext.getString(R.string.accessibility_quick_settings_flashlight_changed_on); 1124fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek } else { 1134fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek return mContext.getString(R.string.accessibility_quick_settings_flashlight_changed_off); 1144fda7b2d97c77c64bac0b44dc7a44597ad2c48b0Selim Cinek } 115b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 116b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 117b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 118b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos public void onFlashlightOff() { 119c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock refreshState(UserBoolean.BACKGROUND_FALSE); 120b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 121b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos 122b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos @Override 123b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos public void onFlashlightError() { 124c6df3cf273a6464005699796d148be0bfdf9e8c3John Spurlock refreshState(UserBoolean.BACKGROUND_FALSE); 125b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos } 126930aaa717eee0f5a578ba2cf68da95e725914609Adrian Roos 127930aaa717eee0f5a578ba2cf68da95e725914609Adrian Roos @Override 128930aaa717eee0f5a578ba2cf68da95e725914609Adrian Roos public void onFlashlightAvailabilityChanged(boolean available) { 129930aaa717eee0f5a578ba2cf68da95e725914609Adrian Roos refreshState(); 130930aaa717eee0f5a578ba2cf68da95e725914609Adrian Roos } 131034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos 132034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos private Runnable mRecentlyOnTimeout = new Runnable() { 133034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos @Override 134034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos public void run() { 135034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos refreshState(); 136034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos } 137034a6c9667b41506b0f6fa94617037717d7a9cd6Adrian Roos }; 138b83777ba5c12295224cd566bba59a44b8860e449Adrian Roos} 139