ActivityBase.java revision 892781804513066b68b4a2fa6f846e862dac252a
1/* 2 * Copyright (C) 2009 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.camera; 18 19import android.app.Activity; 20import android.app.KeyguardManager; 21import android.content.ContentResolver; 22import android.content.Context; 23import android.content.Intent; 24import android.content.pm.ActivityInfo; 25import android.os.AsyncTask; 26import android.os.Bundle; 27import android.util.Log; 28import android.view.KeyEvent; 29import android.view.View; 30import android.view.WindowManager; 31 32import com.android.camera.ui.PopupManager; 33import com.android.camera.ui.RotateImageView; 34 35import java.io.File; 36 37/** 38 * Superclass of Camera and VideoCamera activities. 39 */ 40abstract public class ActivityBase extends Activity { 41 private static final String TAG = "ActivityBase"; 42 private static boolean LOGV = false; 43 private int mResultCodeForTesting; 44 private boolean mOnResumePending; 45 private Intent mResultDataForTesting; 46 private OnScreenHint mStorageHint; 47 protected CameraDevice mCameraDevice; 48 // The bitmap of the last captured picture thumbnail and the URI of the 49 // original picture. 50 protected Thumbnail mThumbnail; 51 // An imageview showing showing the last captured picture thumbnail. 52 protected RotateImageView mThumbnailView; 53 protected AsyncTask<Void, Void, Thumbnail> mLoadThumbnailTask; 54 55 @Override 56 public void onCreate(Bundle icicle) { 57 if (Util.isTabletUI()) { 58 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 59 } else { 60 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 61 } 62 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); 63 super.onCreate(icicle); 64 } 65 66 @Override 67 public void onWindowFocusChanged(boolean hasFocus) { 68 if (LOGV) Log.v(TAG, "onWindowFocusChanged.hasFocus=" + hasFocus 69 + ".mOnResumePending=" + mOnResumePending); 70 if (hasFocus && mOnResumePending) { 71 doOnResume(); 72 mOnResumePending = false; 73 } 74 } 75 76 @Override 77 protected void onResume() { 78 super.onResume(); 79 // Don't grab the camera if in use by lockscreen. For example, face 80 // unlock may be using the camera. Camera may be already opened in 81 // onCreate. doOnResume should continue if mCameraDevice != null. 82 // Suppose camera app is in the foreground. If users turn off and turn 83 // on the screen very fast, camera app can still have the focus when the 84 // lock screen shows up. The keyguard takes input focus, so the caemra 85 // app will lose focus when it is displayed. 86 if (LOGV) Log.v(TAG, "onResume. hasWindowFocus()=" + hasWindowFocus()); 87 if (mCameraDevice == null && isKeyguardLocked()) { 88 if (LOGV) Log.v(TAG, "onResume. mOnResumePending=true"); 89 mOnResumePending = true; 90 } else { 91 if (LOGV) Log.v(TAG, "onResume. mOnResumePending=false"); 92 doOnResume(); 93 mOnResumePending = false; 94 } 95 } 96 97 @Override 98 protected void onPause() { 99 if (LOGV) Log.v(TAG, "onPause"); 100 saveThumbnailToFile(); 101 super.onPause(); 102 103 if (mLoadThumbnailTask != null) { 104 mLoadThumbnailTask.cancel(true); 105 mLoadThumbnailTask = null; 106 } 107 108 if (mStorageHint != null) { 109 mStorageHint.cancel(); 110 mStorageHint = null; 111 } 112 113 mOnResumePending = false; 114 } 115 116 // Put the code of onResume in this method. 117 abstract protected void doOnResume(); 118 119 @Override 120 public boolean onSearchRequested() { 121 return false; 122 } 123 124 @Override 125 public boolean onKeyDown(int keyCode, KeyEvent event) { 126 // Prevent software keyboard or voice search from showing up. 127 if (keyCode == KeyEvent.KEYCODE_SEARCH 128 || keyCode == KeyEvent.KEYCODE_MENU) { 129 if (event.isLongPress()) return true; 130 } 131 132 return super.onKeyDown(keyCode, event); 133 } 134 135 protected void setResultEx(int resultCode) { 136 mResultCodeForTesting = resultCode; 137 setResult(resultCode); 138 } 139 140 protected void setResultEx(int resultCode, Intent data) { 141 mResultCodeForTesting = resultCode; 142 mResultDataForTesting = data; 143 setResult(resultCode, data); 144 } 145 146 public int getResultCode() { 147 return mResultCodeForTesting; 148 } 149 150 public Intent getResultData() { 151 return mResultDataForTesting; 152 } 153 154 @Override 155 protected void onDestroy() { 156 PopupManager.removeInstance(this); 157 super.onDestroy(); 158 } 159 160 private boolean isKeyguardLocked() { 161 KeyguardManager kgm = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); 162 if (LOGV) { 163 if (kgm != null) { 164 Log.v(TAG, "kgm.isKeyguardLocked()="+kgm.isKeyguardLocked() 165 + ". kgm.isKeyguardSecure()="+kgm.isKeyguardSecure()); 166 } 167 } 168 // isKeyguardSecure excludes the slide lock case. 169 return (kgm != null) && kgm.isKeyguardLocked() && kgm.isKeyguardSecure(); 170 } 171 172 protected void updateStorageHint(long storageSpace) { 173 String message = null; 174 if (storageSpace == Storage.UNAVAILABLE) { 175 message = getString(R.string.no_storage); 176 } else if (storageSpace == Storage.PREPARING) { 177 message = getString(R.string.preparing_sd); 178 } else if (storageSpace == Storage.UNKNOWN_SIZE) { 179 message = getString(R.string.access_sd_fail); 180 } else if (storageSpace < Storage.LOW_STORAGE_THRESHOLD) { 181 message = getString(R.string.spaceIsLow_content); 182 } 183 184 if (message != null) { 185 if (mStorageHint == null) { 186 mStorageHint = OnScreenHint.makeText(this, message); 187 } else { 188 mStorageHint.setText(message); 189 } 190 mStorageHint.show(); 191 } else if (mStorageHint != null) { 192 mStorageHint.cancel(); 193 mStorageHint = null; 194 } 195 } 196 197 private void updateThumbnailView() { 198 if (mThumbnail != null) { 199 mThumbnailView.setBitmap(mThumbnail.getBitmap()); 200 mThumbnailView.setVisibility(View.VISIBLE); 201 } else { 202 mThumbnailView.setBitmap(null); 203 mThumbnailView.setVisibility(View.GONE); 204 } 205 } 206 207 protected void getLastThumbnail() { 208 mThumbnail = ThumbnailHolder.getLastThumbnail(getContentResolver()); 209 // Suppose users tap the thumbnail view, go to the gallery, delete the 210 // image, and coming back to the camera. Thumbnail file will be invalid. 211 // Since the new thumbnail will be loaded in another thread later, the 212 // view should be set to gone to prevent from opening the invalid image. 213 updateThumbnailView(); 214 if (mThumbnail == null) { 215 mLoadThumbnailTask = new LoadThumbnailTask().execute(); 216 } 217 } 218 219 private class LoadThumbnailTask extends AsyncTask<Void, Void, Thumbnail> { 220 @Override 221 protected Thumbnail doInBackground(Void... params) { 222 // Load the thumbnail from the file. 223 ContentResolver resolver = getContentResolver(); 224 Thumbnail t = Thumbnail.getLastThumbnailFromFile(getFilesDir(), resolver); 225 226 if (isCancelled()) return null; 227 228 if (t == null) { 229 // Load the thumbnail from the media provider. 230 t = Thumbnail.getLastThumbnailFromContentResolver(resolver); 231 } 232 return t; 233 } 234 235 @Override 236 protected void onPostExecute(Thumbnail thumbnail) { 237 mThumbnail = thumbnail; 238 updateThumbnailView(); 239 } 240 } 241 242 protected void saveThumbnailToFile() { 243 if (mThumbnail != null && !mThumbnail.fromFile()) { 244 new SaveThumbnailTask().execute(mThumbnail); 245 } 246 } 247 248 private class SaveThumbnailTask extends AsyncTask<Thumbnail, Void, Void> { 249 @Override 250 protected Void doInBackground(Thumbnail... params) { 251 final int n = params.length; 252 final File filesDir = getFilesDir(); 253 for (int i = 0; i < n; i++) { 254 params[i].saveLastThumbnailToFile(filesDir); 255 } 256 return null; 257 } 258 } 259} 260