blob: 63698e440c88aa0111721644328b0c669961954a [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.systemui.statusbar.phone;
import android.app.ActivityManagerNative;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
* text.
*/
public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
UnlockMethodCache.OnUnlockMethodChangedListener {
final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
private static final Intent SECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
private static final Intent INSECURE_CAMERA_INTENT =
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
private ImageView mCameraImageView;
private ImageView mPhoneImageView;
private ImageView mLockIcon;
private View mIndicationText;
private ActivityStarter mActivityStarter;
private UnlockMethodCache mUnlockMethodCache;
private LockPatternUtils mLockPatternUtils;
public KeyguardBottomAreaView(Context context) {
super(context);
}
public KeyguardBottomAreaView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mLockPatternUtils = new LockPatternUtils(mContext);
mCameraImageView = (ImageView) findViewById(R.id.camera_button);
mPhoneImageView = (ImageView) findViewById(R.id.phone_button);
mLockIcon = (ImageView) findViewById(R.id.lock_icon);
mIndicationText = findViewById(R.id.keyguard_indication_text);
watchForCameraPolicyChanges();
watchForAccessibilityChanges();
updateCameraVisibility();
updatePhoneVisibility();
mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
mUnlockMethodCache.addListener(this);
updateTrust();
}
public void setActivityStarter(ActivityStarter activityStarter) {
mActivityStarter = activityStarter;
}
private Intent getCameraIntent() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
boolean currentUserHasTrust = updateMonitor.getUserHasTrust(
mLockPatternUtils.getCurrentUser());
return mLockPatternUtils.isSecure() && !currentUserHasTrust
? SECURE_CAMERA_INTENT : INSECURE_CAMERA_INTENT;
}
private void updateCameraVisibility() {
ResolveInfo resolved = mContext.getPackageManager().resolveActivityAsUser(getCameraIntent(),
PackageManager.MATCH_DEFAULT_ONLY,
mLockPatternUtils.getCurrentUser());
boolean visible = !isCameraDisabledByDpm() && resolved != null;
mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private void updatePhoneVisibility() {
boolean visible = isPhoneVisible();
mPhoneImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private boolean isPhoneVisible() {
PackageManager pm = mContext.getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
&& pm.resolveActivity(PHONE_INTENT, 0) != null;
}
private boolean isCameraDisabledByDpm() {
final DevicePolicyManager dpm =
(DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
if (dpm != null) {
try {
final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
final boolean disabledBecauseKeyguardSecure =
(disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
&& KeyguardTouchDelegate.getInstance(getContext()).isSecure();
return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
} catch (RemoteException e) {
Log.e(TAG, "Can't get userId", e);
}
}
return false;
}
private void watchForCameraPolicyChanges() {
final IntentFilter filter = new IntentFilter();
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
getContext().registerReceiverAsUser(mDevicePolicyReceiver,
UserHandle.ALL, filter, null, null);
KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mUpdateMonitorCallback);
}
private void watchForAccessibilityChanges() {
final AccessibilityManager am =
(AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
// Set the initial state
enableAccessibility(am.isTouchExplorationEnabled());
// Watch for changes
am.addTouchExplorationStateChangeListener(
new AccessibilityManager.TouchExplorationStateChangeListener() {
@Override
public void onTouchExplorationStateChanged(boolean enabled) {
enableAccessibility(enabled);
}
});
}
private void enableAccessibility(boolean touchExplorationEnabled) {
mCameraImageView.setOnClickListener(touchExplorationEnabled ? this : null);
mCameraImageView.setClickable(touchExplorationEnabled);
mPhoneImageView.setOnClickListener(touchExplorationEnabled ? this : null);
mPhoneImageView.setClickable(touchExplorationEnabled);
}
@Override
public void onClick(View v) {
if (v == mCameraImageView) {
launchCamera();
} else if (v == mPhoneImageView) {
launchPhone();
}
}
public void launchCamera() {
Intent intent = getCameraIntent();
if (intent == SECURE_CAMERA_INTENT) {
mContext.startActivityAsUser(intent, UserHandle.CURRENT);
} else {
mActivityStarter.startActivity(intent);
}
}
public void launchPhone() {
mActivityStarter.startActivity(PHONE_INTENT);
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (changedView == this && visibility == VISIBLE) {
updateTrust();
updateCameraVisibility();
}
}
private void updateTrust() {
if (getVisibility() != VISIBLE) {
return;
}
int iconRes = mUnlockMethodCache.isMethodInsecure()
? R.drawable.ic_lock_open_24dp
: R.drawable.ic_lock_24dp;
mLockIcon.setImageResource(iconRes);
}
public ImageView getPhoneImageView() {
return mPhoneImageView;
}
public ImageView getCameraImageView() {
return mCameraImageView;
}
public ImageView getLockIcon() {
return mLockIcon;
}
public View getIndicationView() {
return mIndicationText;
}
@Override
public void onMethodSecureChanged(boolean methodSecure) {
updateTrust();
updateCameraVisibility();
}
private final BroadcastReceiver mDevicePolicyReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
post(new Runnable() {
@Override
public void run() {
updateCameraVisibility();
}
});
}
};
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
public void onUserSwitchComplete(int userId) {
updateCameraVisibility();
}
};
}