Related
Ok so for these last three days i have been trying to get into the android game. I did the hello android tutorial and yea. that was boring lol, so i decided to try and create a program to temporarily fix the keyboard backligh issue. i have only part of the code done but it does not execute at all. I am not sure whats the problem. Im not sure if i should post the code here but the program will be free anyways and idc if someone takes it cause its sloppy and doesnt run ahah. and everyone will know i posted it first
'
Code:
package com.dri94.led;
import java.util.*;
import java.io.*;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class LEDLightActivity extends Activity {
/** Called when the activity is first created. */
@SuppressWarnings("null")
@Override
public void onCreate(Bundle savedInstanceState) {
final int SDK_INT;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Scanner input = new Scanner(System.in);
DataOutputStream os = null;
TextView tv = new TextView(this);
tv.setText("Enter 'y' to turn on keyboard light or 'n' to turn it off");
String yOrN = input.next();
if (yOrN == "y") {
tv.setText("Enter SDK number 7 for GB devices or 14 for ICS devices. No other devices are supported at this time");
SDK_INT = input.nextInt();
if (SDK_INT == '7') {
try {
os.writeBytes("echo 255 > /sys/class/leds/keyboard-backlight/brightness\n"
+ "chmod 444 /sys/class/leds/keyboard-backlight/brightness\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else {
try {
os.writeBytes("echo 255 > /sys/class/leds/kpd_backlight_en\n"
+ "chmod 444 /sys/class/leds/kpd_backlight_en\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
i know there are probably many problems with this but right now i want to focus on why it doesnt run. Im giong to try and do everything else like ui and making it an actual program on my own
Im not sure if this is the right forum or not but developers usually dont post in the General Forum
Edit; this is based on code from... another developer whose name i cant remember but i will try and post back here so he gets credit. either way, not all mine. i read his code and then figured out how to write this.
Don't think I can help with your code but I think the problem with this is the light sensor which will override /sys/class/leds/kpd_backlight_en
Looking at getevent it shows /dev/input/event6 as the light-prox, that is /sys/class/input/input6 in userspace. I haven't found any values of use in there though. You could always decompile Keyboard Backlight Controller to see what it does.
Keyboard backlight controller didn't fix my keyboard. it just worked with the led home lights. Even if hash fixes the issue in this next build. I want to finish this program for the fact that I'm working to be an android developer.
Sent from ICS Droid3 using xda premium
No it won't, but I assume it uses the same logic that would work for the keyboard
Gallery takes "foreva" to load after selecting Gallery wiget, camera under Albums. Though pressing menu/wallpaper/gallery/camera and pictures load pretty much right away. Long press on launcher, choose Gallery, camera and loads just as fast.
FYI
eww245 said:
No it won't, but I assume it uses the same logic that would work for the keyboard
Click to expand...
Click to collapse
I never thought of that. Thanks im going to look into that this morning.
edmann said:
Gallery takes "foreva" to load after selecting Gallery wiget, camera under Albums. Though pressing menu/wallpaper/gallery/camera and pictures load pretty much right away. Long press on launcher, choose Gallery, camera and loads just as fast.
FYI
Click to expand...
Click to collapse
I have no clue what this is referring to lol. Explain please.
i've solved this issue with the app tasker. the keyboard backlight is permanently on, if the keyboard is slided out.
in tasker:
new profile, keyboard slided out and ok. then new task: and use run shell:
echo 1 > /sys/class/leds/kpd_backlight_en/brightness; chmod 444 /sys/class/leds/kpd_backlight_en/brightness
use root don't forget;-)
new profile, keyboard slided out and reverse and ok, new task: run shell:
chmod 777 /sys/class/leds/kpd_backlight_en/brightness; echo 0 > /sys/class/leds/kpd_backlight_en/brightness
use root;-)
for the button backlight i do this same, but with display on and off.
yeai know this keeps the keyboard on permanently. Im was going to make it better later. Right now i just dont know why the app wont start.
I dont know how to request Su permissions either. I have yet to look that up. Trying to solve this issue first because adding more code to it is easy, i already have everything planned out with the code. But i dont want to add it because more code before i fix this will make it harder for me to see the problem
This application will allow you to change the resolution of the mirroring mode.
To use it, you'll have to re-sign it with the same signature as the system, if you successfuly installed the mirroring mode you'll find a way since the problem is the same.
You'll also need to change the package MirrorService.apk because I changed an option in it to allow the use of the function that will change the resolution for all kind of android builds (eng, user, userdebug).
Topic about the HDMI Landscape Mirroring mod : http://forum.xda-developers.com/showthread.php?t=1348692
It's a really simple software, it just requires to activate the mirroring mod to be able to change the resolution, you'll keep it to until the next change or reboot.
Language : English/French
Download v1.0.2 : https://rapidshare.com/files/225894882/MirrorResolution.apk
MirrorService.apk from Photon modded : https://rapidshare.com/files/426697782/MirrorService.apk
Source : https://rapidshare.com/files/2349891096/MirrorResolution_source.zip
To achieve this I used the hdmi user library from the motorola addon pack for atrix.
Pack available here : http://developer.motorola.com/docstools/tools/
Docs : http://developer.motorola.com/docstools/library/motorola-hdmi-dual-screen-api/
I reverse-engineered the mirroring service to create an user library to use with Eclipse.
Source & lib : https://rapidshare.com/files/3144458217/mirror_lib.zip
Awesome job, mate!
Very cool.
Works good on NottachTrix. OK to add to the next release?
One question, are the resolutions labeled correctly in the chooser? When I choose 1920 x 1080 60hz it defaults to 800 x 600. But when I choose 1920 x 1080 50hz it applies 1920 x 1080 60z. I know my monitor doesn't do 1920 x 1080 50hz so something seems weird.
I installed the app and replaced the mirrorservice.apk but your mirrorservice file broke my mirror :S
I tested only with the app itself and it changed the resolution, but it just displayed an static image of the app and never changed.
Also, when selecting 1080p, stayed in 720p, but selected 1280x1024 and changed to 1080p.
How can I fix the mirrorservice.apk? What did you change ? maybe I can edit my apk
sotodefonk said:
I installed the app and replaced the mirrorservice.apk but your mirrorservice file broke my mirror :S
I tested only with the app itself and it changed the resolution, but it just displayed an static image of the app and never changed.
Also, when selecting 1080p, stayed in 720p, but selected 1280x1024 and changed to 1080p.
How can I fix the mirrorservice.apk? What did you change ? maybe I can edit my apk
Click to expand...
Click to collapse
The signature of MirrorService.apk needs to match your systems sig or else it won't work properly.
I first installed his resolution app and tried it out with my regular mirrorservice and it didn't work.
Since my rom is already totally resigned I just resigned his mirrorservice.apk and pushed it and then it worked properly. (except for the res labels)
depending on what rom youre using you can try resigning his mirrorservice and pushing it to see if that helps. it should work if youre using one of my roms, not sure about cm7 roms though.
Nottach said:
The signature of MirrorService.apk needs to match your systems sig or else it won't work properly.
I first installed his resolution app and tried it out with my regular mirrorservice and it didn't work.
Since my rom is already totally resigned I just resigned his mirrorservice.apk and pushed it and then it worked properly. (except for the res labels)
depending on what rom youre using you can try resigning his mirrorservice and pushing it to see if that helps. it should work if youre using one of my roms, not sure about cm7 roms though.
Click to expand...
Click to collapse
Actually, pushed back the original mirrorservice, and it kind of works, but like you said, the resolutions are not correclty labeled... 1024x768 is 1080p on mine, but it works after a restart
how to resign?
I decided to install signapktic to resign the app, but had a couple of questions. You say to sign using signature of my system. That is not the testkey, correct? So how would I obtain the signature of my system? Also, do I sign both apps or just the mirrorresolution.apk?
I also feel like I'm completely missing the point of signatures on apks, but I'll figure it out in due time.
Just to confirm, does this work on CM7 ROM's, or is it only for Blur?
For the list of resolutions, I get it of your extern monitor and based on the motorola doc.
Code:
static final int HDMI_STANDARD_INVALID = -1;
static final int HDMI_STANDARD_AUTO = 0;
static final int HDMI_STANDARD_2_3_60HZ = 1; // 720x480P @ 60Hz
static final int HDMI_STANDARD_4_60HZ = 2; // 1280x720P @ 60Hz
static final int HDMI_STANDARD_17_18_50HZ = 3; // 720x576P @ 50Hz
static final int HDMI_STANDARD_19_50HZ = 4; // 1280x720P @ 50Hz
static final int HDMI_STANDARD_1_60HZ = 5; // 640x480P @ 60Hz
static final int HDMI_STANDARD_16_60HZ = 6; // 1920x1080P @ 60Hz
static final int HDMI_STANDARD_31_50HZ = 7; // 1920x1080P @ 50Hz
static final int HDMI_STANDARD_PC_SVGA_60HZ = 8; // 800x600 @ 60Hz
static final int HDMI_STANDARD_PC_XGA_60HZ = 9; // 1024x768 @ 60Hz
static final int HDMI_STANDARD_PC_SXGA_60HZ = 10; // 1280x1024 @ 60Hz
static final int HDMI_STANDARD_PC_WXGA_60HZ = 11; // 1440x900 @ 60Hz
static final int HDMI_STANDARD_PC_WSXGA_60HZ = 12; // 1680x1050 @ 60Hz
static final int HDMI_STANDARD_PC_LD_60HZ = 13; // 1366x768 @ 60Hz
On my LG tv all res are ok.
And no problem to use it on all roms you want, i shared it for that
Pretty cool will give it a try and see if i can go hd thanks
Is this compatible with cm9 or cm7 or only blur based roms?
Sent from my cm9 kang atrix son
Notorious544d said:
Just to confirm, does this work on CM7 ROM's, or is it only for Blur?
Click to expand...
Click to collapse
I don't see an apk with that name in system/app on my CM7, so I assume it's for Blur.
Sent from my MB860 using Tapatalk
how do i fing the correct signature to sign the apk with? im about to do so now but im slightly confused as to how to locate said signature
Sadly, it doesn't work on cm9 turl v8. It says searching for tv, while my tv displays atrix screen. Why it doesn't find it? Anyone else having this problem?
It's build to work with motorola dual screen api sry ...
djeman said:
It's build to work with motorola dual screen api sry ...
Click to expand...
Click to collapse
What do you mean by that? People confirmed that this worked fine on their TVs. Anyone else having troubles on CM9?
Thanks for making the app. I'm just curious on the purpose of the app. What's the advantage of manually modifing the HDMI resolution? Currently, when I plug the Atrix to my HDTV, it always defaults to the maximum screen resolution of the connected display. In my case, it's always 1920x1080 60Hz. To my understanding, your app allows me to modify to lower screen resolution. However, is there any advantage on doing this?
djeman said:
This application will allow you to change the resolution of the mirroring mode.
To use it, you'll have to re-sign it with the same signature as the system, if you successfuly installed the mirroring mode you'll find a way since the problem is the same.
You'll also need to change the package MirrorService.apk because I changed an option in it to allow the use of the function that will change the resolution for all kind of android builds (eng, user, userdebug).
Topic about the HDMI Landscape Mirroring mod : http://forum.xda-developers.com/showthread.php?t=1348692
It's a really simple software, it just requires to activate the mirroring mod to be able to change the resolution, you'll keep it to until the next change or reboot.
Language : English/French
Download v1.0.2 : https://rapidshare.com/files/225894882/MirrorResolution.apk
MirrorService.apk from Photon modded : https://rapidshare.com/files/426697782/MirrorService.apk
Source : https://rapidshare.com/files/2349891096/MirrorResolution_source.zip
To achieve this I used the hdmi user library from the motorola addon pack for atrix.
Pack available here : http://developer.motorola.com/docstools/tools/
Docs : http://developer.motorola.com/docstools/library/motorola-hdmi-dual-screen-api/
I reverse-engineered the mirroring service to create an user library to use with Eclipse.
Source & lib : https://rapidshare.com/files/3144458217/mirror_lib.zip
Click to expand...
Click to collapse
Hi Djeman,
That can be awsome if you can work on it for CM7 based ROM, I'm on Neutrino and this is the last thing I'd like to get !
Thank you in advance.
Nipit said:
What do you mean by that? People confirmed that this worked fine on their TVs. Anyone else having troubles on CM9?
Click to expand...
Click to collapse
i don't see any post with cyoagen mod roms claimed to be working with this. wish it was....
Unfortunately it doesn't work on my Droid 3 5.7.894, am I doing something wrong? After replacing MirrorService.apk there is no HDMI mirroring anymore and the app says not mirroring... Help is highly appreciated.
THANKS
Hi,
I am trying to put a code together to control the refresh behavior of the e-ink screen. The final goal is to have a drop-in library for app developers to help making their app more e-ink friendly.
The code works already for the PRS-T1, but needs a different driver for the Nook Touch (N2EpdController included).
My one and only beta tester gets the famous "There is a problem parsing the package" error. Pls find enclosed the sources.
I would be grateful if someone could fix possible Eclipse setting or other errors.
Hi,
I have some interest in adapting apps to the eink screen, so I will try to help with this. Unfortunately, I cannot post in the dev forums yet.
When you get error installing apps via android UI, it is useful to do via "adb install" to be able to know the error cause. The message was "INSTALL_FAILED_OLDER_SDK", which I solved by lowering the android:minSdkVersion parameter in Manifest. Then, the app installed and ran fine, but didn't do the desired effect yet. I will check the code now...
---------- Post added at 02:41 AM ---------- Previous post was at 01:53 AM ----------
I see that you're trying to use enterA2Mode() for the nook (btw, there is a typo at NoRefreshEnablerActivity.java:29, it should read EINK_NOOK). I've been playing around with this some time ago when I started developing a fast e-ink drawing app for the NST, you can see it here: https://github.com/marspeople/E-Paper (WIP).
With few testing I've done, I guess the 1-bit mode (A2) setting is not applied globally: it should take effect only in the View from which it is called. I haven't investigated further to try to use it globally.
Hi marspeople,
Thanks for pointing out the type, it should read
} else if (DeviceInfo.EINK_NOOK)
Regarding the global value of mode setting. From what I understand, A2 is a permanent mode, so whatever function or app is setting the updatemode, it is kept. With the PRS-T1, it is reset by calling any stock (Sony) app. For the Nook I don't know..
Good luck in compiling, hopefully we come to a version which works on both devices. Then I can proceed to dynamically change the updatemode within an app.
Yes, the A2 mode is kept until any process resets the EPD. Using logcat, I noticed several epd_reset_region messages appearing automatically when I close your app to go back to the launcher. It seems the system overrides the EPD setting, making impossible to use A2 system-wide (at least by this method).
However, if you want A2 just for an app, calling enterA2mode() will probably work, as I used in my own app above.
Can you send me your apk?
salsichad2 said:
Can you send me your apk?
Click to expand...
Click to collapse
You mean the apk for "NoRefresh" or my drawing app?
Hi marspeople,
I would be most interested to know why the initial source code does compile ok, works on the PRS-T1 and does not install on the Nook Touch + the fixes.
With this knowledge I can write either an app to set refresh modes or within apps.
Did you succeed to compile and install on Nook?
Hi again,
in your N2EpdController.java
Code:
83: mtSetRegion.invoke(null, "aarddict", enumsRegion[region], regionParams, enumsMode[mode]);
I would like to replace the hardcoded "aarddict" by something dynamic.
What would be the correct function to infer the wanted name?
Code:
activity.class.getName()
this.getClass().toString()
.. ?
bardo8430 said:
Hi marspeople,
I would be most interested to know why the initial source code does compile ok, works on the PRS-T1 and does not install on the Nook Touch + the fixes.
With this knowledge I can write either an app to set refresh modes or within apps.
Did you succeed to compile and install on Nook?
Click to expand...
Click to collapse
Yes, sorry about the confusion, but I managed to do it, despite the A2 mode didn't work. What I did was just edit the AndroidManifest.xml, changing the android:minSdkVersion parameter to 7 (since the NST runs Android 2.1).
Good luck finding out how to set A2 mode permanently. I guess you don't have a Nook, so feel free to ask me for testing purposes.
Since the Nook A2 mode seems to be overridden when switching foreground activity, I've tried another approach with a background service which toggles A2 mode when requested by user. This way, the foreground activity isn't switched and "fast refreshing" mode works (until you change activity).
This fast refresh mode (called A2) is only possible because it uses only 1-bit depth, i.e, just black on white, meaning you can't see grayscale pictures but it's good enough for black text on white background and scrolling. I have not "created it", it is built-in from the device (you can test using the stock reader, it is activated when holding a page button). What I implemented is a way to activate and deactivate it at user will from inside any app.
Thanks to dairyknight for his N2EpdController class, which made this possible.
Thanks to bardo8430 for bringing the idea.
Thanks to AndroSS source code for screenshots used in automatic contrast.
Changelog:
01/Mar: Now when you launch the app and it is already running, it will activate NoRefresh mode. So you can also use an activation shortcut to the app using NookTouchTools (i.e. B&N's book icon at top left corner).
02/Mar: Improve activation shortcut to perform toggle between modes. Tap gestures aren't needed anymore (use "-noGestures" apk version if you don't want them).
04/Mar: Got rid of initial ghosting by redrawing the screen after activating A2.
04/Mar (2): Minor improvement of removing ghosting at screen edges.
12/Mar (Beta): Now you can adjust contrast in A2 mode. Images shouldn't be dark or black anymore if you raise the contrast a bit.
22/May: Completely redesigned version 2.0:
- Several options can be customized via settings screen.
- NoRefresh can be toggled by manual app shortcut, tap gestures or automatically according to screen animation (new).
- New App Whitelist to avoid unwanted activation in specific apps (except for manual mode).
- Background service can be launched at boot.
- Small improvements and tweaks.
- Custom app icon (finally )
06/Jun: Fix crash on empty whitelist
08/Jul: (Version 2.1)
- Automatic contrast when activating NoRefresh, according to total "brightness" of the screen (simple algorithm). This should ask you for root permission.
- Also supports manual setting in specific situations (customizable).
- Fix possible crash at startup.
26/Jul: (Version 2.2)
- Fix contrast setting behaviour
06/Dec:
- Alternative version with fixed compatibility for FW 1.2.0 available at https://github.com/marspeople/NoRefreshToggle/downloads
First Video: http://youtu.be/6pBPsyno5PY
Other Video: http://youtu.be/kBbl6egyPsQ
Another demo: http://youtu.be/5b7JjllImjM
Repository: https://github.com/marspeople/NoRefreshToggle
Great to see that it works on the Nook! Good job.
When I try to compile on Eclipse, I have to remove the below Override:
//@Override
public boolean onTouch(View v, MotionEvent event) {
otherwise I get an error: The method onTouch(View, MotionEvent) of type A2Service must override a superclass method
When I compile with this mod and run the app, nothing happens after using your gestures. Except that I tap on other icons which then try to launch other apps.
Should NoRefreshToggle keep the focus?
I have a suspicion: The PRS-T1 needs to call a function of the Sony library with extended parameters to pass the updatemode. ANY function carrying the mUpdateMode parameter would do - but it must be called. Which might be the problem here. In the used EinkListView.java, a lot of "injection" functions like below are defined.
Code:
@Override
public void scrollTo(int x, int y) {
try {
Method invalidateMethod = super.getClass().getMethod("scrollTo",
int.class, int.class, int.class);
invalidateMethod.invoke(this, x, y , mUpdateMode);
} catch(Exception e) {
e.printStackTrace();
}
But your code has neither a Listview, nor would any injection function trigger. I am afraid you would have to make the app use a ListView (or WebView).
Can you?
bardo8430 said:
Great to see that it works on the Nook! Good job.
When I try to compile on Eclipse, I have to remove the below Override:
//@Override
public boolean onTouch(View v, MotionEvent event) {
otherwise I get an error: The method onTouch(View, MotionEvent) of type A2Service must override a superclass method
When I compile with this mod and run the app, nothing happens after using your gestures. Except that I tap on other icons which then try to launch other apps.
Should NoRefreshToggle keep the focus?
Click to expand...
Click to collapse
Well, I noticed that problem of accidentally tapping unwanted widgets, I would recommend tapping on a free area of the screen. I could use an overlay button, but it would occasionally get in the way too. What do you mean by "keep the focus"?
---------- Post added at 09:13 PM ---------- Previous post was at 09:05 PM ----------
bardo8430 said:
I have a suspicion: The PRS-T1 needs to call a function of the Sony library with extended parameters to pass the updatemode. ANY function carrying the mUpdateMode parameter would do - but it must be called. Which might be the problem here. In the used EinkListView.java, a lot of "injection" functions like below are defined.
Code:
@Override
public void scrollTo(int x, int y) {
try {
Method invalidateMethod = super.getClass().getMethod("scrollTo",
int.class, int.class, int.class);
invalidateMethod.invoke(this, x, y , mUpdateMode);
} catch(Exception e) {
e.printStackTrace();
}
But your code has neither a Listview, nor would any injection function trigger. I am afraid you would have to make the app use a ListView (or WebView).
Can you?
Click to expand...
Click to collapse
Well, to capture touch events I've used a dummy View which is added to an overlay (see A2Service.java:43). Despite being an android Service instead of Activity, maybe you can instantiate your ListView there and hopefully it will work.
Thanks for the hint on the dummy view, will try.
"keep the focus"?: window manager speak, I mean that a tap stays within your app and does not act on the icons below.
bardo8430 said:
Thanks for the hint on the dummy view, will try.
"keep the focus"?: window manager speak, I mean that a tap stays within your app and does not act on the icons below.
Click to expand...
Click to collapse
Since I'm using a transparent overlay, I have to let touch events pass through, otherwise only my app would see them.
PS: I've added a demo video at a previous post.
I've been trying to improve the functionality of the app by changing from this manual toggle approach to something like: fast mode is triggered (a bit after) when user starts dragging his finger on the screen and restored when released.
However, I've been searching how to do this with no success so far. The invisible overlay that detects touch events currently is only able to capture MotionEvent.ACTION_OUTSIDE event type, which is useful to detect a tap, but can't deal with a drag. I also need that the drag is passed normally to the app below (to perform scrolling or whatever).
I've found this page (http://stackoverflow.com/questions/8073803/android-multi-touch-and-type-system-overlay) in which is proposed a solution that can detect a drag but can't pass it to the app below.
The code is now here: https://github.com/marspeople/NoRefreshToggle . I would appreciate any help from developers.
Maybe it can be run every 1 second when screen is on. I mean nook is not locked. I don't think that changing one parameter would eat battery. Is it worth a try?
Hi marspeople,
thanks again for taking this. My initial intention was to help app developers with no e-ink experience to easily adapt their code. Doing these things inside an app is much easier but needs access to the source.
See the related question on stackoverflow:
http://stackoverflow.com/questions/9391710/adapt-scrolling-swiping-to-e-ink-screens
The external app was used as a mere demonstrator to have it work on the NST and PRS-T1. Good to have a repository for it now.
marspeople said:
Ok, I think I've got it.
Since the Nook A2 mode seems to be overridden when switching foreground activity, I've tried another approach with a background service which toggles A2 mode when requested by user via a touch gesture. This way, the foreground activity isn't switched and "fast refreshing" mode works (until you change activity).
The activation gestures I'm currently using (unfortunately, it seems you can't use hardware keys using this approach) are:
- 4 "downward-right" taps (each tap must be done to the right and below the previous one) to activate (A2 mode)
- 4 "upward-left" taps to deactivate (Normal mode)
Video: http://youtu.be/6pBPsyno5PY
Here is the source code and a apk. bardo8430, I believe it would be easy to port this to the PRS-T1.
Click to expand...
Click to collapse
Noob question.
So I just install the apk and run it and I have Norefresh.
dark_hawk said:
Noob question.
So I just install the apk and run it and I have Norefresh.
Click to expand...
Click to collapse
yes, just open the norefresh app, and like the youtube video tap the screen from top left to bottom right 4 point
but i think the trade off is the screen go black&white with no grayscale (at lease for me)
This started out as an idea I had while trying to calibrate the screen color of my Nexus S using a colorimeter. While a lot of users are not particularly picky about colors, I do hope quite a number of people would also be interested in this. To give a clearer understanding for all, I'll put in a not-so-short introduction.
As most of us would know, AMOLED screens, while good in terms of brightness and contrast, tend to distort colors. If you're viewing an image on an AMOLED screen, you'll likely notice areas which appear oversaturated and have blown-out details. The reason behind this is that our AMOLED screens have a much wider gamut (i.e. displays more colors) than how images are encoded. If you look at the image below, the bigger triangle represents the set of colors that the AMOLED screen can display. The smaller triangle is the sRGB reference color which is how Android and most images are encoded.
Unfortunately for us, the Android OS isn't aware of this difference. A color with value of #00FF00 (pure green) should look like the green at the upper peak of the smaller triangle. But in reality, it is shown to us as the green of the larger triangle. This remapping between the two color spaces causes lighter shades of color to appear darker (or actually more saturated).
So far, the solution to fixing the problem is through the use of voodoo color (cheers to supercurio). Voodoo allows for the modification of gamma which somehow compensates for the saturation levels of the colors. Also, color multipliers allow for the shifting of the white point. White point, you ask? See, the intersection of the dotted lines? That is the white point which is how white would appear on the screen. Some like warm colors (white points to the right) while cool colors are to the left. However, gamma and multipliers only operate on a single color at a time. This means that the larger triangle will always remain the same shape regardless of the settings we use. Colors would look better but still not the same as the original intent.
So what can we do about it? Well one way would be by analyzing the way in which colors are mapped to a visually-oriented reference (such as the xyY/XYZ space shown in the above image). A standard sRGB image would be mapped using:
While the Nexus S (using the marmite kernel by bedalus with equal multipliers) would map out like:
In effect, you can find a map to convert the intended sRGB colors to the values usable by the screen to simulate the original rendering intent of the colors. This is done by using the following relationship:
Note that the other non-labelled matrix here is simply a way to shift the white point from 6500K (warm) to 9300K (cool) to display good colors on our devices using chromatic adaptation. The end effect is a means to fix color by simply mixing together red, green, and blue values (after gamma correction to be strictly accurate but this has its tolerances). The mix is just as shown above or in a more non-scientific notation:
Code:
R = 0.7043 * R + 0.3440 * B - 0.0028 * B
G = 0.0160 * R + 0.8930 * G + 0.0598 * B
B = 0.0195 * R + 0.0846 * G + 1.1185 * B
As an example, I've uploaded a before-and-after comparison of a test image. On a computer display, the right image (modified) would appear weird compared to the left image but if you load it up (or just view it) on your phone, you can see that the right one actually looks better (no oversaturation). This would be better if you have voodoo color with the multipliers set to more or less equal values.
The task then is to implement this on a kernel level (or similar) which I will touch on my next post (maybe tomorrow). Note that I have not successfully done the modifications as I lack the development skillz to match. In this regard, I would like to solicit the assitance of the dev community with a much wider experience with these things than I do.
So I decided to continue writing this today...
Unlike the voodoo color codes which rely on hardware (TL2796 AMOLED driver) to implement gamma correction, the color mixing process is a bit more involved on the software end. There are no chips on the Nexus S which can be configured to perform the mixing process natively. Instead, I have a few ideas on the implementation of the mixing process.
1. Rewrite the framebuffer
I've attempted doing this using native code by opening the /dev/graphics/fb0 device but the problem lies in timing. If the timing is off, the mixing either never occurs or is repeated several times for a given frame causing color distortions. This is further complicated by the use of double buffering on the device. Even more so with the switching behavior between double and triple buffering in JB! I've tried hijacking the VSYNC signal to operate on the timing (see colormix.c attached) but the result is still very glitchy. Or I may be doing it wrong...
2. Handle all routines that write to the framebuffer
Another way would be to handle all the writes to the framebuffer device. This eliminates the need for timing as processing occurs only once as the data is transferred to the framebuffer. I've seen the codes for cfbcopyarea.c, cfbimgblit.c, and cfbfillrect.c but I'm not sure where direct writes to the framebuffer (using mmap access) are handled (if at all handled). So again, I'm not too sure about this one.
3. Hijack the interface from the LCD driver
Yet another unsure idea by the way. Since the LCD driver interact with the physical hardware through 24 GPIO pins, there should be some code describing how data is transferred to these pins. At that level, it might be possible to manipulate the signal just before it is sent to avoid timing issues mentioned earlier.
Most of these ideas are speculative from a person who is not really that deep into development (I'm more of an image processing researcher ). Any feedback and ideas from the community would be great!
I'm down with matrices. Sign me up!
some good ideas here, if you manage to calibrate our screens without using voodoo, this idea can potentially be used on other amoled devices such as s3 to calibrate it, removing it's over-saturation
bedalus said:
I'm down with matrices. Sign me up!
Click to expand...
Click to collapse
LOL. Matrices are fun! Thanks bedalus!
By the way, I took a look at the driver codes and it may be possible to find the next framebuffer using ioctl (from an external program).
Code:
case S3CFB_GET_CURR_FB_INFO:
next_fb_info.phy_start_addr = fix->smem_start;
next_fb_info.xres = var->xres;
next_fb_info.yres = var->yres;
next_fb_info.xres_virtual = var->xres_virtual;
next_fb_info.yres_virtual = var->yres_virtual;
next_fb_info.xoffset = var->xoffset;
next_fb_info.yoffset = var->yoffset;
next_fb_info.lcd_offset_x = 0;
next_fb_info.lcd_offset_y = 0;
if (copy_to_user((void *)arg,
(struct s3cfb_next_info *) &next_fb_info,
sizeof(struct s3cfb_next_info)))
return -EFAULT;
break;
Invoking this should at least resolve the double buffering issues if timed correctly with VSYNC. Again, IF.
noobiekins said:
some good ideas here, if you manage to calibrate our screens without using voodoo, this idea can potentially be used on other amoled devices such as s3 to calibrate it, removing it's over-saturation
Click to expand...
Click to collapse
Yes actually. You just need colorimeter readings of the locations of the red, green, and blue primaries to build the matrix for any other device and compensate for it.
So based on my last post I tried looking at the behavior of the framebuffer device. It seems that there are a few parameters which are being used by the device namely:
xres/yres - dimensions of the visible image in pixels
xres_virtual/yres_virtual - dimensions of the virtual image in pixels
xoffset/yoffset - position in the framebuffer being used
Click to expand...
Click to collapse
Dumping from a test program, I get one of two sets of values from the framebuffer device:
Code:
Start address: 4debf000
Visible resolution: 480, 800
Virtual resolution: 480, 5600
Offsets: 0, 800
Start address: 4debf000
Visible resolution: 480, 800
Virtual resolution: 480, 5600
Offsets: 0, 0
This more or less tells us that the framebuffer memory is actually divided into multiple buffers each with the visible size (480x800) of the display. They alternate (using the offsets) to provide the double buffering effect Android uses. However, what I can't understand is why there are 7 buffers allocated for the device instead of at most 3 (for triple buffering). It might be useful to take snapshots of the entire framebuffer and write them to consecutive bitmaps but I won't bother with that at the moment.
I've also tried using this behavior to synchronize the framebuffer writes using changes in the offset as a trigger:
Code:
for (;;)
{
do
{
// Extract variable framebuffer information
if(ioctl(fd, FBIOGET_VSCREENINFO, &next_vi) < 0)
{
perror("Cannot extract variable framebuffer information");
return -1;
}
} while (next_vi.yoffset == cur_vi.yoffset);
...
<insert color mixing here>
...
}
Unfortunately, the screen still doesn't update as desired. Lots of flickering involved. I'm not sure if the memory accesses are just too slow such that the screen refreshes before we completely rewrite the framebuffer or if its some other problem. I've attached the full code for anyone who might be able to shed some light on this. In this code, I just did a dummy rewrite (red = green, blue = green) instead of color mixing to avoid computation therefore minimizing CPU loading and to have a more pronounced effect on the screen.
I'm clueless about video, but I'm digging around... These are the files that compile in /drivers/video/
Code:
/home/dave/android/androidkernel/drivers/video/backlight/lcd.o
/home/dave/android/androidkernel/drivers/video/backlight/backlight.o
/home/dave/android/androidkernel/drivers/video/backlight/built-in.o
/home/dave/android/androidkernel/drivers/video/fb_notify.o
/home/dave/android/androidkernel/drivers/video/display/built-in.o
/home/dave/android/androidkernel/drivers/video/fb.o
/home/dave/android/androidkernel/drivers/video/fbsysfs.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb_nt35580.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb_tl2796.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb_fimd6x.o
/home/dave/android/androidkernel/drivers/video/samsung/built-in.o
/home/dave/android/androidkernel/drivers/video/cfbimgblt.o
/home/dave/android/androidkernel/drivers/video/fbmem.o
/home/dave/android/androidkernel/drivers/video/modedb.o
/home/dave/android/androidkernel/drivers/video/cfbcopyarea.o
/home/dave/android/androidkernel/drivers/video/fbcmap.o
/home/dave/android/androidkernel/drivers/video/omap2/displays/built-in.o
/home/dave/android/androidkernel/drivers/video/omap2/built-in.o
/home/dave/android/androidkernel/drivers/video/built-in.o
/home/dave/android/androidkernel/drivers/video/fbcvt.o
/home/dave/android/androidkernel/drivers/video/cfbfillrect.o
/home/dave/android/androidkernel/drivers/video/fbmon.o
I'm combing through these files now to see if there's any obvious points to hack in.
bedalus said:
I'm clueless about video, but I'm digging around... These are the files that compile in /drivers/video/
Code:
/home/dave/android/androidkernel/drivers/video/backlight/lcd.o
/home/dave/android/androidkernel/drivers/video/backlight/backlight.o
/home/dave/android/androidkernel/drivers/video/backlight/built-in.o
/home/dave/android/androidkernel/drivers/video/fb_notify.o
/home/dave/android/androidkernel/drivers/video/display/built-in.o
/home/dave/android/androidkernel/drivers/video/fb.o
/home/dave/android/androidkernel/drivers/video/fbsysfs.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb_nt35580.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb_tl2796.o
/home/dave/android/androidkernel/drivers/video/samsung/s3cfb_fimd6x.o
/home/dave/android/androidkernel/drivers/video/samsung/built-in.o
/home/dave/android/androidkernel/drivers/video/cfbimgblt.o
/home/dave/android/androidkernel/drivers/video/fbmem.o
/home/dave/android/androidkernel/drivers/video/modedb.o
/home/dave/android/androidkernel/drivers/video/cfbcopyarea.o
/home/dave/android/androidkernel/drivers/video/fbcmap.o
/home/dave/android/androidkernel/drivers/video/omap2/displays/built-in.o
/home/dave/android/androidkernel/drivers/video/omap2/built-in.o
/home/dave/android/androidkernel/drivers/video/built-in.o
/home/dave/android/androidkernel/drivers/video/fbcvt.o
/home/dave/android/androidkernel/drivers/video/cfbfillrect.o
/home/dave/android/androidkernel/drivers/video/fbmon.o
I'm combing through these files now to see if there's any obvious points to hack in.
Click to expand...
Click to collapse
Great! And here I was having trouble figuring out which files were actually being used...
I'm not sure about other types of hacks but if we're talking about framebuffer rewriting (like what I've been trying to do), the following segment in s3cfb.c may be useful:
Code:
static irqreturn_t s3cfb_irq_frame(int irq, void *data)
{
struct s3cfb_global *fbdev = (struct s3cfb_global *)data;
s3cfb_clear_interrupt(fbdev);
fbdev->vsync_timestamp = ktime_get();
wmb();
wake_up_interruptible(&fbdev->vsync_wq);
return IRQ_HANDLED;
}
Assuming the system interrupt for VSYNC is enabled (which I assume to be the case otherwise the Choreographer API of JB shouldn't work), then maybe a hack there could be done to process the framebuffer just in time with the frame refresh. This is of course under the assumption that the rewrite is fast enough. I'll try sorting through those files as well to see if there's some easier hack.
Couldn't you pre-process the data before it gets to the fb? It sounds like you want to read it and rewrite it. Did i understand correctly?
bedalus said:
Couldn't you pre-process the data before it gets to the fb? It sounds like you want to read it and rewrite it. Did i understand correctly?
Click to expand...
Click to collapse
Yep, you got it right. Right now, I'm trying to read and re-write but as you said, ideally it should be pre-processed before it even arrives at the framebuffer. I'm not sure if its possible though. Applications can access the framebuffer by mmap-ing it onto shared memory which they can write directly to. I've found functions for fb_write and fb_mmap (both in fbmem.c) but I'm not sure if they're being used internally by the kernel to handle mmap and write requests. I have too little knowledge of kernel processes to know for sure.
fb_write looks fully internal to me.
It looks like the OS is given access in drivers/video/fbsysfs.c
bedalus said:
fb_write looks fully internal to me.
It looks like the OS is given access in drivers/video/fbsysfs.c
Click to expand...
Click to collapse
I'm not quite sure what you mean by internal. Does that mean that if we modify it, we can change how all data is written to the framebuffer?
As for fbsysfs.c, I can see how the OS writes the variable information pertaining to the framebuffer. However, I can't seem to find any reference to the actual data being written to the framebuffer. Did I miss something?
nightsky87 said:
I'm not quite sure what you mean by internal. Does that mean that if we modify it, we can change how all data is written to the framebuffer?
As for fbsysfs.c, I can see how the OS writes the variable information pertaining to the framebuffer. However, I can't seem to find any reference to the actual data being written to the framebuffer. Did I miss something?
Click to expand...
Click to collapse
I'm not 100% sure yet, but I think if you needed to, there is probably a way to hack in at that point.
However supercurio hacked into the gamma here arch/arm/mach-s5pv210/herring-panel.c
...and RGB: drivers/video/samsung/s3cfb_tl2796.c
Is your gamut correction totally independent of RGB/gamma?
EDIT: Oh, I see it now. You have to correct R based partly on G and B etc. Okay. I'll keep looking.
bedalus said:
I'm not 100% sure yet, but I think if you needed to, there is probably a way to hack in at that point.
However supercurio hacked into the gamma here arch/arm/mach-s5pv210/herring-panel.c
...and RGB: drivers/video/samsung/s3cfb_tl2796.c
Is your gamut correction totally independent of RGB/gamma?
EDIT: Oh, I see it now. You have to correct R based partly on G and B etc. Okay. I'll keep looking.
Click to expand...
Click to collapse
Yep... I realized that my attempt at buffer rewrites read and write from the framebuffer one byte at a time! Major I/O overheads! I totally forgot about that.
I'll try rewriting that code as well.
Here's another file:
Code:
include/linux/tl2796.h
It contains the template for the RGB multipliers.
EDIT: I'm trying to see which files use this header now
EDIT: arch/arm/mach-s5pv210/herring-panel.c
...and drivers/video/samsung/s3cfb_tl2796.c
...these are the only two files, so the matrix transformation you want to perform probably needs to happen in one of these files only.
bedalus said:
Here's another file:
Code:
include/linux/tl2796.h
It contains the template for the RGB multipliers.
EDIT: I'm trying to see which files use this header now
EDIT: arch/arm/mach-s5pv210/herring-panel.c
...and drivers/video/samsung/s3cfb_tl2796.c
...these are the only two files, so the matrix transformation you want to perform probably needs to happen in one of these files only.
Click to expand...
Click to collapse
I think the RGB multipliers you're referring to are the same ones used by supercurio and they operate on a per-color basis. In fact, those two files don't directly modify RGB values as far as I can tell. By the time the signal reaches the TL2796 AMOLED driver, they're already mapped to the GPIO_LCD_D<> ports (see /arch/arm/mach-s5pv210/include/mach/gpio-herring.h for the physical mapping).
EDIT:
I did a grep on fb_write and bumped into this code in /include/linux/fb.h:
Code:
/* For framebuffers with strange non linear layouts or that do not
* work with normal memory mapped access
*/
ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
Since I can confirm that the framebuffers with our devices can support mmap, I suppose this means any app can directly read/write to the framebuffer without going through some intermediate function. This leaves us with framebuffer rewrites or hijacking the transfer of data from framebuffer to physical device. I like the second option better.
nightsky87 said:
I think the RGB multipliers you're referring to are the same ones used by supercurio and they operate on a per-color basis. In fact, those two files don't directly modify RGB values as far as I can tell. By the time the signal reaches the TL2796 AMOLED driver, they're already mapped to the GPIO_LCD_D<> ports (see /arch/arm/mach-s5pv210/include/mach/gpio-herring.h for the physical mapping).
Click to expand...
Click to collapse
After a lot of head scratching, I see what you mean.
I performed a search for S5PV210_GPF* and found these files:
Code:
drivers/gpio/gpio-s5pv210.c
arch/arm/mach-s5pv210/herring-panel.c
arch/arm/mach-s5pv210/setup-fb.c
arch/arm/mach-s5pv210/mach-herring.c
...all of which are compiled into the kernel.
Probably if the best place to intervene is on the GPIOs, it must be in one of these files. I'll keep looking!
EDIT: I just saw your edit in the previous post, and I agree! Option 2 seems preferable.
bedalus said:
After a lot of head scratching, I see what you mean.
I performed a search for S5PV210_GPF* and found these files:
Code:
drivers/gpio/gpio-s5pv210.c
arch/arm/mach-s5pv210/herring-panel.c
arch/arm/mach-s5pv210/setup-fb.c
arch/arm/mach-s5pv210/mach-herring.c
...all of which are compiled into the kernel.
Probably if the best place to intervene is on the GPIOs, it must be in one of these files. I'll keep looking!
EDIT: I just saw your edit in the previous post, and I agree! Option 2 seems preferable.
Click to expand...
Click to collapse
Ironically, register definitions don't seem to be in those files. They probably used a different set of defines. What I did find was this in /drivers/video/samsung/s3cfb_fimd6x.c:
Code:
int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, int id)
{
struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
dma_addr_t start_addr = 0, end_addr = 0;
u32 shw;
if (fix->smem_start) {
start_addr = fix->smem_start + (var->xres_virtual *
(var->bits_per_pixel / 8) * var->yoffset);
end_addr = start_addr + fix->line_length * var->yres;
}
if (pdata->hw_ver == 0x62) {
shw = readl(ctrl->regs + S3C_WINSHMAP);
shw |= S3C_WINSHMAP_PROTECT(id);
writel(shw, ctrl->regs + S3C_WINSHMAP);
}
writel(start_addr, ctrl->regs + S3C_VIDADDR_START0(id));
writel(end_addr, ctrl->regs + S3C_VIDADDR_END0(id));
if (pdata->hw_ver == 0x62) {
shw = readl(ctrl->regs + S3C_WINSHMAP);
shw &= ~(S3C_WINSHMAP_PROTECT(id));
writel(shw, ctrl->regs + S3C_WINSHMAP);
}
dev_dbg(ctrl->dev, "[fb%d] start_addr: 0x%08x, end_addr: 0x%08x\n",
id, start_addr, end_addr);
return 0;
}
Unfortunately for use, this seems to use DMA transfers. The driver sets the start and end addresses for the hardware to automatically transfer the data to the registers representing the GPIO. The only way I can think of to modify this behavior is in this sequence:
1. Create our own "framebuffer" (or double the size of the current framebuffer)
2. Mix colors from the original buffer and write it to ours
3. Repeat every new frame
4. Point the DMA transfer source to our framebuffer instead of the original
Quite a complex process I think... I'm not even sure if its worth the development effort.
nightsky87 said:
Ironically, register definitions don't seem to be in those files. They probably used a different set of defines. What I did find was this in /drivers/video/samsung/s3cfb_fimd6x.c:
Code:
int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, int id)
{
struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
struct fb_var_screeninfo *var = &ctrl->fb[id]->var;
struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
dma_addr_t start_addr = 0, end_addr = 0;
u32 shw;
if (fix->smem_start) {
start_addr = fix->smem_start + (var->xres_virtual *
(var->bits_per_pixel / 8) * var->yoffset);
end_addr = start_addr + fix->line_length * var->yres;
}
if (pdata->hw_ver == 0x62) {
shw = readl(ctrl->regs + S3C_WINSHMAP);
shw |= S3C_WINSHMAP_PROTECT(id);
writel(shw, ctrl->regs + S3C_WINSHMAP);
}
writel(start_addr, ctrl->regs + S3C_VIDADDR_START0(id));
writel(end_addr, ctrl->regs + S3C_VIDADDR_END0(id));
if (pdata->hw_ver == 0x62) {
shw = readl(ctrl->regs + S3C_WINSHMAP);
shw &= ~(S3C_WINSHMAP_PROTECT(id));
writel(shw, ctrl->regs + S3C_WINSHMAP);
}
dev_dbg(ctrl->dev, "[fb%d] start_addr: 0x%08x, end_addr: 0x%08x\n",
id, start_addr, end_addr);
return 0;
}
Unfortunately for use, this seems to use DMA transfers. The driver sets the start and end addresses for the hardware to automatically transfer the data to the registers representing the GPIO. The only way I can think of to modify this behavior is in this sequence:
1. Create our own "framebuffer" (or double the size of the current framebuffer)
2. Mix colors from the original buffer and write it to ours
3. Repeat every new frame
4. Point the DMA transfer source to our framebuffer instead of the original
Quite a complex process I think... I'm not even sure if its worth the development effort.
Click to expand...
Click to collapse
Well, i need a new challenge
bedalus said:
Well, i need a new challenge
Click to expand...
Click to collapse
Great then! Good luck!!
...just kidding
The way I see it, it might not be that hard after all. The way the code is structured, seems to show that you can just retain most of the fb routines. They mostly describe stuff like offsets, dimensions, and the like. If you copy the ENTIRE framebuffer into another memory location and manipulate that, you won't have to concern yourself with the rest of those functions. Yeah it uses up about 17 MB more of precious RAM (if my calculations are right) but at least you only have to set the DMA addresses instead of recoding a lot of things.
Before anything, can you somehow check which files in the /drivers/gpu/ folder are being used/compiled? I think I may see something useful in those files but I'm not sure if its even relevant.
so, i've been building android 7.0 for the raspberry pi and it seems
that if you select anything within the settings app then it crashes.
here is the logcat: http://paste.ubuntu.com/23097356/
it would be awesome if someone could point me in the right direction.
thnx.
Temporary fix
Hi,
I just commented out 2 lines in frameworks/base/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java:
(lines 217, 218 or somewhere close)
Code:
public void showMenuIcon() {
mShowingMenu = true;
// getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
// getActionBar().setDisplayHomeAsUpEnabled(true);
}
This is just a temporary fix, but I could use most of the functionality of Settings.
Are you using the peyo-hd port from github? He suggests using TvSettings instead of Settings, but the fix above worked for me.
Jacek