186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock/* 286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * Copyright (C) 2012 The Android Open Source Project 386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * 486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * you may not use this file except in compliance with the License. 686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * You may obtain a copy of the License at 786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * 886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * http://www.apache.org/licenses/LICENSE-2.0 986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * 1086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * Unless required by applicable law or agreed to in writing, software 1186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 1286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * See the License for the specific language governing permissions and 1486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock * limitations under the License. 1586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock */ 1686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 1786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockpackage com.android.internal.policy.impl.keyguard; 1886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 1986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.content.Context; 2086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.content.pm.PackageManager.NameNotFoundException; 21dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlockimport android.graphics.Bitmap; 22dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlockimport android.graphics.Canvas; 2386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.graphics.Color; 24737798271e6e5b9466acef26ead061ecf6d0f292John Spurlockimport android.graphics.Point; 2586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.os.Handler; 2686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.os.SystemClock; 2786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.util.Log; 2886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.view.LayoutInflater; 294b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlockimport android.view.MotionEvent; 3086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlockimport android.view.View; 31737798271e6e5b9466acef26ead061ecf6d0f292John Spurlockimport android.view.ViewGroup; 32e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlockimport android.view.WindowManager; 33dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlockimport android.widget.FrameLayout; 34dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlockimport android.widget.ImageView; 35dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlockimport android.widget.ImageView.ScaleType; 3686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 37c4842c11932ea4f60fe7ae09b0a59660207e1587Svetoslav Ganovimport com.android.internal.R; 38dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlockimport com.android.internal.policy.impl.keyguard.KeyguardActivityLauncher.CameraWidgetInfo; 3986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 404b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlockpublic class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener { 4186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private static final String TAG = CameraWidgetFrame.class.getSimpleName(); 4286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private static final boolean DEBUG = KeyguardHostView.DEBUG; 4357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private static final int WIDGET_ANIMATION_DURATION = 250; // ms 4457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private static final int WIDGET_WAIT_DURATION = 650; // ms 4557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private static final int RECOVERY_DELAY = 1000; // ms 4686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 4786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock interface Callbacks { 4886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock void onLaunchingCamera(); 4957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock void onCameraLaunchedSuccessfully(); 5057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock void onCameraLaunchedUnsuccessfully(); 5186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 5286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 5386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private final Handler mHandler = new Handler(); 54dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock private final KeyguardActivityLauncher mActivityLauncher; 5586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private final Callbacks mCallbacks; 56e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock private final WindowManager mWindowManager; 57737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock private final Point mRenderedSize = new Point(); 58bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock private final int[] mScreenLocation = new int[2]; 5986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 60dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock private View mWidgetView; 6186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private long mLaunchCameraStart; 624b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock private boolean mActive; 634b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock private boolean mTransitioning; 6457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private boolean mRecovering; 654b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock private boolean mDown; 6686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 6757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private final Runnable mTransitionToCameraRunnable = new Runnable() { 6857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock @Override 6957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock public void run() { 7057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock transitionToCamera(); 7157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock }}; 7257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock 7357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private final Runnable mTransitionToCameraEndAction = new Runnable() { 7486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock @Override 7586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock public void run() { 76dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock if (!mTransitioning) 77dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock return; 7857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock Handler worker = getWorkerHandler() != null ? getWorkerHandler() : mHandler; 7947cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock mLaunchCameraStart = SystemClock.uptimeMillis(); 80dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock if (DEBUG) Log.d(TAG, "Launching camera at " + mLaunchCameraStart); 8157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mActivityLauncher.launchCamera(worker, mSecureCameraActivityStartedRunnable); 8257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock }}; 8357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock 8457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private final Runnable mRecoverRunnable = new Runnable() { 8557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock @Override 8657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock public void run() { 8757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock recover(); 8857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock }}; 8957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock 9057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private final Runnable mRecoverEndAction = new Runnable() { 9157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock @Override 9257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock public void run() { 9357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock if (!mRecovering) 9457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock return; 9557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mCallbacks.onCameraLaunchedUnsuccessfully(); 9657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock reset(); 97dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock }}; 98dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock 99dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock private final Runnable mRenderRunnable = new Runnable() { 100dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock @Override 101dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock public void run() { 102dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock render(); 10386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock }}; 10486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 10557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private final Runnable mSecureCameraActivityStartedRunnable = new Runnable() { 1064b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock @Override 1074b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock public void run() { 10857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock onSecureCameraActivityStarted(); 10957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock } 11057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock }; 1114b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock 1126275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { 1136275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock private boolean mShowing; 1146275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock void onKeyguardVisibilityChanged(boolean showing) { 1156275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock if (mShowing == showing) 1166275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock return; 1176275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock mShowing = showing; 1186275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock CameraWidgetFrame.this.onKeyguardVisibilityChanged(mShowing); 1196275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock }; 1206275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock }; 1216275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock 122dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock private CameraWidgetFrame(Context context, Callbacks callbacks, 123dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock KeyguardActivityLauncher activityLauncher) { 12486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock super(context); 12586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock mCallbacks = callbacks; 126dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock mActivityLauncher = activityLauncher; 127e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 1286275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock KeyguardUpdateMonitor.getInstance(context).registerCallback(mCallback); 1296275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock if (DEBUG) Log.d(TAG, "new CameraWidgetFrame instance " + instanceId()); 130dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock } 13186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 132dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock public static CameraWidgetFrame create(Context context, Callbacks callbacks, 133dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock KeyguardActivityLauncher launcher) { 134dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock if (context == null || callbacks == null || launcher == null) 135dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock return null; 136dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock 137dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock CameraWidgetInfo widgetInfo = launcher.getCameraWidgetInfo(); 138dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock if (widgetInfo == null) 139dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock return null; 140dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock View widgetView = widgetInfo.layoutId > 0 ? 141dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock inflateWidgetView(context, widgetInfo) : 142dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock inflateGenericWidgetView(context); 143dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock if (widgetView == null) 144dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock return null; 145dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock 146dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock ImageView preview = new ImageView(context); 14747cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock preview.setLayoutParams(new FrameLayout.LayoutParams( 14847cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock FrameLayout.LayoutParams.MATCH_PARENT, 14947cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock FrameLayout.LayoutParams.MATCH_PARENT)); 150dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock preview.setScaleType(ScaleType.FIT_CENTER); 151c4842c11932ea4f60fe7ae09b0a59660207e1587Svetoslav Ganov preview.setContentDescription(preview.getContext().getString( 152c4842c11932ea4f60fe7ae09b0a59660207e1587Svetoslav Ganov R.string.keyguard_accessibility_camera)); 153dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock CameraWidgetFrame cameraWidgetFrame = new CameraWidgetFrame(context, callbacks, launcher); 154dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock cameraWidgetFrame.addView(preview); 155dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock cameraWidgetFrame.mWidgetView = widgetView; 1564b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock preview.setOnClickListener(cameraWidgetFrame); 157dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock return cameraWidgetFrame; 15886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 15986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 160dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock private static View inflateWidgetView(Context context, CameraWidgetInfo widgetInfo) { 1614b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock if (DEBUG) Log.d(TAG, "inflateWidgetView: " + widgetInfo.contextPackage); 162dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock View widgetView = null; 16386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock Exception exception = null; 16486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock try { 165dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock Context cameraContext = context.createPackageContext( 166dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock widgetInfo.contextPackage, Context.CONTEXT_RESTRICTED); 16786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock LayoutInflater cameraInflater = (LayoutInflater) 16886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock cameraContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 16986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock cameraInflater = cameraInflater.cloneInContext(cameraContext); 170dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock widgetView = cameraInflater.inflate(widgetInfo.layoutId, null, false); 17186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } catch (NameNotFoundException e) { 17286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock exception = e; 17386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } catch (RuntimeException e) { 17486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock exception = e; 17586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 17686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock if (exception != null) { 17786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock Log.w(TAG, "Error creating camera widget view", exception); 17886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 179dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock return widgetView; 180dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock } 181dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock 182dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock private static View inflateGenericWidgetView(Context context) { 1834b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock if (DEBUG) Log.d(TAG, "inflateGenericWidgetView"); 184dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock ImageView iv = new ImageView(context); 185dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock iv.setImageResource(com.android.internal.R.drawable.ic_lockscreen_camera); 186dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock iv.setScaleType(ScaleType.CENTER); 187dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock iv.setBackgroundColor(Color.argb(127, 0, 0, 0)); 188dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock return iv; 18986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 19086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 191dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock public void render() { 19237d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final Throwable[] thrown = new Throwable[1]; 19337d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final Bitmap[] offscreen = new Bitmap[1]; 19447cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock try { 19537d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final int width = getRootView().getWidth(); 19637d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final int height = getRootView().getHeight(); 197737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock if (mRenderedSize.x == width && mRenderedSize.y == height) { 19837d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s", 199737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock width, height)); 200737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock return; 201737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock } 20247cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock if (width == 0 || height == 0) { 20347cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock return; 20447cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock } 20537d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final long start = SystemClock.uptimeMillis(); 20637d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock offscreen[0] = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 20737d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final Canvas c = new Canvas(offscreen[0]); 20847cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock mWidgetView.measure( 20947cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 21047cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); 21147cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock mWidgetView.layout(0, 0, width, height); 21247cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock mWidgetView.draw(c); 21337d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock 21437d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final long end = SystemClock.uptimeMillis(); 21537d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock if (DEBUG) Log.d(TAG, String.format( 21637d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock "Rendered camera widget in %sms size=%sx%s instance=%s at %s", 21737d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock end - start, 21837d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock width, height, 2196275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock instanceId(), 22037d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock end)); 221737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock mRenderedSize.set(width, height); 22247cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock } catch (Throwable t) { 22337d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock thrown[0] = t; 22447cde77bc7ac5c3a1e486691596a7534ad855ff2John Spurlock } 22537d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock 22637d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock mHandler.post(new Runnable() { 22737d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock @Override 22837d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock public void run() { 22937d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock if (thrown[0] == null) { 23037d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock try { 23137d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock ((ImageView) getChildAt(0)).setImageBitmap(offscreen[0]); 23237d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock } catch (Throwable t) { 23337d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock thrown[0] = t; 23437d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock } 23537d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock } 23637d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock if (thrown[0] == null) 23737d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock return; 23837d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock 23937d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock Log.w(TAG, "Error rendering camera widget", thrown[0]); 24037d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock try { 24137d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock removeAllViews(); 24237d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final View genericView = inflateGenericWidgetView(mContext); 24337d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock addView(genericView); 24437d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock } catch (Throwable t) { 24537d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock Log.w(TAG, "Error inflating generic camera widget", t); 24637d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock } 24737d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock }}); 24886b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 24986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 25086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private void transitionToCamera() { 251bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (mTransitioning || mDown) return; 252cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock 2534b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mTransitioning = true; 254dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock 255cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final View child = getChildAt(0); 256cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final View root = getRootView(); 257cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock 258cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final int startWidth = child.getWidth(); 259cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final int startHeight = child.getHeight(); 260dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock 261cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final int finishWidth = root.getWidth(); 262cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final int finishHeight = root.getHeight(); 263dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock 264cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final float scaleX = (float) finishWidth / startWidth; 265cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final float scaleY = (float) finishHeight / startHeight; 266cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final float scale = Math.round( Math.max(scaleX, scaleY) * 100) / 100f; 267cfc3086b18396df03f982fb98112649dc5b5a6f2Adam Powell 268cfc3086b18396df03f982fb98112649dc5b5a6f2Adam Powell final int[] loc = new int[2]; 269cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock root.getLocationInWindow(loc); 270cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final int finishCenter = loc[1] + finishHeight / 2; 271cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock 272cfc3086b18396df03f982fb98112649dc5b5a6f2Adam Powell child.getLocationInWindow(loc); 273cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock final int startCenter = loc[1] + startHeight / 2; 274cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock 275cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock if (DEBUG) Log.d(TAG, String.format("Transitioning to camera. " + 276cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock "(start=%sx%s, finish=%sx%s, scale=%s,%s, startCenter=%s, finishCenter=%s)", 277cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock startWidth, startHeight, 278cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock finishWidth, finishHeight, 279cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock scaleX, scaleY, 280cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock startCenter, finishCenter)); 281cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock 282e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock enableWindowExitAnimation(false); 28386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock animate() 284dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock .scaleX(scale) 285dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock .scaleY(scale) 286cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock .translationY(finishCenter - startCenter) 287dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock .setDuration(WIDGET_ANIMATION_DURATION) 28857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock .withEndAction(mTransitionToCameraEndAction) 28986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock .start(); 290cf69c56b8336e2bd5c8e20f948cc80ca53e0c25aJohn Spurlock 29186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock mCallbacks.onLaunchingCamera(); 29286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 29386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 29457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private void recover() { 29557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock if (DEBUG) Log.d(TAG, "recovering at " + SystemClock.uptimeMillis()); 29657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mRecovering = true; 29757f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock animate() 29857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock .scaleX(1) 29957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock .scaleY(1) 30057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock .translationY(0) 30157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock .setDuration(WIDGET_ANIMATION_DURATION) 30257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock .withEndAction(mRecoverEndAction) 30357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock .start(); 30457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock } 30557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock 30686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock @Override 3074b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock public void onClick(View v) { 3084b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock if (DEBUG) Log.d(TAG, "clicked"); 3094b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock if (mTransitioning) return; 310bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (mActive) { 3114b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock cancelTransitionToCamera(); 3124b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock transitionToCamera(); 3134b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock } 3144b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock } 3154b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock 3164b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock @Override 3176275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock protected void onDetachedFromWindow() { 3186275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock if (DEBUG) Log.d(TAG, "onDetachedFromWindow: instance " + instanceId() 3196275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock + " at " + SystemClock.uptimeMillis()); 3206275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock super.onDetachedFromWindow(); 3216275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback); 32257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock cancelTransitionToCamera(); 32357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mHandler.removeCallbacks(mRecoverRunnable); 32486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 32586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 32686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock @Override 32786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock public void onActive(boolean isActive) { 3284b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mActive = isActive; 3294b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock if (mActive) { 3304b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock rescheduleTransitionToCamera(); 33186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } else { 33286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock reset(); 33386b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 33486b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 33586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 3364b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock @Override 337bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock public boolean onUserInteraction(MotionEvent event) { 338bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (mTransitioning) { 339bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (DEBUG) Log.d(TAG, "onUserInteraction eaten: mTransitioning"); 340bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock return true; 341bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock } 342bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock 343bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock getLocationOnScreen(mScreenLocation); 344bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock int rawBottom = mScreenLocation[1] + getHeight(); 345bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (event.getRawY() > rawBottom) { 346bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (DEBUG) Log.d(TAG, "onUserInteraction eaten: below widget"); 347bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock return true; 348bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock } 349bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock 350bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock int action = event.getAction(); 3514b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mDown = action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE; 352bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (mActive) { 3534b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock rescheduleTransitionToCamera(); 3544b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock } 355bb5c941149b66c0192736468bb60f47984dd5e1fJohn Spurlock if (DEBUG) Log.d(TAG, "onUserInteraction observed, not eaten"); 3564b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock return false; 3574b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock } 3584b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock 3594b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock @Override 3604b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock protected void onFocusLost() { 36157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock if (DEBUG) Log.d(TAG, "onFocusLost at " + SystemClock.uptimeMillis()); 3624b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock cancelTransitionToCamera(); 3634b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock super.onFocusLost(); 3644b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock } 3654b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock 366dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock public void onScreenTurnedOff() { 367dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock if (DEBUG) Log.d(TAG, "onScreenTurnedOff"); 368dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock reset(); 369dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock } 370dbe24b7def8df3a539790827d3f395f4d933802bJohn Spurlock 3714b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock private void rescheduleTransitionToCamera() { 3724b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock if (DEBUG) Log.d(TAG, "rescheduleTransitionToCamera at " + SystemClock.uptimeMillis()); 3734b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mHandler.removeCallbacks(mTransitionToCameraRunnable); 3744b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mHandler.postDelayed(mTransitionToCameraRunnable, WIDGET_WAIT_DURATION); 3754b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock } 3764b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock 3774b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock private void cancelTransitionToCamera() { 3784b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock if (DEBUG) Log.d(TAG, "cancelTransitionToCamera at " + SystemClock.uptimeMillis()); 3794b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mHandler.removeCallbacks(mTransitionToCameraRunnable); 3804b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock } 3814b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock 38286b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private void onCameraLaunched() { 38357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mCallbacks.onCameraLaunchedSuccessfully(); 3844b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock reset(); 38586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 38686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 38786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock private void reset() { 38857f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock if (DEBUG) Log.d(TAG, "reset at " + SystemClock.uptimeMillis()); 3894b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mLaunchCameraStart = 0; 3904b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mTransitioning = false; 39157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mRecovering = false; 3924b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock mDown = false; 3934b976ea1af04f8c340ef7e0d79f73d7cdb5eb72eJohn Spurlock cancelTransitionToCamera(); 39457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mHandler.removeCallbacks(mRecoverRunnable); 39586b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock animate().cancel(); 39686b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock setScaleX(1); 39786b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock setScaleY(1); 398cfc3086b18396df03f982fb98112649dc5b5a6f2Adam Powell setTranslationY(0); 399e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock enableWindowExitAnimation(true); 40086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 40186b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock 402dcc9681b0d4f52e1f441ef2abdda3eb949cc0c4bJohn Spurlock @Override 403737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock protected void onSizeChanged(int w, int h, int oldw, int oldh) { 404737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s", 405737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock w, h, oldw, oldh, SystemClock.uptimeMillis())); 40637d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock final Handler worker = getWorkerHandler(); 40737d84ae6051ab6d2add1e0ef51cf2aa2605c3225John Spurlock (worker != null ? worker : mHandler).post(mRenderRunnable); 408737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock super.onSizeChanged(w, h, oldw, oldh); 40986b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock } 410e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock 411e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock private void enableWindowExitAnimation(boolean isEnabled) { 412e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock View root = getRootView(); 413737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock ViewGroup.LayoutParams lp = root.getLayoutParams(); 414737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock if (!(lp instanceof WindowManager.LayoutParams)) 415737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock return; 416737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock WindowManager.LayoutParams wlp = (WindowManager.LayoutParams) lp; 417e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock int newWindowAnimations = isEnabled ? com.android.internal.R.style.Animation_LockScreen : 0; 418737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock if (newWindowAnimations != wlp.windowAnimations) { 41957f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock if (DEBUG) Log.d(TAG, "setting windowAnimations to: " + newWindowAnimations 42057f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock + " at " + SystemClock.uptimeMillis()); 421737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock wlp.windowAnimations = newWindowAnimations; 422737798271e6e5b9466acef26ead061ecf6d0f292John Spurlock mWindowManager.updateViewLayout(root, wlp); 423e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock } 424e2ac5207f204ee26ba43c033d9ffb51f7daee2bdJohn Spurlock } 4256275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock 4266275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock private void onKeyguardVisibilityChanged(boolean showing) { 4276275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged " + showing 4286275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock + " at " + SystemClock.uptimeMillis()); 4296275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock if (mTransitioning && !showing) { 4306275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock mTransitioning = false; 43157f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mRecovering = false; 43257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mHandler.removeCallbacks(mRecoverRunnable); 4336275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock if (mLaunchCameraStart > 0) { 4346275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock long launchTime = SystemClock.uptimeMillis() - mLaunchCameraStart; 4356275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock if (DEBUG) Log.d(TAG, String.format("Camera took %sms to launch", launchTime)); 4366275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock mLaunchCameraStart = 0; 4376275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock onCameraLaunched(); 4386275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock } 4396275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock } 4406275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock } 4416275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock 44257f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock private void onSecureCameraActivityStarted() { 44357f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock if (DEBUG) Log.d(TAG, "onSecureCameraActivityStarted at " + SystemClock.uptimeMillis()); 44457f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock mHandler.postDelayed(mRecoverRunnable, RECOVERY_DELAY); 44557f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock } 44657f928fc4afc02d2fe45523efea687eee7f86c02John Spurlock 4476275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock private String instanceId() { 4486275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock return Integer.toHexString(hashCode()); 4496275b3f1f3de7b0ca285e8f57a6d6014b0fa95b3John Spurlock } 45086b6357e5eb91950eac7de7ffe29e5a4ad32903bJohn Spurlock} 451