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