1 /* 2 * Copyright (C) 2012 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 package com.android.keyguard; 17 18 import android.animation.ObjectAnimator; 19 import android.app.ActivityManager; 20 import android.app.PendingIntent; 21 import android.app.SearchManager; 22 import android.app.admin.DevicePolicyManager; 23 import android.content.ComponentName; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.graphics.drawable.Drawable; 27 import android.os.Bundle; 28 import android.os.PowerManager; 29 import android.os.UserHandle; 30 import android.provider.Settings; 31 import android.telephony.TelephonyManager; 32 import android.util.AttributeSet; 33 import android.util.Log; 34 import android.util.Slog; 35 import android.view.View; 36 import android.widget.LinearLayout; 37 38 import com.android.internal.telephony.IccCardConstants.State; 39 import com.android.internal.widget.LockPatternUtils; 40 import com.android.internal.widget.multiwaveview.GlowPadView; 41 import com.android.internal.widget.multiwaveview.GlowPadView.OnTriggerListener; 42 43 public class KeyguardSelectorView extends LinearLayout implements KeyguardSecurityView { 44 private static final boolean DEBUG = KeyguardHostView.DEBUG; 45 private static final String TAG = "SecuritySelectorView"; 46 private static final String ASSIST_ICON_METADATA_NAME = 47 "com.android.systemui.action_assist_icon"; 48 49 private KeyguardSecurityCallback mCallback; 50 private GlowPadView mGlowPadView; 51 private ObjectAnimator mAnim; 52 private View mFadeView; 53 private boolean mIsBouncing; 54 private boolean mCameraDisabled; 55 private boolean mSearchDisabled; 56 private LockPatternUtils mLockPatternUtils; 57 private SecurityMessageDisplay mSecurityMessageDisplay; 58 private Drawable mBouncerFrame; 59 60 OnTriggerListener mOnTriggerListener = new OnTriggerListener() { 61 62 public void onTrigger(View v, int target) { 63 final int resId = mGlowPadView.getResourceIdForTarget(target); 64 65 switch (resId) { 66 case R.drawable.ic_action_assist_generic: 67 Intent assistIntent = 68 ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 69 .getAssistIntent(mContext, true, UserHandle.USER_CURRENT); 70 if (assistIntent != null) { 71 mActivityLauncher.launchActivity(assistIntent, false, true, null, null); 72 } else { 73 Log.w(TAG, "Failed to get intent for assist activity"); 74 } 75 mCallback.userActivity(0); 76 break; 77 78 case R.drawable.ic_lockscreen_camera: 79 mActivityLauncher.launchCamera(null, null); 80 mCallback.userActivity(0); 81 break; 82 83 case R.drawable.ic_lockscreen_unlock_phantom: 84 case R.drawable.ic_lockscreen_unlock: 85 mCallback.userActivity(0); 86 mCallback.dismiss(false); 87 break; 88 } 89 } 90 91 public void onReleased(View v, int handle) { 92 if (!mIsBouncing) { 93 doTransition(mFadeView, 1.0f); 94 } 95 } 96 97 public void onGrabbed(View v, int handle) { 98 mCallback.userActivity(0); 99 doTransition(mFadeView, 0.0f); 100 } 101 102 public void onGrabbedStateChange(View v, int handle) { 103 104 } 105 106 public void onFinishFinalAnimation() { 107 108 } 109 110 }; 111 112 KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { 113 114 @Override 115 public void onDevicePolicyManagerStateChanged() { 116 updateTargets(); 117 } 118 119 @Override 120 public void onSimStateChanged(State simState) { 121 updateTargets(); 122 } 123 }; 124 125 private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() { 126 127 @Override 128 KeyguardSecurityCallback getCallback() { 129 return mCallback; 130 } 131 132 @Override 133 LockPatternUtils getLockPatternUtils() { 134 return mLockPatternUtils; 135 } 136 137 @Override 138 Context getContext() { 139 return mContext; 140 }}; 141 142 public KeyguardSelectorView(Context context) { 143 this(context, null); 144 } 145 146 public KeyguardSelectorView(Context context, AttributeSet attrs) { 147 super(context, attrs); 148 mLockPatternUtils = new LockPatternUtils(getContext()); 149 } 150 151 @Override 152 protected void onFinishInflate() { 153 super.onFinishInflate(); 154 mGlowPadView = (GlowPadView) findViewById(R.id.glow_pad_view); 155 mGlowPadView.setOnTriggerListener(mOnTriggerListener); 156 updateTargets(); 157 158 mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); 159 View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame); 160 mBouncerFrame = bouncerFrameView.getBackground(); 161 } 162 163 public void setCarrierArea(View carrierArea) { 164 mFadeView = carrierArea; 165 } 166 167 public boolean isTargetPresent(int resId) { 168 return mGlowPadView.getTargetPosition(resId) != -1; 169 } 170 171 @Override 172 public void showUsabilityHint() { 173 mGlowPadView.ping(); 174 } 175 176 private void updateTargets() { 177 int currentUserHandle = mLockPatternUtils.getCurrentUser(); 178 DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager(); 179 int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, currentUserHandle); 180 boolean secureCameraDisabled = mLockPatternUtils.isSecure() 181 && (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0; 182 boolean cameraDisabledByAdmin = dpm.getCameraDisabled(null, currentUserHandle) 183 || secureCameraDisabled; 184 final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext()); 185 boolean disabledBySimState = monitor.isSimLocked(); 186 boolean cameraTargetPresent = 187 isTargetPresent(R.drawable.ic_lockscreen_camera); 188 boolean searchTargetPresent = 189 isTargetPresent(R.drawable.ic_action_assist_generic); 190 191 if (cameraDisabledByAdmin) { 192 Log.v(TAG, "Camera disabled by Device Policy"); 193 } else if (disabledBySimState) { 194 Log.v(TAG, "Camera disabled by Sim State"); 195 } 196 boolean currentUserSetup = 0 != Settings.Secure.getIntForUser( 197 mContext.getContentResolver(), 198 Settings.Secure.USER_SETUP_COMPLETE, 199 0 /*default */, 200 currentUserHandle); 201 boolean searchActionAvailable = 202 ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 203 .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null; 204 mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent 205 || !currentUserSetup; 206 mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent 207 || !currentUserSetup; 208 updateResources(); 209 } 210 211 public void updateResources() { 212 // Update the search icon with drawable from the search .apk 213 if (!mSearchDisabled) { 214 Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) 215 .getAssistIntent(mContext, false, UserHandle.USER_CURRENT); 216 if (intent != null) { 217 // XXX Hack. We need to substitute the icon here but haven't formalized 218 // the public API. The "_google" metadata will be going away, so 219 // DON'T USE IT! 220 ComponentName component = intent.getComponent(); 221 boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component, 222 ASSIST_ICON_METADATA_NAME + "_google", R.drawable.ic_action_assist_generic); 223 224 if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component, 225 ASSIST_ICON_METADATA_NAME, R.drawable.ic_action_assist_generic)) { 226 Slog.w(TAG, "Couldn't grab icon from package " + component); 227 } 228 } 229 } 230 231 mGlowPadView.setEnableTarget(R.drawable.ic_lockscreen_camera, !mCameraDisabled); 232 mGlowPadView.setEnableTarget(R.drawable.ic_action_assist_generic, !mSearchDisabled); 233 } 234 235 void doTransition(View view, float to) { 236 if (mAnim != null) { 237 mAnim.cancel(); 238 } 239 mAnim = ObjectAnimator.ofFloat(view, "alpha", to); 240 mAnim.start(); 241 } 242 243 public void setKeyguardCallback(KeyguardSecurityCallback callback) { 244 mCallback = callback; 245 } 246 247 public void setLockPatternUtils(LockPatternUtils utils) { 248 mLockPatternUtils = utils; 249 } 250 251 @Override 252 public void reset() { 253 mGlowPadView.reset(false); 254 } 255 256 @Override 257 public boolean needsInput() { 258 return false; 259 } 260 261 @Override 262 public void onPause() { 263 KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback); 264 } 265 266 @Override 267 public void onResume(int reason) { 268 KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback); 269 } 270 271 @Override 272 public KeyguardSecurityCallback getCallback() { 273 return mCallback; 274 } 275 276 @Override 277 public void showBouncer(int duration) { 278 mIsBouncing = true; 279 KeyguardSecurityViewHelper. 280 showBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration); 281 } 282 283 @Override 284 public void hideBouncer(int duration) { 285 mIsBouncing = false; 286 KeyguardSecurityViewHelper. 287 hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration); 288 } 289 } 290