diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/com/android/camera/CameraActivity.java | 10 | ||||
-rwxr-xr-x | src/com/android/camera/CaptureModule.java | 94 | ||||
-rwxr-xr-x | src/com/android/camera/CaptureUI.java | 5 | ||||
-rwxr-xr-x | src/com/android/camera/LocationManager.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/MediaSaveService.java | 68 | ||||
-rwxr-xr-x | src/com/android/camera/PermissionsActivity.java | 4 | ||||
-rwxr-xr-x[-rw-r--r--] | src/com/android/camera/PhotoModule.java | 2 | ||||
-rwxr-xr-x | src/com/android/camera/SettingsActivity.java | 186 | ||||
-rwxr-xr-x | src/com/android/camera/SettingsManager.java | 54 | ||||
-rwxr-xr-x | src/com/android/camera/Storage.java | 66 | ||||
-rwxr-xr-x | src/com/android/camera/imageprocessor/PostProcessor.java | 22 | ||||
-rwxr-xr-x | src/com/android/camera/util/VendorTagUtil.java | 49 |
12 files changed, 538 insertions, 24 deletions
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index 9e1855ff3..f776d8ddd 100755 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -169,7 +169,7 @@ public class CameraActivity extends Activity private static final int SWITCH_SAVE_PATH = 2; /** Permission request code */ - private static final int PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1; + private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1; /** Whether onResume should reset the view to the preview. */ private boolean mResetToPreviewOnResume = true; @@ -2048,13 +2048,13 @@ public class CameraActivity extends Activity } public void requestLocationPermission() { - if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) + if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { Log.v(TAG, "Request Location permission"); mCurrentModule.waitingLocationPermissionResult(true); requestPermissions( - new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, - PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION); + new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, + PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION); } } @@ -2062,7 +2062,7 @@ public class CameraActivity extends Activity public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { - case PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION: { + case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: { // If request is cancelled, the result arrays are empty. mCurrentModule.waitingLocationPermissionResult(false); if (grantResults.length > 0 diff --git a/src/com/android/camera/CaptureModule.java b/src/com/android/camera/CaptureModule.java index 4343a46cd..f785d1146 100755 --- a/src/com/android/camera/CaptureModule.java +++ b/src/com/android/camera/CaptureModule.java @@ -31,6 +31,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Matrix; import android.graphics.Point; @@ -137,6 +138,8 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.Date; import java.util.LinkedList; import java.util.List; @@ -269,6 +272,12 @@ public class CaptureModule implements CameraModule, PhotoController, public static CameraCharacteristics.Key<long[]> EXPOSURE_RANGE = new CameraCharacteristics.Key<>("org.codeaurora.qcamera3.iso_exp_priority.exposure_time_range", long[].class); + // manual WB color temperature and gains + public static CameraCharacteristics.Key<int[]> WB_COLOR_TEMPERATURE_RANGE = + new CameraCharacteristics.Key<>("org.codeaurora.qcamera3.manualWB.color_temperature_range", int[].class); + public static CameraCharacteristics.Key<float[]> WB_RGB_GAINS_RANGE = + new CameraCharacteristics.Key<>("org.codeaurora.qcamera3.manualWB.gains_range", float[].class); + public static CameraCharacteristics.Key<Integer> buckets = new CameraCharacteristics.Key<>("org.codeaurora.qcamera3.histogram.buckets", Integer.class); public static CameraCharacteristics.Key<Integer> maxCount = @@ -1489,7 +1498,11 @@ public class CaptureModule implements CameraModule, PhotoController, if(mFrameProcessor.isFrameFilterEnabled() && !mDeepPortraitMode) { mActivity.runOnUiThread(new Runnable() { public void run() { - mUI.getSurfaceHolder().setFixedSize(mPreviewSize.getHeight(), mPreviewSize.getWidth()); + SurfaceHolder surfaceHolder = mUI.getSurfaceHolder(); + if (surfaceHolder != null) { + surfaceHolder.setFixedSize( + mPreviewSize.getHeight(), mPreviewSize.getWidth()); + } } }); } @@ -2422,6 +2435,24 @@ public class CaptureModule implements CameraModule, PhotoController, byte[] bytes = getJpegData(image); + if (mSettingsManager.getSavePictureFormat() == + SettingsManager.HEIF_FORMAT) { + String value = mSettingsManager.getValue( + SettingsManager.KEY_JPEG_QUALITY); + int qualityNumber = getQualityNumber(value); + mActivity.getMediaSaveService().addHEIFImageFromJpeg(bytes, + title,date,null,image.getWidth(),image.getHeight(), + 0,null,mContentResolver, + mOnMediaSavedListener,qualityNumber,"heif"); + image.close(); + if (mLongshotActive) { + mLastJpegData = bytes; + } else { + mActivity.updateThumbnail(bytes); + } + return; + } + if (image.getFormat() == ImageFormat.RAW10) { mActivity.getMediaSaveService().addRawImage(bytes, title, "raw"); @@ -2797,6 +2828,7 @@ public class CaptureModule implements CameraModule, PhotoController, applyAWBCCTAndAgain(builder); applyBGStats(builder); applyBEStats(builder); + applyWbColorTemperature(builder); } /** @@ -3778,10 +3810,17 @@ public class CaptureModule implements CameraModule, PhotoController, mPictureSize = parsePictureSize(pictureSize); Size[] prevSizes = mSettingsManager.getSupportedOutputSize(getMainCameraId(), SurfaceHolder.class); - mSupportedMaxPictureSize = prevSizes[0]; + List<Size> prevSizeList = Arrays.asList(prevSizes); + prevSizeList.sort((o1,o2) -> o2.getWidth()*o2.getHeight() - o1.getWidth()*o1.getHeight()); + mSupportedMaxPictureSize = prevSizeList.get(0); Size[] rawSize = mSettingsManager.getSupportedOutputSize(getMainCameraId(), ImageFormat.RAW10); - mSupportedRawPictureSize = rawSize[0]; + if (rawSize == null || rawSize.length == 0) { + mSupportedRawPictureSize = null; + mSaveRaw = false; + } else { + mSupportedRawPictureSize = rawSize[0]; + } mPreviewSize = getOptimalPreviewSize(mPictureSize, prevSizes); Size[] thumbSizes = mSettingsManager.getSupportedThumbnailSizes(getMainCameraId()); mPictureThumbSize = getOptimalPreviewSize(mPictureSize, thumbSizes); // get largest thumb size @@ -4164,7 +4203,11 @@ public class CaptureModule implements CameraModule, PhotoController, if (mFrameProcessor.isFrameFilterEnabled()) { mActivity.runOnUiThread(new Runnable() { public void run() { - mUI.getSurfaceHolder().setFixedSize(mVideoSize.getHeight(), mVideoSize.getWidth()); + SurfaceHolder surfaceHolder = mUI.getSurfaceHolder(); + if (surfaceHolder != null) { + surfaceHolder.setFixedSize( + mVideoSize.getHeight(), mVideoSize.getWidth()); + } } }); } @@ -4316,6 +4359,7 @@ public class CaptureModule implements CameraModule, PhotoController, requestAudioFocus(); try { mMediaRecorder.start(); // Recording is now started + Log.d(TAG, "StartRecordingVideo done."); } catch (RuntimeException e) { Toast.makeText(mActivity,"Could not start media recorder.\n " + "Can't start video recording.", Toast.LENGTH_LONG).show(); @@ -4330,7 +4374,12 @@ public class CaptureModule implements CameraModule, PhotoController, public void startMediaRecording() { if (!startMediaRecorder()) { - mUI.showUIafterRecording(); + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mUI.showUIafterRecording(); + } + }); releaseMediaRecorder(); mFrameProcessor.setVideoOutputSurface(null); restartSession(true); @@ -4609,6 +4658,7 @@ public class CaptureModule implements CameraModule, PhotoController, setEndOfStream(true, false); if (!ApiHelper.HAS_RESUME_SUPPORTED){ mMediaRecorder.start(); + Log.d(TAG, "StartRecordingVideo done."); } else { try { Method resumeRec = Class.forName("android.media.MediaRecorder").getMethod("resume"); @@ -4670,6 +4720,8 @@ public class CaptureModule implements CameraModule, PhotoController, e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); + } catch (NullPointerException e) { + e.printStackTrace(); } } @@ -5378,6 +5430,38 @@ public class CaptureModule implements CameraModule, PhotoController, updateBEStatsVisibility(View.GONE); } + private void applyWbColorTemperature(CaptureRequest.Builder request) { + final SharedPreferences pref = mActivity.getSharedPreferences( + ComboPreferences.getLocalSharedPreferencesName(mActivity, getMainCameraId()), + Context.MODE_PRIVATE); + String manualWBMode = mSettingsManager.getValue(SettingsManager.KEY_MANUAL_WB); + String cctMode = mActivity.getString( + R.string.pref_camera_manual_wb_value_color_temperature); + String gainMode = mActivity.getString( + R.string.pref_camera_manual_wb_value_rbgb_gains); + Log.v("daming", " >>> 5362 >>> cctMode :" + cctMode); + if (manualWBMode.equals(cctMode)) { + int colorTempValue = Integer.parseInt(pref.getString( + SettingsManager.KEY_MANUAL_WB_TEMPERATURE_VALUE, "-1")); + Log.v("daming", " >>> 5366 >>> colorTempValue :" + colorTempValue); + if (colorTempValue != -1) { + VendorTagUtil.setWbColorTemperatureValue(request, colorTempValue); + } + } else if (manualWBMode.equals(gainMode)) { + float rGain = pref.getFloat(SettingsManager.KEY_MANUAL_WB_R_GAIN, -1.0f); + float gGain = pref.getFloat(SettingsManager.KEY_MANUAL_WB_G_GAIN, -1.0f); + float bGain = pref.getFloat(SettingsManager.KEY_MANUAL_WB_B_GAIN, -1.0f); + if (rGain != -1.0 && gGain != -1.0 && bGain != -1.0f) { + request.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF); + float[] gains = {rGain, gGain, bGain}; + Log.v("daming", " >>> 5375 >>> rGain :" + rGain + ", gGain :" + gGain + ", bGain :" + bGain); + VendorTagUtil.setMWBGainsValue(request, gains); + } + } else { + VendorTagUtil.setMWBDisableMode(request); + } + } + private void updateGraghViewVisibility(final int visibility) { mActivity.runOnUiThread(new Runnable() { public void run() { diff --git a/src/com/android/camera/CaptureUI.java b/src/com/android/camera/CaptureUI.java index ccb45e12d..0b738365c 100755 --- a/src/com/android/camera/CaptureUI.java +++ b/src/com/android/camera/CaptureUI.java @@ -67,6 +67,7 @@ import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; +import com.android.camera.imageprocessor.filter.BeautificationFilter; import com.android.camera.imageprocessor.filter.DeepPortraitFilter; import com.android.camera.ui.AutoFitSurfaceView; import com.android.camera.ui.Camera2FaceView; @@ -1361,7 +1362,9 @@ public class CaptureUI implements FocusOverlayManager.FocusUI, enableMakeupMenu = false; enableFilterMenu = false; } - + if(!BeautificationFilter.isSupportedStatic()) { + enableMakeupMenu = false; + } mMakeupButton.setEnabled(enableMakeupMenu); mFilterModeSwitcher.setEnabled(enableFilterMenu); mSceneModeSwitcher.setEnabled(enableSceneMenu); diff --git a/src/com/android/camera/LocationManager.java b/src/com/android/camera/LocationManager.java index 5aedf060e..2ae901aed 100755 --- a/src/com/android/camera/LocationManager.java +++ b/src/com/android/camera/LocationManager.java @@ -79,7 +79,7 @@ public class LocationManager { } private boolean hasLoationPermission() { - return mContext.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) + return mContext.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; } diff --git a/src/com/android/camera/MediaSaveService.java b/src/com/android/camera/MediaSaveService.java index 217f44f27..8394162db 100644 --- a/src/com/android/camera/MediaSaveService.java +++ b/src/com/android/camera/MediaSaveService.java @@ -163,6 +163,23 @@ public class MediaSaveService extends Service { t.execute(); } + public void addHEIFImageFromJpeg(byte[] data, String title, long date, Location loc, + int width, int height, int orientation, ExifInterface exif, + ContentResolver resolver, OnMediaSavedListener listener, + int qualitiy, String pictureFormat) { + if (isQueueFull()) { + Log.e(TAG, "Cannot add image when the queue is full"); + return; + } + HEIFImageSaveTask t = new HEIFImageSaveTask(data, title, date, loc, width, height, orientation, + exif, resolver, listener, qualitiy, pictureFormat); + mMemoryUse += data.length; + if (isQueueFull()) { + onQueueFull(); + } + t.execute(); + } + public void addClearsightImage(byte[] clearsight, GImage bayer, GDepth.DepthMap depthMap, String title, long date, Location loc, int width, int height, int orientation, ExifInterface exif, @@ -328,6 +345,57 @@ public class MediaSaveService extends Service { } } + private class HEIFImageSaveTask extends AsyncTask<Void, Void, Uri> { + private byte[] data; + private String title; + private long date; + private Location loc; + private int width, height; + private int orientation; + private ExifInterface exif; + private ContentResolver resolver; + private OnMediaSavedListener listener; + private int quality; + private String pictureFormat; + + public HEIFImageSaveTask(byte[] data, String title, long date, Location loc, + int width, int height, int orientation, ExifInterface exif, + ContentResolver resolver, OnMediaSavedListener listener, + int quality,String pictureFormat) { + this.data = data; + this.title = title; + this.date = date; + this.loc = loc; + this.width = width; + this.height = height; + this.orientation = orientation; + this.exif = exif; + this.resolver = resolver; + this.listener = listener; + this.quality = quality; + this.pictureFormat = pictureFormat; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + } + + @Override + protected Uri doInBackground(Void... params) { + return Storage.addHeifImage( + resolver,title,date,loc,orientation,exif,data, + width,height,quality,pictureFormat); + } + + @Override + protected void onPostExecute(Uri uri) { + boolean previouslyFull = isQueueFull(); + mMemoryUse -= data.length; + if (isQueueFull() != previouslyFull) onQueueAvailable(); + } + } + private class ImageSaveTask extends AsyncTask <Void, Void, Uri> { private byte[] data; private String title; diff --git a/src/com/android/camera/PermissionsActivity.java b/src/com/android/camera/PermissionsActivity.java index 91699c34f..fb0c080db 100755 --- a/src/com/android/camera/PermissionsActivity.java +++ b/src/com/android/camera/PermissionsActivity.java @@ -79,7 +79,7 @@ public class PermissionsActivity extends Activity { mFlagHasStoragePermission = true; } - if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) + if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { mNumPermissionsToRequest++; mShouldRequestLocationPermission = true; @@ -119,7 +119,7 @@ public class PermissionsActivity extends Activity { } if (mShouldRequestLocationPermission) { permissionsToRequest[permissionsRequestIndex] = - Manifest.permission.ACCESS_COARSE_LOCATION; + Manifest.permission.ACCESS_FINE_LOCATION; mIndexPermissionRequestLocation = permissionsRequestIndex; } requestPermissions(permissionsToRequest, PERMISSION_REQUEST_CODE); diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index f3c57cb71..672b973d0 100644..100755 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -637,7 +637,7 @@ public class PhotoModule // camera only private void locationFirstRun() { boolean enableRecordingLocation = false; - if (mActivity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) + if (mActivity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { enableRecordingLocation = true; } diff --git a/src/com/android/camera/SettingsActivity.java b/src/com/android/camera/SettingsActivity.java index e413090a4..d180d6c27 100755 --- a/src/com/android/camera/SettingsActivity.java +++ b/src/com/android/camera/SettingsActivity.java @@ -66,6 +66,7 @@ public class SettingsActivity extends PreferenceActivity { private static final String TAG = "SettingsActivity"; private SettingsManager mSettingsManager; private SharedPreferences mSharedPreferences; + private SharedPreferences mLocalSharedPref; private boolean mDeveloperMenuEnabled; private int privateCounter = 0; private final int DEVELOPER_MENU_TOUCH_COUNT = 10; @@ -134,6 +135,10 @@ public class SettingsActivity extends PreferenceActivity { autoHdrPref.setEnabled(true); } } + + if ( (pref.getKey().equals(SettingsManager.KEY_MANUAL_WB)) ) { + updateManualWBSettings(); + } } } }; @@ -338,6 +343,181 @@ public class SettingsActivity extends PreferenceActivity { alert.show(); } + private void showManualWBGainDialog(final LinearLayout linear, + final AlertDialog.Builder alert) { + SharedPreferences.Editor editor = mLocalSharedPref.edit(); + final TextView rGainTtext = new TextView(SettingsActivity.this); + final TextView rGainValue = new TextView(SettingsActivity.this); + final EditText rGainInput = new EditText(SettingsActivity.this); + final TextView gGainTtext = new TextView(SettingsActivity.this); + final TextView gGainValue = new TextView(SettingsActivity.this); + final EditText gGainInput = new EditText(SettingsActivity.this); + final TextView bGainTtext = new TextView(SettingsActivity.this); + final TextView bGainValue = new TextView(SettingsActivity.this); + final EditText bGainInput = new EditText(SettingsActivity.this); + int floatType = InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_CLASS_NUMBER; + rGainInput.setInputType(floatType); + gGainInput.setInputType(floatType); + bGainInput.setInputType(floatType); + + float rGain = mLocalSharedPref.getFloat(SettingsManager.KEY_MANUAL_WB_R_GAIN, -1.0f); + float gGain = mLocalSharedPref.getFloat(SettingsManager.KEY_MANUAL_WB_G_GAIN, -1.0f); + float bGain = mLocalSharedPref.getFloat(SettingsManager.KEY_MANUAL_WB_B_GAIN, -1.0f); + + if (rGain == -1.0) { + rGainValue.setText(" Current rGain is " ); + } else { + rGainValue.setText(" Current rGain is " + rGain); + } + if (rGain == -1.0) { + gGainValue.setText(" Current gGain is " ); + } else { + gGainValue.setText(" Current gGain is " + gGain); + } + if (rGain == -1.0) { + bGainValue.setText(" Current bGain is "); + } else { + bGainValue.setText(" Current bGain is " + bGain); + } + int cameraId = mSettingsManager.getCurrentCameraId(); + final float[] gainsRange = mSettingsManager.getWBGainsRangeValues(cameraId); + //refresh camera parameters to get latest CCT value + if (gainsRange == null) { + alert.setMessage("Enter gains value in the range get is NULL "); + } else { + alert.setMessage("Enter gains value in the range of " + gainsRange[0]+ " to " + gainsRange[1]); + } + linear.addView(rGainTtext); + linear.addView(rGainInput); + linear.addView(rGainValue); + linear.addView(gGainTtext); + linear.addView(gGainInput); + linear.addView(gGainValue); + linear.addView(bGainTtext); + linear.addView(bGainInput); + linear.addView(bGainValue); + alert.setView(linear); + alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + float rGain = -1.0f; + float gGain = -1.0f; + float bGain = -1.0f; + String rgainStr = rGainInput.getText().toString(); + String ggainStr = gGainInput.getText().toString(); + String bgainStr = bGainInput.getText().toString(); + if (rgainStr.length() > 0) { + rGain = Float.parseFloat(rgainStr); + } + if (ggainStr.length() > 0) { + gGain = Float.parseFloat(ggainStr); + } + if (bgainStr.length() > 0) { + bGain = Float.parseFloat(bgainStr); + } + if (gainsRange == null) { + RotateTextToast.makeText(SettingsActivity.this, "Gains Range is NULL, " + + "Invalid gains", Toast.LENGTH_SHORT).show(); + return; + } + if (rGain <= gainsRange[1] && rGain >= gainsRange[0]) { + Log.v(TAG, "Setting rGain value : " + rGain); + editor.putFloat(SettingsManager.KEY_MANUAL_WB_R_GAIN, rGain); + } else { + RotateTextToast.makeText(SettingsActivity.this, "Invalid rGain value:", + Toast.LENGTH_SHORT).show(); + } + if (gGain <= gainsRange[1] && gGain >= gainsRange[0]) { + Log.v(TAG, "Setting gGain value : " + gGain); + editor.putFloat(SettingsManager.KEY_MANUAL_WB_G_GAIN, gGain); + } else { + RotateTextToast.makeText(SettingsActivity.this, "Invalid gGain value:", + Toast.LENGTH_SHORT).show(); + } + if (bGain <= gainsRange[1] && bGain >= gainsRange[0]) { + Log.v(TAG, "Setting bGain value : " + bGain); + editor.putFloat(SettingsManager.KEY_MANUAL_WB_B_GAIN, bGain); + } else { + RotateTextToast.makeText(SettingsActivity.this, "Invalid bGain value:", + Toast.LENGTH_SHORT).show(); + } + editor.apply(); + } + }); + alert.show(); + } + + private void updateManualWBSettings() { + int cameraId = mSettingsManager.getCurrentCameraId(); + SharedPreferences.Editor editor = mLocalSharedPref.edit(); + final AlertDialog.Builder alert = new AlertDialog.Builder(SettingsActivity.this); + LinearLayout linear = new LinearLayout(SettingsActivity.this); + linear.setOrientation(1); + alert.setTitle("Manual White Balance Settings"); + alert.setNegativeButton("Cancel",new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog,int id) { + dialog.cancel(); + } + }); + + String cctMode = this.getString( + R.string.pref_camera_manual_wb_value_color_temperature); + String rgbGainMode = this.getString( + R.string.pref_camera_manual_wb_value_rbgb_gains); + String currentWBTemp = mLocalSharedPref.getString( + SettingsManager.KEY_MANUAL_WB_TEMPERATURE_VALUE, "-1"); + final String manualWBMode = mSettingsManager.getValue(SettingsManager.KEY_MANUAL_WB); + Log.v(TAG, "manualWBMode selected = " + manualWBMode); + final int[] wbRange = mSettingsManager.getWBColorTemperatureRangeValues(cameraId); + if (manualWBMode.equals(cctMode)) { + final TextView CCTtext = new TextView(SettingsActivity.this); + final EditText CCTinput = new EditText(SettingsActivity.this); + CCTinput.setInputType(InputType.TYPE_CLASS_NUMBER); + + //refresh camera parameters to get latest CCT value + if (currentWBTemp.equals("-1")) { + CCTtext.setText(" Current CCT is "); + } else { + CCTtext.setText(" Current CCT is " + currentWBTemp); + } + if (wbRange == null) { + alert.setMessage("Enter CCT value is get NULL "); + } else { + alert.setMessage("Enter CCT value in the range of " + wbRange[0]+ " to " + wbRange[1]); + } + linear.addView(CCTinput); + linear.addView(CCTtext); + alert.setView(linear); + alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog,int id) { + int newCCT = -1; + String cct = CCTinput.getText().toString(); + if (cct.length() > 0) { + newCCT = Integer.parseInt(cct); + } + if (wbRange == null) { + RotateTextToast.makeText(SettingsActivity.this, "CCT Range is NULL, " + + "Invalid CCT", Toast.LENGTH_SHORT).show(); + return; + } + if (newCCT <= wbRange[1] && newCCT >= wbRange[0]) { + Log.v(TAG, "Setting CCT value : " + newCCT); + //0 corresponds to manual CCT mode + editor.putString(SettingsManager.KEY_MANUAL_WB_TEMPERATURE_VALUE, cct); + editor.apply(); + } else { + RotateTextToast.makeText(SettingsActivity.this, "Invalid CCT", + Toast.LENGTH_SHORT).show(); + } + } + }); + alert.show(); + } else if (manualWBMode.equals(rgbGainMode)) { + showManualWBGainDialog(linear, alert); + } else { + // user select off, nothing to do. + } + } + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -359,6 +539,11 @@ public class SettingsActivity extends PreferenceActivity { finish(); return; } + + int cameraId = mSettingsManager.getCurrentCameraId(); + mLocalSharedPref = this.getSharedPreferences( + ComboPreferences.getLocalSharedPreferencesName(this, cameraId), + Context.MODE_PRIVATE); mSettingsManager.registerListener(mListener); addPreferencesFromResource(R.xml.setting_menu_preferences); mSharedPreferences = getPreferenceManager().getSharedPreferences(); @@ -452,6 +637,7 @@ public class SettingsActivity extends PreferenceActivity { private void initializePreferences() { updatePreference(SettingsManager.KEY_PICTURE_SIZE); + updatePreference(SettingsManager.KEY_PICTURE_FORMAT); updatePreference(SettingsManager.KEY_VIDEO_QUALITY); updatePreference(SettingsManager.KEY_EXPOSURE); updatePreference(SettingsManager.KEY_VIDEO_HIGH_FRAME_RATE); diff --git a/src/com/android/camera/SettingsManager.java b/src/com/android/camera/SettingsManager.java index 7640cb53b..6f4008908 100755 --- a/src/com/android/camera/SettingsManager.java +++ b/src/com/android/camera/SettingsManager.java @@ -102,6 +102,8 @@ public class SettingsManager implements ListMenu.SettingsListener { public static final int SCENE_MODE_PROMODE_INT = SCENE_MODE_CUSTOM_START + 9; public static final int SCENE_MODE_DEEPZOOM_INT = SCENE_MODE_CUSTOM_START + 10; public static final int SCENE_MODE_DEEPPORTRAIT_INT = SCENE_MODE_CUSTOM_START + 11; + public static final int JPEG_FORMAT = 0; + public static final int HEIF_FORMAT = 1; public static final String SCENE_MODE_DUAL_STRING = "100"; public static final String SCENE_MODE_SUNSET_STRING = "10"; public static final String SCENE_MODE_LANDSCAPE_STRING = "4"; @@ -124,6 +126,7 @@ public class SettingsManager implements ListMenu.SettingsListener { public static final String KEY_CAMERA_ID = "pref_camera2_id_key"; public static final String KEY_SWITCH_CAMERA = "pref_camera2_switch_camera_key"; public static final String KEY_PICTURE_SIZE = "pref_camera2_picturesize_key"; + public static final String KEY_PICTURE_FORMAT = "pref_camera2_picture_format_key"; public static final String KEY_ISO = "pref_camera2_iso_key"; public static final String KEY_EXPOSURE = "pref_camera2_exposure_key"; public static final String KEY_TIMER = "pref_camera2_timer_key"; @@ -159,10 +162,20 @@ public class SettingsManager implements ListMenu.SettingsListener { public static final String KEY_SHARPNESS_CONTROL_MODE = "pref_camera2_sharpness_control_key"; public static final String KEY_AF_MODE = "pref_camera2_afmode_key"; public static final String KEY_EXPOSURE_METERING_MODE = "pref_camera2_exposure_metering_key"; + + //manual 3A keys and parameter strings public static final String KEY_MANUAL_EXPOSURE = "pref_camera2_manual_exp_key"; public static final String KEY_MANUAL_ISO_VALUE = "pref_camera2_manual_iso_key"; public static final String KEY_MANUAL_GAINS_VALUE = "pref_camera2_manual_gains_key"; public static final String KEY_MANUAL_EXPOSURE_VALUE = "pref_camera2_manual_exposure_key"; + + public static final String KEY_MANUAL_WB = "pref_camera2_manual_wb_key"; + public static final String KEY_MANUAL_WB_TEMPERATURE_VALUE = + "pref_camera2_manual_temperature_key"; + public static final String KEY_MANUAL_WB_R_GAIN = "pref_camera2_manual_wb_r_gain"; + public static final String KEY_MANUAL_WB_G_GAIN = "pref_camera2_manual_wb_g_gain"; + public static final String KEY_MANUAL_WB_B_GAIN = "pref_camera2_manual_wb_b_gain"; + public static final String KEY_QCFA = "pref_camera2_qcfa_key"; public static final String KEY_EIS_VALUE = "pref_camera2_eis_key"; public static final String KEY_FOVC_VALUE = "pref_camera2_fovc_key"; @@ -730,6 +743,7 @@ public class SettingsManager implements ListMenu.SettingsListener { if (flashMode != null) { if (!isFlashAvailable(mCameraId)) { removePreference(mPreferenceGroup, KEY_FLASH_MODE); + removePreference(mPreferenceGroup, KEY_VIDEO_FLASH_MODE); mFilteredKeys.add(flashMode.getKey()); } } @@ -939,6 +953,38 @@ public class SettingsManager implements ListMenu.SettingsListener { return pref.getEntryValues(); } + public int[] getWBColorTemperatureRangeValues(int cameraId) { + int[] wbRange = null; + try { + wbRange = mCharacteristics.get(cameraId).get(CaptureModule.WB_COLOR_TEMPERATURE_RANGE); + if (wbRange == null) { + Log.w(TAG, "Supported exposure range get null."); + return null; + } + } catch(NullPointerException e) { + Log.w(TAG, "Supported exposure range modes is null."); + } catch(IllegalArgumentException e) { + Log.w(TAG, "Supported exposure range modes occur IllegalArgumentException."); + } + return wbRange; + } + + public float[] getWBGainsRangeValues(int cameraId) { + float[] rgbRange = null; + try { + rgbRange = mCharacteristics.get(cameraId).get(CaptureModule.WB_RGB_GAINS_RANGE); + if (rgbRange == null) { + Log.w(TAG, "Supported gains range get null."); + return null; + } + } catch(NullPointerException e) { + Log.w(TAG, "Supported gains range modes is null."); + } catch(IllegalArgumentException e) { + Log.w(TAG, "Supported gains range modes occur IllegalArgumentException."); + } + return rgbRange; + } + public long[] getExposureRangeValues(int cameraId) { long[] exposureRange = null; try { @@ -1693,11 +1739,19 @@ public class SettingsManager implements ListMenu.SettingsListener { return num_val; } + + public boolean isCamera2HDRSupport(){ String value = getValue(KEY_HDR); return value != null && value.equals("enable"); } + public int getSavePictureFormat() { + String value = getValue(SettingsManager.KEY_PICTURE_FORMAT); + if (value == null) return 0; + return Integer.valueOf(value); + } + public boolean isZSLInHALEnabled(){ String value = getValue(KEY_ZSL); String halZSLValue = mContext.getString(R.string.pref_camera2_zsl_entryvalue_hal_zsl); diff --git a/src/com/android/camera/Storage.java b/src/com/android/camera/Storage.java index 13f65e14c..a71a88a47 100755 --- a/src/com/android/camera/Storage.java +++ b/src/com/android/camera/Storage.java @@ -18,14 +18,18 @@ package com.android.camera; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import android.annotation.TargetApi; import android.content.ContentResolver; import android.content.ContentValues; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.location.Location; import android.net.Uri; import android.os.Build; import android.os.Environment; +import android.os.Handler; import android.os.StatFs; import android.provider.MediaStore.Images; import android.provider.MediaStore.Images.ImageColumns; @@ -35,6 +39,8 @@ import android.util.Log; import com.android.camera.data.LocalData; import com.android.camera.exif.ExifInterface; import com.android.camera.util.ApiHelper; +import androidx.heifwriter.HeifWriter; +import android.graphics.ImageFormat; public class Storage { private static final String TAG = "CameraStorage"; @@ -135,13 +141,24 @@ public class Storage { values.put(ImageColumns.TITLE, title); if (mimeType.equalsIgnoreCase("jpeg") || mimeType.equalsIgnoreCase("image/jpeg") || + mimeType.equalsIgnoreCase("heif") || mimeType == null) { - values.put(ImageColumns.DISPLAY_NAME, title + ".jpg"); + + if (mimeType.equalsIgnoreCase("heif")){ + values.put(ImageColumns.DISPLAY_NAME, title + ".heic"); + } else { + values.put(ImageColumns.DISPLAY_NAME, title + ".jpg"); + } + } else { values.put(ImageColumns.DISPLAY_NAME, title + ".raw"); } values.put(ImageColumns.DATE_TAKEN, date); - values.put(ImageColumns.MIME_TYPE, "image/jpeg"); + if (mimeType.equalsIgnoreCase("heif")) { + values.put(ImageColumns.MIME_TYPE, "image/heif"); + } else { + values.put(ImageColumns.MIME_TYPE, "image/jpeg"); + } // Clockwise rotation in degrees. 0, 90, 180, or 270. values.put(ImageColumns.ORIENTATION, orientation); values.put(ImageColumns.DATA, path); @@ -180,6 +197,40 @@ public class Storage { return size; } + public static Uri addHeifImage(ContentResolver resolver, String title, long date, + Location location, int orientation, ExifInterface exif, byte[] data, int width, + int height, int quality, String mimeType) { + String path = generateFilepath(title, mimeType); + Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length); + if (bitmap != null) { + try { + HeifWriter.Builder builder = + new HeifWriter.Builder(path,width, height,HeifWriter.INPUT_MODE_BITMAP); + builder.setQuality(quality); + builder.setMaxImages(1); + builder.setPrimaryIndex(0); + builder.setRotation(orientation); + HeifWriter heifWriter = builder.build(); + heifWriter.start(); + heifWriter.addBitmap(bitmap); + heifWriter.stop(3000); + heifWriter.close(); + } catch (IOException|IllegalStateException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + bitmap.recycle(); + } + File f = new File(path); + int size = 0; + if (f.exists() && f.isFile()) { + size = (int) f.length(); + } + return addImage(resolver, title, date, location, orientation, + size, path, width, height, mimeType); + } + // Overwrites the file and updates the MediaStore, or inserts the image if // one does not already exist. public static void updateImage(Uri imageUri, ContentResolver resolver, String title, long date, @@ -224,11 +275,16 @@ public class Storage { } public static String generateFilepath(String title, String pictureFormat) { - if (pictureFormat == null || pictureFormat.equalsIgnoreCase("jpeg")) { + if (pictureFormat == null || pictureFormat.equalsIgnoreCase("jpeg") + || pictureFormat.equalsIgnoreCase("heif")) { + String suffix = ".jpg"; + if (pictureFormat.equalsIgnoreCase("heif")) { + suffix = ".heic"; + } if (isSaveSDCard() && SDCard.instance().isWriteable()) { - return SDCard.instance().getDirectory() + '/' + title + ".jpg"; + return SDCard.instance().getDirectory() + '/' + title + suffix; } else { - return DIRECTORY + '/' + title + ".jpg"; + return DIRECTORY + '/' + title + suffix; } } else { return RAW_DIRECTORY + '/' + title + ".raw"; diff --git a/src/com/android/camera/imageprocessor/PostProcessor.java b/src/com/android/camera/imageprocessor/PostProcessor.java index c227f32b2..302ab4f15 100755 --- a/src/com/android/camera/imageprocessor/PostProcessor.java +++ b/src/com/android/camera/imageprocessor/PostProcessor.java @@ -459,12 +459,18 @@ public class PostProcessor{ if(mController.getPreviewCaptureResult() == null || mController.getPreviewCaptureResult().get(CaptureResult.CONTROL_AE_STATE) == CameraMetadata.CONTROL_AE_STATE_FLASH_REQUIRED) { if(DEBUG_ZSL) Log.d(TAG, "Flash required image"); + if (imageItem != null) + imageItem.closeImage(); imageItem = null; } if (mController.isSelfieFlash()) { + if (imageItem != null) + imageItem.closeImage(); imageItem = null; } if (mController.isLongShotActive()) { + if (imageItem != null) + imageItem.closeImage(); imageItem = null; } if (imageItem != null) { @@ -1278,9 +1284,19 @@ public class PostProcessor{ mController.showCapturedReview(bytes, orientation); } } else { - mActivity.getMediaSaveService().addImage( - bytes, title, date, null, image.getCropRect().width(), image.getCropRect().height(), - orientation, null, mController.getMediaSavedListener(), mActivity.getContentResolver(), "jpeg"); + if(SettingsManager.getInstance().getSavePictureFormat() == + SettingsManager.HEIF_FORMAT) { + String value = SettingsManager.getInstance().getValue( + SettingsManager.KEY_JPEG_QUALITY); + int qualityNumber = CaptureModule.getQualityNumber(value); + mActivity.getMediaSaveService().addHEIFImageFromJpeg(bytes,title,date,null, + image.getWidth(),image.getHeight(),orientation,null,mActivity.getContentResolver(), + mController.getMediaSavedListener(),qualityNumber,"heif"); + } else { + mActivity.getMediaSaveService().addImage( + bytes, title, date, null, image.getCropRect().width(), image.getCropRect().height(), + orientation, null, mController.getMediaSavedListener(), mActivity.getContentResolver(), "jpeg"); + } mController.updateThumbnailJpegData(bytes); image.close(); } diff --git a/src/com/android/camera/util/VendorTagUtil.java b/src/com/android/camera/util/VendorTagUtil.java index 2842b62cf..b2efbfa54 100755 --- a/src/com/android/camera/util/VendorTagUtil.java +++ b/src/com/android/camera/util/VendorTagUtil.java @@ -57,9 +57,20 @@ public class VendorTagUtil { private static CaptureRequest.Key<Integer> USE_ISO_VALUE = new CaptureRequest.Key<>("org.codeaurora.qcamera3.iso_exp_priority.use_iso_value", Integer.class); - private static final CaptureRequest.Key<Byte> HDRVideoMode = + private static CaptureRequest.Key<Integer> WB_COLOR_TEMPERATURE = + new CaptureRequest.Key<>("org.codeaurora.qcamera3.manualWB.color_temperature", + Integer.class); + private static CaptureRequest.Key<float[]> MANUAL_WB_GAINS = + new CaptureRequest.Key<>("org.codeaurora.qcamera3.manualWB.gains", float[].class); + private static CaptureRequest.Key<Integer> PARTIAL_MANUAL_WB_MODE = + new CaptureRequest.Key<>("org.codeaurora.qcamera3.manualWB.partial_mwb_mode", Integer.class); + private static CaptureRequest.Key<Byte> HDRVideoMode = new CaptureRequest.Key<>("org.quic.camera2.streamconfigs.HDRVideoMode", Byte.class); + private static final int MANUAL_WB_DISABLE_MODE = 0; + private static final int MANUAL_WB_CCT_MODE = 1; + private static final int MANUAL_WB_GAINS_MODE = 2; + private static boolean isSupported(CaptureRequest.Builder builder, CaptureRequest.Key<?> key) { boolean supported = true; @@ -147,6 +158,42 @@ public class VendorTagUtil { return isSupported(builder, USE_ISO_VALUE); } + private static boolean isPartialWBModeSupported(CaptureRequest.Builder builder) { + return isSupported(builder, PARTIAL_MANUAL_WB_MODE); + } + + private static boolean isWBTemperatureSupported(CaptureRequest.Builder builder) { + return isSupported(builder, WB_COLOR_TEMPERATURE); + } + + private static boolean isMWBGainsSupported(CaptureRequest.Builder builder) { + return isSupported(builder, MANUAL_WB_GAINS); + } + + public static void setWbColorTemperatureValue(CaptureRequest.Builder builder, Integer value) { + if (isPartialWBModeSupported(builder)) { + builder.set(PARTIAL_MANUAL_WB_MODE, MANUAL_WB_CCT_MODE); + if (isWBTemperatureSupported(builder)) { + builder.set(WB_COLOR_TEMPERATURE, value); + } + } + } + + public static void setMWBGainsValue(CaptureRequest.Builder builder, float[] gains) { + if (isPartialWBModeSupported(builder)) { + builder.set(PARTIAL_MANUAL_WB_MODE, MANUAL_WB_GAINS_MODE); + if (isMWBGainsSupported(builder)) { + builder.set(MANUAL_WB_GAINS, gains); + } + } + } + + public static void setMWBDisableMode(CaptureRequest.Builder builder) { + if (isPartialWBModeSupported(builder)) { + builder.set(PARTIAL_MANUAL_WB_MODE, MANUAL_WB_DISABLE_MODE); + } + } + public static void setHDRVideoMode(CaptureRequest.Builder builder, byte mode) { if ( isHDRVideoModeSupported(builder) ) { builder.set(HDRVideoMode, mode); |