blob: 74bc6984d137560a8bea0b27fc2d28021dfe29ee [file] [log] [blame]
Jorim Jaggia6310292014-04-16 14:11:52 +02001/*
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.statusbar.phone;
18
19import android.app.ActivityManagerNative;
20import android.app.admin.DevicePolicyManager;
21import android.content.BroadcastReceiver;
22import android.content.Context;
23import android.content.Intent;
24import android.content.IntentFilter;
Jorim Jaggi97b63c42014-05-02 23:03:34 +020025import android.content.pm.PackageManager;
Adrian Roosa06905b2014-05-28 12:13:48 +020026import android.content.pm.ResolveInfo;
Jorim Jaggia6310292014-04-16 14:11:52 +020027import android.os.RemoteException;
28import android.os.UserHandle;
29import android.provider.MediaStore;
30import android.util.AttributeSet;
31import android.util.Log;
Jorim Jaggia6310292014-04-16 14:11:52 +020032import android.view.View;
Jorim Jaggia6310292014-04-16 14:11:52 +020033import android.view.accessibility.AccessibilityManager;
Jorim Jaggia6310292014-04-16 14:11:52 +020034import android.widget.FrameLayout;
Adrian Roos2fe592d2014-05-17 03:11:59 +020035import android.widget.ImageView;
Adrian Roosa06905b2014-05-28 12:13:48 +020036
37import com.android.internal.widget.LockPatternUtils;
38import com.android.keyguard.KeyguardUpdateMonitor;
39import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jorim Jaggia6310292014-04-16 14:11:52 +020040import com.android.systemui.R;
Adrian Roos1e1d6ac2014-07-22 17:18:55 +020041import com.android.systemui.statusbar.policy.FlashlightController;
Jorim Jaggia6310292014-04-16 14:11:52 +020042
43/**
44 * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
45 * text.
46 */
Selim Cinek4c6969a2014-05-26 19:22:17 +020047public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
Jorim Jaggiecc798e2014-05-26 18:14:37 +020048 UnlockMethodCache.OnUnlockMethodChangedListener {
Jorim Jaggia6310292014-04-16 14:11:52 +020049
50 final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
51
Adrian Roosa06905b2014-05-28 12:13:48 +020052 private static final Intent SECURE_CAMERA_INTENT =
53 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
54 .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
55 private static final Intent INSECURE_CAMERA_INTENT =
56 new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
Jorim Jaggi97b63c42014-05-02 23:03:34 +020057 private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
58
Selim Cinek4c6969a2014-05-26 19:22:17 +020059 private ImageView mCameraImageView;
60 private ImageView mPhoneImageView;
Adrian Roos2fe592d2014-05-17 03:11:59 +020061 private ImageView mLockIcon;
Selim Cinekf99d0002014-06-13 07:36:01 +020062 private View mIndicationText;
Jorim Jaggi97b63c42014-05-02 23:03:34 +020063
Jorim Jaggi97b63c42014-05-02 23:03:34 +020064 private ActivityStarter mActivityStarter;
Jorim Jaggiecc798e2014-05-26 18:14:37 +020065 private UnlockMethodCache mUnlockMethodCache;
Adrian Roosa06905b2014-05-28 12:13:48 +020066 private LockPatternUtils mLockPatternUtils;
Adrian Roos1e1d6ac2014-07-22 17:18:55 +020067 private FlashlightController mFlashlightController;
Adrian Roos2fe592d2014-05-17 03:11:59 +020068
Jorim Jaggia6310292014-04-16 14:11:52 +020069 public KeyguardBottomAreaView(Context context) {
70 super(context);
71 }
72
73 public KeyguardBottomAreaView(Context context, AttributeSet attrs) {
74 super(context, attrs);
75 }
76
77 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) {
78 super(context, attrs, defStyleAttr);
79 }
80
81 public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
82 int defStyleRes) {
83 super(context, attrs, defStyleAttr, defStyleRes);
84 }
85
86 @Override
87 protected void onFinishInflate() {
88 super.onFinishInflate();
Adrian Roosa06905b2014-05-28 12:13:48 +020089 mLockPatternUtils = new LockPatternUtils(mContext);
Selim Cinek4c6969a2014-05-26 19:22:17 +020090 mCameraImageView = (ImageView) findViewById(R.id.camera_button);
91 mPhoneImageView = (ImageView) findViewById(R.id.phone_button);
Adrian Roos2fe592d2014-05-17 03:11:59 +020092 mLockIcon = (ImageView) findViewById(R.id.lock_icon);
Selim Cinekf99d0002014-06-13 07:36:01 +020093 mIndicationText = findViewById(R.id.keyguard_indication_text);
Adrian Roosa06905b2014-05-28 12:13:48 +020094 watchForCameraPolicyChanges();
Jorim Jaggia6310292014-04-16 14:11:52 +020095 watchForAccessibilityChanges();
96 updateCameraVisibility();
Jorim Jaggi97b63c42014-05-02 23:03:34 +020097 updatePhoneVisibility();
Jorim Jaggiecc798e2014-05-26 18:14:37 +020098 mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
99 mUnlockMethodCache.addListener(this);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200100 updateTrust();
Jorim Jaggia6310292014-04-16 14:11:52 +0200101 }
102
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200103 public void setActivityStarter(ActivityStarter activityStarter) {
104 mActivityStarter = activityStarter;
105 }
106
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200107 public void setFlashlightController(FlashlightController flashlightController) {
108 mFlashlightController = flashlightController;
109 }
110
Adrian Roosa06905b2014-05-28 12:13:48 +0200111 private Intent getCameraIntent() {
112 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
113 boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
114 mLockPatternUtils.getCurrentUser());
115 return mLockPatternUtils.isSecure() && !currentUserHasTrust
116 ? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
117 }
118
Jorim Jaggia6310292014-04-16 14:11:52 +0200119 private void updateCameraVisibility() {
Adrian Roosa06905b2014-05-28 12:13:48 +0200120 ResolveInfo resolved = mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
121 PackageManager.MATCH_DEFAULT_ONLY,
122 mLockPatternUtils.getCurrentUser());
123 boolean visible = !isCameraDisabledByDpm() && resolved != null;
Selim Cinek4c6969a2014-05-26 19:22:17 +0200124 mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
Jorim Jaggia6310292014-04-16 14:11:52 +0200125 }
126
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200127 private void updatePhoneVisibility() {
128 boolean visible = isPhoneVisible();
Selim Cinek4c6969a2014-05-26 19:22:17 +0200129 mPhoneImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200130 }
131
132 private boolean isPhoneVisible() {
133 PackageManager pm = mContext.getPackageManager();
134 return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
135 && pm.resolveActivity(PHONE_INTENT, 0) != null;
136 }
137
Jorim Jaggia6310292014-04-16 14:11:52 +0200138 private boolean isCameraDisabledByDpm() {
139 final DevicePolicyManager dpm =
140 (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
141 if (dpm != null) {
142 try {
143 final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
144 final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
145 final boolean disabledBecauseKeyguardSecure =
146 (disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
147 && KeyguardTouchDelegate.getInstance(getContext()).isSecure();
148 return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
149 } catch (RemoteException e) {
150 Log.e(TAG, "Can't get userId", e);
151 }
152 }
153 return false;
154 }
155
Adrian Roosa06905b2014-05-28 12:13:48 +0200156 private void watchForCameraPolicyChanges() {
Jorim Jaggia6310292014-04-16 14:11:52 +0200157 final IntentFilter filter = new IntentFilter();
158 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Adrian Roosa06905b2014-05-28 12:13:48 +0200159 getContext().registerReceiverAsUser(mDevicePolicyReceiver,
160 UserHandle.ALL, filter, null, null);
161 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
Jorim Jaggia6310292014-04-16 14:11:52 +0200162 }
163
164 private void watchForAccessibilityChanges() {
165 final AccessibilityManager am =
166 (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
167
168 // Set the initial state
169 enableAccessibility(am.isTouchExplorationEnabled());
170
171 // Watch for changes
172 am.addTouchExplorationStateChangeListener(
173 new AccessibilityManager.TouchExplorationStateChangeListener() {
174 @Override
175 public void onTouchExplorationStateChanged(boolean enabled) {
176 enableAccessibility(enabled);
177 }
178 });
179 }
180
181 private void enableAccessibility(boolean touchExplorationEnabled) {
Selim Cinek4c6969a2014-05-26 19:22:17 +0200182 mCameraImageView.setOnClickListener(touchExplorationEnabled ? this : null);
183 mCameraImageView.setClickable(touchExplorationEnabled);
184 mPhoneImageView.setOnClickListener(touchExplorationEnabled ? this : null);
185 mPhoneImageView.setClickable(touchExplorationEnabled);
Jorim Jaggia6310292014-04-16 14:11:52 +0200186 }
187
Selim Cinek4c6969a2014-05-26 19:22:17 +0200188 @Override
189 public void onClick(View v) {
190 if (v == mCameraImageView) {
191 launchCamera();
192 } else if (v == mPhoneImageView) {
193 launchPhone();
194 }
195 }
196
197 public void launchCamera() {
Adrian Roos1e1d6ac2014-07-22 17:18:55 +0200198 mFlashlightController.killFlashlight();
Adrian Roosa06905b2014-05-28 12:13:48 +0200199 Intent intent = getCameraIntent();
200 if (intent == SECURE_CAMERA_INTENT) {
201 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
202 } else {
203 mActivityStarter.startActivity(intent);
204 }
Jorim Jaggia6310292014-04-16 14:11:52 +0200205 }
206
Selim Cinek4c6969a2014-05-26 19:22:17 +0200207 public void launchPhone() {
Jorim Jaggi97b63c42014-05-02 23:03:34 +0200208 mActivityStarter.startActivity(PHONE_INTENT);
209 }
210
Adrian Roos2fe592d2014-05-17 03:11:59 +0200211
212 @Override
213 protected void onVisibilityChanged(View changedView, int visibility) {
214 super.onVisibilityChanged(changedView, visibility);
215 if (changedView == this && visibility == VISIBLE) {
216 updateTrust();
Adrian Roosa06905b2014-05-28 12:13:48 +0200217 updateCameraVisibility();
Adrian Roos2fe592d2014-05-17 03:11:59 +0200218 }
219 }
220
221 private void updateTrust() {
222 if (getVisibility() != VISIBLE) {
223 return;
224 }
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200225 int iconRes = mUnlockMethodCache.isMethodInsecure()
226 ? R.drawable.ic_lock_open_24dp
227 : R.drawable.ic_lock_24dp;
Adrian Roos2fe592d2014-05-17 03:11:59 +0200228 mLockIcon.setImageResource(iconRes);
229 }
230
Selim Cinek4c6969a2014-05-26 19:22:17 +0200231 public ImageView getPhoneImageView() {
232 return mPhoneImageView;
233 }
234
235 public ImageView getCameraImageView() {
236 return mCameraImageView;
237 }
238
239 public ImageView getLockIcon() {
240 return mLockIcon;
241 }
242
Selim Cinekf99d0002014-06-13 07:36:01 +0200243 public View getIndicationView() {
244 return mIndicationText;
245 }
246
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200247 @Override
Jorim Jaggi2580a9762014-06-25 03:08:25 +0200248 public boolean hasOverlappingRendering() {
249 return false;
250 }
251
252 @Override
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200253 public void onMethodSecureChanged(boolean methodSecure) {
254 updateTrust();
Adrian Roosa06905b2014-05-28 12:13:48 +0200255 updateCameraVisibility();
Jorim Jaggiecc798e2014-05-26 18:14:37 +0200256 }
Adrian Roosa06905b2014-05-28 12:13:48 +0200257
258 private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
259 public void onReceive(Context context, Intent intent) {
260 post(new Runnable() {
261 @Override
262 public void run() {
263 updateCameraVisibility();
264 }
265 });
266 }
267 };
268
269 private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
270 new KeyguardUpdateMonitorCallback() {
271 @Override
272 public void onUserSwitchComplete(int userId) {
273 updateCameraVisibility();
274 }
275 };
Jorim Jaggia6310292014-04-16 14:11:52 +0200276}