[Samsung Galaxy R i9103] mrsaccess:
Exposure / HDR bug and proposed fix

Some may have read my complaints about the broken exposure compensation function of i9103. This is a bug that affects all ROMs, even official ones. I chose to solve it for Adam's ROM because it is open source and this helps a lot.

I have a solution and a flashable zip for Adam's CM 10.1 to prove the fix.

First, how to detect the problem:

Open the native camera app. Change the exposure (+/-) symbol to -2, then to 2. After each change wait for some time, so the camera can stabilize. Every time you will get the same preview (and the same photo if you shoot).

The correct behavior is to get a very dark image for -2 and a very bright image for 2.

For this reason we can't use any HDR app, nor the native one. They shoot photos but they don't give better quality. HDR isn't a filter, it is supposed to give better quality in situations with difficult lighting.

Also we can't use the exposure compensation function of various apps. Some apps that support many steps, map the -0.4 setting to -2.0, -0.3 to -1.5 etc. But this is problematic in itself.

The problem explained:

Our device supports 8 levels of exposure compensation and off. Android for some reason thinks it supports 40 levels and off.

For the kernel sources (android_kernel_samsung_n1-cm-10.1/include/media/s5k4ecgx.h) you can see what our camera really supports.

It is in these lines, which show the exposure compensation levels (-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0).

S5K4ECGX_EXPOSURE_P2P0 = 0,
S5K4ECGX_EXPOSURE_P1P5,
S5K4ECGX_EXPOSURE_P1P0,
S5K4ECGX_EXPOSURE_P0P5,
S5K4ECGX_EXPOSURE_ZERO,
S5K4ECGX_EXPOSURE_M0P5,
S5K4ECGX_EXPOSURE_M1P0,
S5K4ECGX_EXPOSURE_M1P5,
S5K4ECGX_EXPOSURE_M2P0,

In CM sources, in file android_frameworks_base-cm-10.1/core/java/android/hardware/Camera.java there are the functions that go wrong.

Specifically these are the functions:

getMinExposureCompensation() [should return -4, number of indexed values, returns -20]

getMaxExposureCompensation() [should return 4, number of indexed values, returns 20]

getExposureCompensationStep() [should return 0.5 step, returns 0.1]

Samsung deals with this in their Camera apk. So they get their app to work and broke every other application from Google Play when it comes to exposure compensation and HDR. Kudos Samsung for major douchebaggery.

Proposed solution:

Unfortunately I couldn't find how to fix it properly (make hardware detection work), so the only solution I can think of, is to hardcode our device's values inside core/java/android/hardware/Camera.java.

This is the patch I propose:

--- android_frameworks_base-cm-10.1/core/java/android/hardware/Camera.java 2013-03-03 13:18:54.000000000 +0200
+++ Camera-fixedvalues.java 2013-03-04 23:58:31.425967568 +0200
@@ -3103,7 +3103,7 @@
* exposure compensation is not supported.
*/
public int getMaxExposureCompensation() {
- return getInt(KEY_MAX_EXPOSURE_COMPENSATION, 0);
+ return 4;
}

/**
@@ -3114,7 +3114,7 @@
* exposure compensation is not supported.
*/
public int getMinExposureCompensation() {
- return getInt(KEY_MIN_EXPOSURE_COMPENSATION, 0);
+ return -4;
}

/**
@@ -3126,7 +3126,7 @@
* is -2.
*/
public float getExposureCompensationStep() {
- return getFloat(KEY_EXPOSURE_COMPENSATION_STEP, 0);
+ return -0.5;
}

/**

I don't have a development environment set up (would appreciate a guide on this), so I took Adam's framework.jar, decompile it, fixed the problematic functions and re-packaged it.

Proof of concept:

I attach two flashable zips. One has the modded framework.jar which will make your exposure compensation behave correctly, and the other will restore Adam's original framework.jar in case you don't like mine.

Just flash from CWM, then wipe cache partition and reboot.