KeyguardSelectorView.java revision dcb3d84b82cc2448d04e73359a716581bfb657db
136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn/* 236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * Copyright (C) 2012 The Android Open Source Project 336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * 436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * you may not use this file except in compliance with the License. 636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * You may obtain a copy of the License at 736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * 836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * 1036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * See the License for the specific language governing permissions and 1436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn * limitations under the License. 1536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn */ 1636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornpackage com.android.internal.policy.impl.keyguard; 1736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 1836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.animation.ObjectAnimator; 1936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.app.ActivityManagerNative; 2036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.app.SearchManager; 2136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.content.ActivityNotFoundException; 2236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.content.ComponentName; 2336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.content.Context; 2436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.content.Intent; 2536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.os.RemoteException; 2636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.os.UserHandle; 2736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.provider.MediaStore; 2836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.util.AttributeSet; 2936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.util.Log; 3036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.util.Slog; 3136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.view.View; 3236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.widget.Button; 3336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport android.widget.LinearLayout; 3436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 3536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport com.android.internal.telephony.IccCardConstants; 3636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport com.android.internal.widget.LockPatternUtils; 3736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport com.android.internal.widget.multiwaveview.GlowPadView; 3836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener; 3936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornimport com.android.internal.R; 4036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 4136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackbornpublic class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView { 4236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private static final boolean DEBUG = KeyguardHostView.DEBUG; 4336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private static final String TAG = "SecuritySelectorView"; 4436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private static final String ASSIST_ICON_METADATA_NAME = 4536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn "com.android.systemui.action_assist_icon"; 4636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private KeyguardSecurityCallback mCallback; 4736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private GlowPadView mGlowPadView; 4836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private Button mEmergencyCallButton; 4936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private ObjectAnimator mAnim; 5036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private boolean mCameraDisabled; 5136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private boolean mSearchDisabled; 5236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn private LockPatternUtils mLockPatternUtils; 5336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 5436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn OnTriggerListener mOnTriggerListener = new OnTriggerListener() { 5536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 5636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public void onTrigger(View v, int target) { 5736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn final int resId = mGlowPadView.getResourceIdForTarget(target); 5836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn switch (resId) { 5936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn case com.android.internal.R.drawable.ic_action_assist_generic: 6036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn Intent assistIntent = 6136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 6236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn .getAssistIntent(mContext, UserHandle.USER_CURRENT); 6336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn if (assistIntent != null) { 6436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn launchActivity(assistIntent); 6536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } else { 6636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn Log.w(TAG, "Failed to get intent for assist activity"); 6736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 6836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mCallback.userActivity(0); 6936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn break; 7036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 7136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn case com.android.internal.R.drawable.ic_lockscreen_camera: 7236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn launchActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)); 7336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mCallback.userActivity(0); 7436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn break; 7536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 7636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn case com.android.internal.R.drawable.ic_lockscreen_unlock_phantom: 7736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn case com.android.internal.R.drawable.ic_lockscreen_unlock: 7836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn mCallback.dismiss(false); 7936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn break; 8036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 8136cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 8236cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 8336cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public void onReleased(View v, int handle) { 8436cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn doTransition(mEmergencyCallButton, 1.0f); 8536cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 8636cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 8736cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn public void onGrabbed(View v, int handle) { 8836cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn doTransition(mEmergencyCallButton, 0.0f); 8936cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn } 9036cd41f8efa6f6a683d3353d309ff548295af9e9Dianne Hackborn 91 public void onGrabbedStateChange(View v, int handle) { 92 93 } 94 95 public void onFinishFinalAnimation() { 96 97 } 98 99 }; 100 101 KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { 102 103 private boolean mEmergencyDialerDisableBecauseSimLocked; 104 105 @Override 106 public void onDevicePolicyManagerStateChanged() { 107 updateTargets(); 108 } 109 110 @Override 111 public void onSimStateChanged(IccCardConstants.State simState) { 112 // Some carriers aren't capable of handling emergency calls while the SIM is locked 113 mEmergencyDialerDisableBecauseSimLocked = KeyguardUpdateMonitor.isSimLocked(simState) 114 && !mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked(); 115 updateTargets(); 116 } 117 118 void onPhoneStateChanged(int phoneState) { 119 if (mEmergencyCallButton != null) { 120 mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked(); 121 mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton, 122 phoneState, !mEmergencyDialerDisableBecauseSimLocked); 123 } 124 }; 125 }; 126 127 public KeyguardSelectorView(Context context) { 128 this(context, null); 129 } 130 131 public KeyguardSelectorView(Context context, AttributeSet attrs) { 132 super(context, attrs); 133 mLockPatternUtils = new LockPatternUtils(getContext()); 134 } 135 136 @Override 137 protected void onFinishInflate() { 138 super.onFinishInflate(); 139 mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view); 140 mGlowPadView.setOnTriggerListener(mOnTriggerListener); 141 mEmergencyCallButton = (Button) findViewById(R.id.emergency_call_button); 142 KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mInfoCallback); 143 updateTargets(); 144 } 145 146 public boolean isTargetPresent(int resId) { 147 return mGlowPadView.getTargetPosition(resId) != -1; 148 } 149 150 private void updateTargets() { 151 boolean disabledByAdmin = mLockPatternUtils.getDevicePolicyManager() 152 .getCameraDisabled(null); 153 final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext()); 154 boolean disabledBySimState = monitor.isSimLocked(); 155 boolean cameraTargetPresent = 156 isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_camera); 157 boolean searchTargetPresent = 158 isTargetPresent(com.android.internal.R.drawable.ic_action_assist_generic); 159 160 if (disabledByAdmin) { 161 Log.v(TAG, "Camera disabled by Device Policy"); 162 } else if (disabledBySimState) { 163 Log.v(TAG, "Camera disabled by Sim State"); 164 } 165 boolean searchActionAvailable = 166 ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 167 .getAssistIntent(mContext, UserHandle.USER_CURRENT) != null; 168 mCameraDisabled = disabledByAdmin || disabledBySimState || !cameraTargetPresent; 169 mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent; 170 updateResources(); 171 } 172 173 public void updateResources() { 174 // Update the search icon with drawable from the search .apk 175 if (!mSearchDisabled) { 176 Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 177 .getAssistIntent(mContext, UserHandle.USER_CURRENT); 178 if (intent != null) { 179 // XXX Hack. We need to substitute the icon here but haven't formalized 180 // the public API. The "_google" metadata will be going away, so 181 // DON'T USE IT! 182 ComponentName component = intent.getComponent(); 183 boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component, 184 ASSIST_ICON_METADATA_NAME + "_google", 185 com.android.internal.R.drawable.ic_action_assist_generic); 186 187 if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component, 188 ASSIST_ICON_METADATA_NAME, 189 com.android.internal.R.drawable.ic_action_assist_generic)) { 190 Slog.w(TAG, "Couldn't grab icon from package " + component); 191 } 192 } 193 } 194 195 mGlowPadView.setEnableTarget(com.android.internal.R.drawable 196 .ic_lockscreen_camera, !mCameraDisabled); 197 mGlowPadView.setEnableTarget(com.android.internal.R.drawable 198 .ic_action_assist_generic, !mSearchDisabled); 199 } 200 201 void doTransition(Object v, float to) { 202 if (mAnim != null) { 203 mAnim.cancel(); 204 } 205 mAnim = ObjectAnimator.ofFloat(mEmergencyCallButton, "alpha", to); 206 mAnim.start(); 207 } 208 209 public void setKeyguardCallback(KeyguardSecurityCallback callback) { 210 mCallback = callback; 211 } 212 213 public void setLockPatternUtils(LockPatternUtils utils) { 214 mLockPatternUtils = utils; 215 } 216 217 /** 218 * Launches the said intent for the current foreground user. 219 * @param intent 220 */ 221 private void launchActivity(Intent intent) { 222 intent.setFlags( 223 Intent.FLAG_ACTIVITY_NEW_TASK 224 | Intent.FLAG_ACTIVITY_SINGLE_TOP 225 | Intent.FLAG_ACTIVITY_CLEAR_TOP); 226 try { 227 ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity(); 228 } catch (RemoteException e) { 229 Log.w(TAG, "can't dismiss keyguard on launch"); 230 } 231 try { 232 mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT)); 233 } catch (ActivityNotFoundException e) { 234 Log.w(TAG, "Activity not found for intent + " + intent.getAction()); 235 } 236 } 237 238 @Override 239 public void reset() { 240 mGlowPadView.reset(false); 241 } 242 243 @Override 244 public boolean needsInput() { 245 return false; 246 } 247 248 @Override 249 public void onPause() { 250 KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mInfoCallback); 251 } 252 253 @Override 254 public void onResume() { 255 KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mInfoCallback); 256 } 257 258 @Override 259 public KeyguardSecurityCallback getCallback() { 260 return mCallback; 261 } 262 263} 264