Feature #1383 ยป 0001-make-Camera-work-on-lock-screen-secure-mode.patch
AndroidManifest.xml | ||
---|---|---|
45 | 45 |
<action android:name="android.media.action.STILL_IMAGE_CAMERA" /> |
46 | 46 |
<category android:name="android.intent.category.DEFAULT" /> |
47 | 47 |
</intent-filter> |
48 |
<intent-filter> |
|
49 |
<action android:name="android.media.action.IMAGE_CAPTURE_SECURE" /> |
|
50 |
<category android:name="android.intent.category.DEFAULT" /> |
|
51 |
</intent-filter> |
|
52 |
<intent-filter> |
|
53 |
<action android:name="android.media.action.STILL_IMAGE_CAMERA_SECURE" /> |
|
54 |
<category android:name="android.intent.category.DEFAULT" /> |
|
55 |
</intent-filter> |
|
48 | 56 |
</activity> |
49 | 57 |
<activity android:name="com.android.camera.VideoCamera" |
50 | 58 |
android:label="@string/video_camera_label" |
src/com/android/camera/ActivityBase.java | ||
---|---|---|
20 | 20 | |
21 | 21 |
import android.app.Activity; |
22 | 22 |
import android.app.KeyguardManager; |
23 |
import android.content.BroadcastReceiver; |
|
23 | 24 |
import android.content.Context; |
24 | 25 |
import android.content.Intent; |
26 |
import android.content.IntentFilter; |
|
25 | 27 |
import android.content.pm.ActivityInfo; |
26 | 28 |
import android.hardware.Camera; |
27 | 29 |
import android.os.Bundle; |
28 | 30 |
import android.util.Log; |
29 | 31 |
import android.view.KeyEvent; |
32 |
import android.view.WindowManager; |
|
30 | 33 | |
31 | 34 |
/** |
32 | 35 |
* Superclass of Camera and VideoCamera activities. |
... | ... | |
38 | 41 |
private boolean mOnResumePending; |
39 | 42 |
private Intent mResultDataForTesting; |
40 | 43 |
protected Camera mCameraDevice; |
44 |
// settings for lock screen camera |
|
45 |
protected static final String INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE = |
|
46 |
"android.media.action.STILL_IMAGE_CAMERA_SECURE"; |
|
47 |
protected static final String ACTION_IMAGE_CAPTURE_SECURE = |
|
48 |
"android.media.action.IMAGE_CAPTURE_SECURE"; |
|
41 | 49 | |
42 | 50 |
@Override |
43 | 51 |
public void onCreate(Bundle icicle) { |
... | ... | |
47 | 55 |
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); |
48 | 56 |
} |
49 | 57 |
super.onCreate(icicle); |
58 | ||
59 |
if(isCameraSecure()){ |
|
60 |
Log.v(TAG, "Starting in secure camera mode."); |
|
61 | ||
62 |
// show on lock screen |
|
63 |
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); |
|
64 | ||
65 |
// Filter for screen off so that we can finish secure camera activity |
|
66 |
// when screen is off. |
|
67 |
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); |
|
68 |
registerReceiver(mScreenOffReceiver, filter); |
|
69 |
} |
|
50 | 70 |
} |
51 | 71 | |
52 | 72 |
@Override |
... | ... | |
62 | 82 |
@Override |
63 | 83 |
protected void onResume() { |
64 | 84 |
super.onResume(); |
85 |
onResumeAfterSuper(); |
|
65 | 86 |
// Don't grab the camera if in use by lockscreen. For example, face |
66 | 87 |
// unlock may be using the camera. Camera may be already opened in |
67 | 88 |
// onCreate. doOnResume should continue if mCameraDevice != null. |
... | ... | |
127 | 148 | |
128 | 149 |
@Override |
129 | 150 |
protected void onDestroy() { |
151 |
if (isCameraSecure()) { |
|
152 |
unregisterReceiver(mScreenOffReceiver); |
|
153 |
} |
|
130 | 154 |
PopupManager.removeInstance(this); |
131 | 155 |
super.onDestroy(); |
132 | 156 |
} |
133 | 157 | |
134 |
private boolean isKeyguardLocked() {
|
|
158 |
protected boolean isKeyguardLocked() {
|
|
135 | 159 |
KeyguardManager kgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); |
136 | 160 |
if (LOGV) { |
137 | 161 |
if (kgm != null) { |
... | ... | |
142 | 166 |
// isKeyguardSecure excludes the slide lock case. |
143 | 167 |
return (kgm != null) && kgm.isKeyguardLocked() && kgm.isKeyguardSecure(); |
144 | 168 |
} |
169 | ||
170 |
protected boolean isCameraSecure() { |
|
171 |
// Check if this is in the secure camera mode. |
|
172 |
String action = getIntent().getAction(); |
|
173 |
if (INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE.equals(action) |
|
174 |
|| ACTION_IMAGE_CAPTURE_SECURE.equals(action)){ |
|
175 |
return true; |
|
176 |
} |
|
177 |
else{ |
|
178 |
return isKeyguardLocked(); |
|
179 |
} |
|
180 |
} |
|
181 | ||
182 |
// close activity when screen turns off |
|
183 |
protected BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() { |
|
184 |
@Override |
|
185 |
public void onReceive(Context context, Intent intent) { |
|
186 |
Log.v(TAG, "Finishing because screen turned off."); |
|
187 |
finish(); |
|
188 |
} |
|
189 |
}; |
|
190 | ||
191 |
// implemented in class Camera, class Video needs empty one |
|
192 |
public void onResumeAfterSuper() {}; |
|
145 | 193 |
} |
src/com/android/camera/Camera.java | ||
---|---|---|
100 | 100 |
private static final int SHOW_TAP_TO_FOCUS_TOAST = 6; |
101 | 101 |
private static final int UPDATE_THUMBNAIL = 7; |
102 | 102 | |
103 |
// This is the delay before we execute onResume tasks when coming |
|
104 |
// from the lock screen, to allow time for onPause to execute. |
|
105 |
private static final int ON_RESUME_TASKS_DELAY_MSEC = 20; |
|
106 | ||
103 | 107 |
// The subset of parameters we need to update in setCameraParameters(). |
104 | 108 |
private static final int UPDATE_PARAM_INITIALIZE = 1; |
105 | 109 |
private static final int UPDATE_PARAM_ZOOM = 2; |
... | ... | |
1345 | 1349 | |
1346 | 1350 |
@OnClickAttr |
1347 | 1351 |
public void onThumbnailClicked(View v) { |
1348 |
if (isCameraIdle() && mThumbnail != null) { |
|
1352 |
if (isCameraIdle() && mThumbnail != null && !isCameraSecure()) {
|
|
1349 | 1353 |
showSharePopup(); |
1350 | 1354 |
} |
1351 | 1355 |
} |
... | ... | |
2318 | 2322 |
mAeLockSupported = mInitialParams.isAutoExposureLockSupported(); |
2319 | 2323 |
mAwbLockSupported = mInitialParams.isAutoWhiteBalanceLockSupported(); |
2320 | 2324 |
} |
2325 | ||
2326 |
@Override |
|
2327 |
public void onResumeAfterSuper() { |
|
2328 |
// Add delay on resume from lock screen only, in order to to speed up |
|
2329 |
// the onResume --> onPause --> onResume cycle from lock screen. |
|
2330 |
// Don't do always because letting go of thread can cause delay. |
|
2331 |
String action = getIntent().getAction(); |
|
2332 |
if (isCameraSecure()) { |
|
2333 |
Log.v(TAG, "On resume, from lock screen."); |
|
2334 |
// Note: onPauseAfterSuper() will delete this runnable, so we will |
|
2335 |
// at most have 1 copy queued up. |
|
2336 |
mHandler.postDelayed(new Runnable() { |
|
2337 |
public void run() { |
|
2338 |
doOnResume(); |
|
2339 |
} |
|
2340 |
}, ON_RESUME_TASKS_DELAY_MSEC); |
|
2341 |
// show on lock screen |
|
2342 |
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); |
|
2343 |
} else { |
|
2344 |
Log.v(TAG, "On resume."); |
|
2345 |
doOnResume(); |
|
2346 |
} |
|
2347 |
} |
|
2321 | 2348 |
} |
src/com/android/camera/VideoCamera.java | ||
---|---|---|
608 | 608 | |
609 | 609 |
@OnClickAttr |
610 | 610 |
public void onThumbnailClicked(View v) { |
611 |
if (!mMediaRecorderRecording && mThumbnail != null) { |
|
611 |
if (!mMediaRecorderRecording && mThumbnail != null && !isCameraSecure()) {
|
|
612 | 612 |
showSharePopup(); |
613 | 613 |
} |
614 | 614 |
} |