Kernel Development Tutorials
Important Links:
Ubuntu - http://www.ubuntu.com/download/ubuntu/download
Sourcery G++ Lite 2011.03-42 for ARM EABI - http://www.codesourcery.com/sgpp/lite/arm/portal/release1802
Stock Samsung Source - https://github.com/dharamg3/kernel_stock_g3 OR https://opensource.samsung.com/
Github for the Tutorials - https://github.com/dharamg3/g3_tuts
Source of Other Kernels to Compare:
G3MOD - Galaxy 3 - https://github.com/dharamg3/G3MOD
FuguMod - Galaxy 3 - https://github.com/sdadier/froyo
I will explain everything Step by Step.
If you got time to learn/develop join in.
If you get some step working and a fellow developer cant get it, please help each other by answering everyone's doubts.I cant reply to each and every query always.
Most of the code is to be run in the terminal. So I wont be mentioning to Open terminal every time.
I would like to thank marcellusbe who was the first one to make a proper custom Kernel for G3, who taught me how to build a kernel, and also lot of other help.
Note:
Please do not post useless messages.
If you dont know coding, please learn that first.
Do not flood my inbox with PM's. I will not respond to PM's regarding Kernel Development. Please post in the thread.
[*]I AM NOT RESPONSIBLE IF YOU HARDBRICK YOUR PHONE, DOING ANY OF THE FOLLOWING STEPS
Install Ubuntu(x86/x64)
1. Install a virtual machine software.(VMware/Virtualbox)
2. Create a new Virtual Machine.
3. Use Ubuntu ISO to install. Download from here - http://www.ubuntu.com/download/ubuntu/download - I use Ubuntu 10.10 x86
4. Allocate enough space for the Virtual machine as the source is itself around 500mb for Kernel. And if you are like me, then you will want to keep backups at each stage.
5. Recommended RAM is 1GB.
6. Let Ubuntu be installed (VMware and Virtualbox have Easy Install which installs Ubuntu itself)
Logging In As Root
1. When Ubuntu first boots, login with the username and password you mentioned while installing.
2. Open Terminal
3. Use following command.(Always the code after $/# is the one to be used. The one before that just specifies [email protected]:~)
## Anything after ## is a comment by me.
Code:
[email protected]:~$ sudo passwd
[sudo] password for dharammaniar: ## Enter password which you used to login.
Enter new UNIX password: ## Enter Password for root(it can be same as your prev password)
Retype new UNIX password: ## Re-Enter Password for root
passwd: password updated successfully
[email protected]:~$ su
Password: ## Enter the root password
[email protected]:/home/dharammaniar#
4. Once you get the last line as above means you now have root access.
5. Now logout from this user and login with username as root
6. On starting Terminal now, you should get
Code:
[email protected]:~#
Setting Up Build Environment
1. You should always be running as root.
2. Go To System->Administration->Synaptic Package Manager
3. Search for ncurses-devel
4. Install libncurses5-dev.
5. Go to http://www.codesourcery.com/sgpp/lite/arm/portal/release1802
6. Download IA32 GNU/Linux Installer. Keep the arm-2011.03-42-arm-none-eabi.bin file on the desktop.(I like to keep everything on the desktop for faster access)
7. Run code and select NO
Code:
dpkg-reconfigure -plow dash
8. Run Installer using code
Code:
apt-get install ia32-libs ## FOR THOSE WHO HAVE x64 Ubuntu installed
/bin/sh /root/Desktop/arm-2011.03-42-arm-none-eabi.bin ## THANKS TO cdesai for the tip :)
9. Do the usual Next Next Next Next.Dont change any paths.Install as typical.
10. Wait till it is installing
11. Wait more
12. Still waiting
13. Again Next -> Done.
14. You now have the development environment ready.
Downloading Sources
1. Download Samsung Source from https://opensource.samsung.com/ or https://github.com/dharamg3/kernel_stock_g3
2. If you download from https://opensource.samsung.com/ then you will not have the initramfs.
3. To get stock initramfs, you need to extract it from one of the stock kernel(I will explain it later).
Extracting initramfs from zImageBased on script from mizch - http://forum.xda-developers.com/showthread.php?t=901152
Download Files from the attachments.
1. Extract files from initramfs-utils.zip to /bin/
2. Make a folder on the Desktop named unpack.
3. Extract the repack-zImage.sh file from repack-zImage.v6.zip in the unpack folder on Desktop.
4. Add your zImage from which you want to extract initramfs in the unpack folder.
5. Run Command
Code:
cd /root/Desktop/unpack
sh repack-zImage.sh -u
6. You will get the unpacked zImage in the same folder which will contain the initramfs folder also.
Note: To make things simple, i use a script to unpack.
Download from attachment.
Add this unpack.sh file to your unpack folder and run it by double clicking
Building Kernel
1. Download Source as mentioned in the above tutorial.
2. Create a folder on the Desktop. I have named it g3.
3. Add initramfs folder and Kernel folder in that folder.
4. Run Code to make initramfs.cpio
Code:
cd initramfs
find . -print0 | cpio --null -ov --format=newc > ../initramfs.cpio
5. You can also use the script named initramfs.sh from attachments. Copy it to the g3 folder and run it by double clicking.
6. By doing step 4 or 5 you will get initramfs.cpio in the g3 folder.
7. Next you need to do is modify the makefile in Kernel folder.
Original is
Code:
ARCH := arm
CROSS_COMPILE := /opt/toolchains/arm-2009q3/bin/arm-none-linux-gnueabi-
Change to
Code:
ARCH := arm
CROSS_COMPILE := /root/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-eabi-
8. Now you need the configuration file.
9. Copy the apollo_rev_02_android_defconfig file from /Kernel/arch/arm/configs to /Kernel/
10. Rename it to .config (Note: It should be only .config and not apollo_rev_02_android_defconfig.config)
11. Now in Terminal run the following code.
Code:
cd /root/Desktop/g3/Kernel
make menuconfig
12. You will get a GUI menu.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
13. Go to General Setup
14. Next go to Initramfs source file(s)
15. Press Enter and give path as
Code:
../initramfs.cpio
16. Exit from menuconfig
17. Enter Code
Code:
make
OR
Code:
make -j4 ## THIS ONE ONLY IF YOU GOT A GOOD CPU THAT SUPPORTS MULTI-THREADING :)
18. Building will start. There will be many warnings. Ignore them.
19. After building is finished, you will get zImage at /Kernel/arch/arm/boot/
20. Add this zImage to a test.tar(attachment) using Total Commander.
21. Flash as One Package in Odin.
22. Enjoy
Note: This is the stock kernel and supports only rfs filesystem. So before flashing it, please change filesystem to rfs and then flash.
Kernel Basics
The Kernel is basically divided into 2 parts.
The Kernel and the initramfs.Those are the two folders in your g3folder.
initramfs
initramfs is a root filesystem which is embedded into the kernel and loaded at an early stage of the boot process. It is the successor of initrd. It provides early userspace which lets you do things that the kernel can't easily do by itself during the boot process.
GIT Commits
I will commit my source every time i make a tutorial. You can check out all the commits on my github for the tutorials - https://github.com/dharamg3/g3_tuts
Fixed Sound Click Bug During Calls - https://github.com/dharamg3/g3_tuts/commit/2f623a5fb88062deb5dbc7d8d1040c05f43b3d91
1% Battery MOD - https://github.com/dharamg3/g3_tuts/commit/f5259a58f14351ccffee49e9fc235b9670369b90
Voodoo Sound v10 - https://github.com/dharamg3/g3_tuts/commit/0bb0f9a538fdb59138e0bcc957d33aa15fd39155
ADB Root and BusyBox - https://github.com/dharamg3/g3_tuts/commit/57424d6a122e6ff219165fd718de8555029a1079
FileSystem Support - https://github.com/dharamg3/g3_tuts/commit/5db762b1402f7775af4ef7da395d5c9d0b99ed0f
Kernel Modding - Part 1
PLEASE DONT ASK HOW OR WHY ANY PART IS DONE. I WILL EXPLAIN ALL THAT I KNOW. BUT SOME PART OF THIS HAS BEEN DONE BY TRIAL AND ERROR METHOD, WHEREAS SOME PART MAYBE OUT OF MY SCOPE OF KNOWLEDGE.
Removing The Sound Click Bug During Calls
We all know that this is the most basic bug found out in the Kernel of Samsung. The clicking sound we get during calls. Many of you may complain that this bug is solved in the newer ROM's, but remember we are building from the original Samsung Source, which is modified in the newer kernel's. We dont have those modifications so here it goes, the Sound Click Bug.
We to find out this bug you need to check the dmesg when you are in a call.
It shows you that there is some sound routing done during the call. So you know that this is something related to the sound driver.
Now the sound driver for Galaxy 3 is the wm8994 driver, which is present at Kernel/sound/soc/codecs/
So the changes to be made are in the file wm8994.c
In the function static int wm8994_resume(struct platform_device *pdev)
Originally the code was
Code:
if (wm8994_power == 0) {
audio_power(1); /* Board Specific function */
wm8994_power = 1;
}
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
wm8994_enable_path(codec, wm8994_curr_path);
After editing the code is
Code:
if (wm8994_power == 0) {
audio_power(1); /* Board Specific function */
wm8994_power = 1;
wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
wm8994_enable_path(codec, wm8994_curr_path);
}
1% Battery MOD
The battery driver for galaxy 3 is found at Kernel/drivers/power/
The file to be added is s5p6442_battery.c
The Samsung battery driver originally divides battery in the following Steps:
100,90,80,70,60,50,40,30,20,15,5,3,1
If you look at the source code, you should be able to find that out easily.
We need to make it return each value in between also so that we get the 1% MOD that is required.
So now, the original code was
Code:
if (bat_vol > batt_full)
{
int temp = (batt_max - batt_full);
if (bat_vol > (batt_full + temp) ||
s3c_bat_info.bat_info.batt_is_full)
bat_level = 100;
else
bat_level = 90;
#ifdef __CHECK_CHG_CURRENT__
if (s3c_bat_info.bat_info.charging_enabled) {
check_chg_current(bat_ps);
if (!s3c_bat_info.bat_info.batt_is_full)
bat_level = 90;
}
#endif /* __CHECK_CHG_CURRENT__ */
dev_dbg(dev, "%s: (full)level = %d\n", __func__, bat_level );
}
else if (batt_full >= bat_vol && bat_vol > batt_almost)
{
int temp = (batt_full - batt_almost) / 2;
if (bat_vol > (batt_almost + 86))
bat_level = 80;
else
bat_level = 70;
dev_dbg(dev, "%s: (almost)level = %d\n", __func__, bat_level);
}
else if (batt_almost >= bat_vol && bat_vol > batt_high)
{
int temp = (batt_almost - batt_high) / 2;
if (bat_vol > (batt_high + 62))
bat_level = 60;
else
bat_level = 50;
dev_dbg(dev, "%s: (high)level = %d\n", __func__, bat_level );
}
else if (batt_high >= bat_vol && bat_vol > batt_medium)
{
int temp = (batt_high - batt_medium) / 2;
if (bat_vol > (batt_medium + 26))
bat_level = 40;
else
bat_level = 30;
dev_dbg(dev, "%s: (med)level = %d\n", __func__, bat_level);
}
else if (batt_medium >= bat_vol && bat_vol > batt_low)
{
int temp = (batt_medium - batt_low) / 2;
if (bat_vol > (batt_low + 50))
bat_level = 20;
else
bat_level = 15;
dev_dbg(dev, "%s: (low)level = %d\n", __func__, bat_level);
}
else if (batt_low >= bat_vol && bat_vol > batt_critical)
{
bat_level = 5;
dev_dbg(dev, "%s: (cri)level = %d, vol = %d\n", __func__,
bat_level, bat_vol);
}
else if (batt_critical >= bat_vol && bat_vol > batt_min)
{
bat_level = 3;
dev_info(dev, "%s: (min)level = %d, vol = %d\n", __func__,
bat_level, bat_vol);
}
else if (batt_min >= bat_vol && bat_vol > batt_off)
{
bat_level = 1;
dev_info(dev, "%s: (off)level = %d, vol = %d\n", __func__,
bat_level, bat_vol);
}
else if (batt_off >= bat_vol)
{
bat_level = 0;
dev_info(dev, "%s: (off)level = %d, vol = %d", __func__,
bat_level, bat_vol);
}
We need to edit it to make
Code:
if (bat_vol > batt_full)
{
int temp = (batt_max - batt_full);
if (bat_vol > (batt_full + temp) ||
s3c_bat_info.bat_info.batt_is_full)
bat_level = 100;
else
{
bat_level = 90 + (((bat_vol - batt_full) *10) / temp);
}
#ifdef __CHECK_CHG_CURRENT__
if (s3c_bat_info.bat_info.charging_enabled) {
check_chg_current(bat_ps);
if (!s3c_bat_info.bat_info.batt_is_full)
bat_level = 90;
}
#endif /* __CHECK_CHG_CURRENT__ */
dev_dbg(dev, "%s: (full)level = %d\n", __func__, bat_level );
}
else if (batt_full >= bat_vol && bat_vol > batt_almost)
{
int temp = (batt_full - batt_almost) / 2;
bat_level = 70 + (((bat_vol - batt_almost) *10) / temp);
dev_dbg(dev, "%s: (almost)level = %d\n", __func__, bat_level);
}
else if (batt_almost >= bat_vol && bat_vol > batt_high)
{
int temp = (batt_almost - batt_high) / 2;
bat_level = 50 + (((bat_vol - batt_high) *10) / temp);
dev_dbg(dev, "%s: (high)level = %d\n", __func__, bat_level );
}
else if (batt_high >= bat_vol && bat_vol > batt_medium)
{
int temp = (batt_high - batt_medium) / 2;
bat_level = 30 + (((bat_vol - batt_medium) *10) / temp);
dev_dbg(dev, "%s: (med)level = %d\n", __func__, bat_level);
}
else if (batt_medium >= bat_vol && bat_vol > batt_low)
{
int temp = (batt_medium - batt_low) / 2;
bat_level = 15 + ((( bat_vol - batt_low) *5) / temp);
dev_dbg(dev, "%s: (low)level = %d\n", __func__, bat_level);
}
else if (batt_low >= bat_vol && bat_vol > batt_critical)
{
bat_level = 5;
dev_dbg(dev, "%s: (cri)level = %d, vol = %d\n", __func__,
bat_level, bat_vol);
}
else if (batt_critical >= bat_vol && bat_vol > batt_min)
{
bat_level = 3;
dev_info(dev, "%s: (min)level = %d, vol = %d\n", __func__,
bat_level, bat_vol);
}
else if (batt_min >= bat_vol && bat_vol > batt_off)
{
bat_level = 1;
dev_info(dev, "%s: (off)level = %d, vol = %d\n", __func__,
bat_level, bat_vol);
}
else if (batt_off >= bat_vol)
{
bat_level = 0;
dev_info(dev, "%s: (off)level = %d, vol = %d", __func__,
bat_level, bat_vol);
}
and also we need to change the Total ADC count
Originally
Code:
#define ADC_TOTAL_COUNT 20
Change it to
Code:
#define ADC_TOTAL_COUNT 100
Voodoo Sound Driver
The Sound Driver for Galaxy 3 is the wm8994 Wolfson Microelectronics Codec.
The WM8994 is a highly integrated ultra-low power hi-fi CODEC designed for smartphones and other portable devices rich in multimedia features.
Features
Hi-Fi 24-bit 4-channel DAC and 2-channel ADC
100dB SNR during stereo DAC playback (‘A’ weighted)
Smart MIC interface
- Power, clocking and data input for up to four digital MICs
- High performance analogue MIC interface
- MIC activity monitor & interrupt allows processor to sleep
1W stereo / 2W mono class D/AB speaker driver
Capless class W headphone drivers
- Integrated charge pump
- 6mW total power for DAC playback to headphones
4 line outputs (single-ended or differential)
BTL earpiece driver
Digital audio interfaces for multi-processor architecture
- Asynchronous stereo duplex sample rate conversion
- Powerful mixing and digital loopback functions
ReTune™ Mobile 5-band, 6-channel parametric EQ
Programmable dynamic range controller
Dual FLL provides all necessary clocks
- Self-clocking modes allows processor to sleep
- All standard sample rates from 8kHz to 96kHz
Active noise reduction circuits
- DC offset correction removes pops and clicks
- Ground loop noise cancellation
Integrated LDO regulators
72-ball W-CSP package (4.511mm x 4.023mm x 0.7mm)
The Voodoo Driver is developed by supercurio.
The changes to be made for the voodoo driver are at sound/soc/codec/
The Changes are as the following Commit. (Please ignore the /Kernel/scripts part....I forgot to do a make clean -i before commiting )
RootADB and BusyBox
Android Debug Bridge (adb) is a versatile command line tool that lets you communicate with an emulator instance or connected Android-powered device. It is a client-server program that includes three components:
A client, which runs on your development machine. You can invoke a client from a shell by issuing an adb command. Other Android tools such as the ADT plugin and DDMS also create adb clients.
A server, which runs as a background process on your development machine. The server manages communication between the client and the adb daemon running on an emulator or device.
A daemon, which runs as a background process on each emulator or device instance.
You can find the adb tool in <sdk>/platform-tools/.
RootADB gives you root access while performing adb functions.
BusyBox combines tiny versions of many common UNIX utilities into a single small executable. It provides replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc. The utilities in BusyBox generally have fewer options than their full-featured GNU cousins; however, the options that are included provide the expected functionality and behave very much like their GNU counterparts. BusyBox provides a fairly complete environment for any small or embedded system.
BusyBox has been written with size-optimization and limited resources in mind. It is also extremely modular so you can easily include or exclude commands (or features) at compile time. This makes it easy to customize your embedded systems. To create a working system, just add some device nodes in /dev, a few configuration files in /etc, and a Linux kernel.
The Changes to be made for these are in the initramfs.
These can be found in this Commit.
Kernel Modding - Part 2
PLEASE DONT ASK HOW OR WHY ANY PART IS DONE. I WILL EXPLAIN ALL THAT I KNOW. BUT SOME PART OF THIS HAS BEEN DONE BY TRIAL AND ERROR METHOD, WHEREAS SOME PART MAYBE OUT OF MY SCOPE OF KNOWLEDGE.
File System Support: rfs/ext2/ext3/ext4
RFS
SAMSUNG RFS (Robust File System) is an embedded flash file system that uses SAMSUNG OneNAND flash memory as storage on any consumer electronic devices.
SAMSUNG RFS runs in the Linux kernel and is fully compatible with FAT file system standards (FAT16/32).
EXT2
http://en.wikipedia.org/wiki/Ext2
EXT3
http://en.wikipedia.org/wiki/Ext3
EXT4
http://en.wikipedia.org/wiki/Ext4
[DEV] Debate: ext2 vs ext3 vs ext4 : http://forum.xda-developers.com/showthread.php?t=800353
[REF] Information About Filesystems : http://forum.xda-developers.com/showthread.php?t=1058095
The changes to be done are as in the commit.
Reserved
Reserved
Reserved
Too many reserved post as usual (all you need is one post to explain all )
Anyways I'll make videos on this soon..
all the users need to know is to install Ubuntu by themself.. everything else will be covered in the video.
well, i intend to add everything here...including where to mod, which code and stuff...
nice to see your post.... XD
dharam can you post some information about overlocking and undervolt?i need it indeed
dxdiag32 said:
nice to see your post.... XD
dharam can you post some information about overlocking and undervolt?i need it indeed
Click to expand...
Click to collapse
everything will come in time...
Thks man, i have never known how to make a kernal before
Sent from my GT-I5801 using XDA App
I hav one question. This tutorial wil b in general or this is specifically for g3?
rudolf895 said:
Too many reserved post as usual (all you need is one post to explain all )
Anyways I'll make videos on this soon..
all the users need to know is to install Ubuntu by themself.. everything else will be covered in the video.
Click to expand...
Click to collapse
the big advantage of having multiple posts reserved is that you can have som kind of directory on the first post linking to the sections in the other posts, this is of big use in a massive theme like kernel development. also i do not see why nobody does this here as of now, always they reserve multiple posts and nobody links them in first post, what makes the use of them obsolete...
vikraam said:
I hav one question. This tutorial wil b in general or this is specifically for g3?
Click to expand...
Click to collapse
well, specifically for g3...the basic steps are same for all phones, but the code and stuff will be more specific for g3...
dharamg3 said:
well, specifically for g3...the basic steps are same for all phones, but the code and stuff will be more specific for g3...
Click to expand...
Click to collapse
I wud like to thank u a million times. Thanq very very much
Hey first a great Karnel now How to make one!!! good going!!! Thanks Mate
============== FIXES ==============
1. https://android-review.googlesource.com/#/c/81970/
Head: All service returning START_STICKY do not restart after it is being killed.
Symptom: if you will start heavy application (game, video encode/decode viewing or bad application which occupy lot of resources), android can kill background service, for example Skype or WhatsApp, but will never restart services when resources become free. Need to start application again or even full phone restart.
Affected version: 4.4, 4.4.1, and 4.4.2.
2. https://android-review.googlesource.com/#/c/98918/
Head: If all activities of a given stack were finishing, no activity was marked as front-of-task.
Symptom: if recents has several apps running, clicking BACK button fast to close current activity will bring to front another activity.
Affected version: 4.4.*
Mod does not have any settings activity. Just enabled it in Xposed menu.
INSTRUCTIONS:
if you get boot-loop
1. after phone start go to Xposed and immediately uncheck module.
2. issue command adb logcat > logcat.txt
3. phone will reboot again soon
4. upload logcat somewhere and post link here.
5. After next restart mod will be disabled.
6. Wait when I will publish correction.
Can be downloaded through Xposed Installer or here: http://repo.xposed.info/module/kz.virtex.android.issue63793fix
Source code:
Code:
package kz.virtex.android.issue63793fix;
import android.content.pm.ApplicationInfo;
import android.os.SystemClock;
import android.util.EventLog;
import android.util.Slog;
import com.android.server.am.EventLogTags;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedHelpers;
public class XMain implements IXposedHookZygoteInit
{
@Override
public void initZygote(StartupParam startupParam) throws Throwable
{
final Class<?> ActiveServices = XposedHelpers.findClass("com.android.server.am.ActiveServices", null);
XposedHelpers.findAndHookMethod(ActiveServices, "killServicesLocked", "com.android.server.am.ProcessRecord", "boolean", new XC_MethodReplacement()
{
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable
{
Boolean DEBUG_SERVICE = (Boolean) XposedHelpers.getStaticBooleanField(ActiveServices, "DEBUG_SERVICE");
String TAG = (String) XposedHelpers.getStaticObjectField(ActiveServices, "TAG");
Object app = param.args[0];
boolean allowRestart = (Boolean) param.args[1];
Object services = XposedHelpers.getObjectField(app, "services");
int size = (Integer) XposedHelpers.callMethod(services, "size");
// First clear app state from services.
for (int i = size - 1; i >= 0; i--) {
Object sr = XposedHelpers.callMethod(services, "valueAt", i);
Object stats = XposedHelpers.getObjectField(sr, "stats");
synchronized (XposedHelpers.callMethod(stats, "getBatteryStats")) {
XposedHelpers.callMethod(stats, "stopLaunchedLocked");
}
Object sr_app = XposedHelpers.getObjectField(sr, "app");
Boolean persistent = XposedHelpers.getBooleanField(sr_app, "persistent");
Boolean stopIfKilled = XposedHelpers.getBooleanField(sr, "stopIfKilled");
if (sr_app != null && !persistent && stopIfKilled) {
Object sr_app_services = XposedHelpers.getObjectField(sr_app, "services");
XposedHelpers.callMethod(sr_app_services, "remove", sr);
}
XposedHelpers.setObjectField(sr, "app", null);
XposedHelpers.setObjectField(sr, "isolatedProc", null);
XposedHelpers.setObjectField(sr, "executeNesting", 0);
XposedHelpers.callMethod(sr, "forceClearTracker");
Object mDestroyingServices = XposedHelpers.getObjectField(param.thisObject, "mDestroyingServices");
Boolean check = (Boolean) XposedHelpers.callMethod(mDestroyingServices, "remove", sr);
if (check) {
if (DEBUG_SERVICE)
Slog.v(TAG, "killServices remove destroying " + sr);
}
Object bindings = XposedHelpers.getObjectField(sr, "bindings");
final int numClients = (Integer) XposedHelpers.callMethod(bindings, "size");
for (int bindingi = numClients - 1; bindingi >= 0; bindingi--) {
Object IntentBindRecord = XposedHelpers.callMethod(bindings, "valueAt", bindingi);
if (DEBUG_SERVICE)
Slog.v(TAG, "Killing binding " + IntentBindRecord + ": shouldUnbind=" + XposedHelpers.getObjectField(IntentBindRecord, "hasBound"));
XposedHelpers.setObjectField(IntentBindRecord, "binder", null);
XposedHelpers.setObjectField(IntentBindRecord, "requested", false);
XposedHelpers.setObjectField(IntentBindRecord, "received", false);
XposedHelpers.setObjectField(IntentBindRecord, "hasBound", false);
}
}
// Clean up any connections this application has to other
// services.
Object connections = XposedHelpers.getObjectField(app, "connections");
size = (Integer) XposedHelpers.callMethod(connections, "size");
for (int i = size - 1; i >= 0; i--) {
Object ConnectionRecord = XposedHelpers.callMethod(connections, "valueAt", i);
XposedHelpers.callMethod(param.thisObject, "removeConnectionLocked", ConnectionRecord, app, null);
}
XposedHelpers.callMethod(connections, "clear");
Object smap = XposedHelpers.callMethod(param.thisObject, "getServiceMap", XposedHelpers.getObjectField(app, "userId"));
// Now do remaining service cleanup.
services = XposedHelpers.getObjectField(app, "services");
size = (Integer) XposedHelpers.callMethod(services, "size");
for (int i = size - 1; i >= 0; i--) {
Object sr = XposedHelpers.callMethod(services, "valueAt", i);
Object mServicesByName = XposedHelpers.getObjectField(smap, "mServicesByName");
if (XposedHelpers.callMethod(mServicesByName, "get", XposedHelpers.getObjectField(sr, "name")) != sr) {
Object cur = XposedHelpers.callMethod(mServicesByName, "get", XposedHelpers.getObjectField(sr, "name"));
Slog.wtf(TAG, "Service " + sr + " in process " + app + " not same as in map: " + cur);
Object app_services = XposedHelpers.getObjectField(app, "services");
XposedHelpers.callMethod(app_services, "removeAt", i);
continue;
}
// Any services running in the application may need to be
// placed back in the pending list.
Object serviceInfo = XposedHelpers.getObjectField(sr, "serviceInfo");
Object applicationInfo = XposedHelpers.getObjectField(serviceInfo, "applicationInfo");
if (allowRestart && XposedHelpers.getIntField(sr, "crashCount") >= 2 && (XposedHelpers.getIntField(applicationInfo, "flags") & ApplicationInfo.FLAG_PERSISTENT) == 0) {
Slog.w(TAG, "Service crashed " + XposedHelpers.getIntField(sr, "crashCount") + " times, stopping: " + sr);
EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH, XposedHelpers.getObjectField(sr, "userId"), XposedHelpers.getObjectField(sr, "crashCount"), XposedHelpers.getObjectField(sr, "shortName"), XposedHelpers.getObjectField(app, "pid"));
XposedHelpers.callMethod(param.thisObject, "bringDownServiceLocked", sr);
} else if (!allowRestart) {
XposedHelpers.callMethod(param.thisObject, "bringDownServiceLocked", sr);
} else {
boolean canceled = (Boolean) XposedHelpers.callMethod(param.thisObject, "scheduleServiceRestartLocked", sr, true);
// Should the service remain running? Note that in the
// extreme case of so many attempts to deliver a command
// that it failed we also will stop it here.
if (XposedHelpers.getBooleanField(sr, "startRequested") && (XposedHelpers.getBooleanField(sr, "stopIfKilled") || canceled)) {
Object pendingStarts = XposedHelpers.getObjectField(sr, "pendingStarts");
if ((Integer) XposedHelpers.callMethod(pendingStarts, "size") == 0) {
XposedHelpers.setBooleanField(sr, "startRequested", false);
if (XposedHelpers.getObjectField(sr, "tracker") != null) {
Object tracker = XposedHelpers.getObjectField(sr, "tracker");
Object mAm = XposedHelpers.getObjectField(param.thisObject, "mAm");
Object mProcessStats = XposedHelpers.getObjectField(mAm, "mProcessStats");
XposedHelpers.callMethod(tracker, "setStarted", false, XposedHelpers.callMethod(mProcessStats, "getMemFactorLocked"), SystemClock.uptimeMillis());
}
if (!XposedHelpers.getBooleanField(sr, "hasAutoCreateConnections")) {
// Whoops, no reason to restart!
XposedHelpers.callMethod(param.thisObject, "bringDownServiceLocked", sr);
}
}
}
}
}
if (!allowRestart) {
Object app_services = XposedHelpers.getObjectField(app, "services");
XposedHelpers.callMethod(app_services, "clear");
// Make sure there are no more restarting services for this
// process.
Object mRestartingServices = XposedHelpers.getObjectField(param.thisObject, "mRestartingServices");
for (int i = (Integer) XposedHelpers.callMethod(mRestartingServices, "size") - 1; i >= 0; i--) {
Object r = XposedHelpers.callMethod(mRestartingServices, "get", i);
String processName = (String) XposedHelpers.getObjectField(r, "processName");
Object serviceInfo = XposedHelpers.getObjectField(r, "serviceInfo");
Object applicationInfo = XposedHelpers.getObjectField(serviceInfo, "applicationInfo");
Object info = XposedHelpers.getObjectField(app, "info");
if (processName.equals((String) XposedHelpers.getObjectField(app, "processName")) && XposedHelpers.getIntField(applicationInfo, "uid") == XposedHelpers.getIntField(info, "uid")) {
XposedHelpers.callMethod(mRestartingServices, "remove", i);
XposedHelpers.callMethod(param.thisObject, "clearRestartingIfNeededLocked", r);
}
}
Object mPendingServices = XposedHelpers.getObjectField(param.thisObject, "mPendingServices");
for (int i = (Integer) XposedHelpers.callMethod(mPendingServices, "size") - 1; i >= 0; i--) {
Object r = XposedHelpers.callMethod(mPendingServices, "get", i);
String processName = (String) XposedHelpers.getObjectField(r, "processName");
Object serviceInfo = XposedHelpers.getObjectField(r, "serviceInfo");
Object applicationInfo = XposedHelpers.getObjectField(serviceInfo, "applicationInfo");
Object info = XposedHelpers.getObjectField(app, "info");
if (processName.equals((String) XposedHelpers.getObjectField(app, "processName")) && XposedHelpers.getIntField(applicationInfo, "uid") == XposedHelpers.getIntField(info, "uid")) {
XposedHelpers.callMethod(mPendingServices, "remove", i);
}
}
}
// Make sure we have no more records on the stopping list.
Object mDestroyingServices = XposedHelpers.getObjectField(param.thisObject, "mDestroyingServices");
int i = (Integer) XposedHelpers.callMethod(mDestroyingServices, "size");
while (i > 0) {
i--;
Object sr = XposedHelpers.callMethod(mDestroyingServices, "get", i);
if (XposedHelpers.getObjectField(sr, "app") == app) {
XposedHelpers.callMethod(sr, "forceClearTracker");
XposedHelpers.callMethod(mDestroyingServices, "remove", i);
if (DEBUG_SERVICE)
Slog.v(TAG, "killServices remove destroying " + sr);
}
}
Object executingServices = XposedHelpers.getObjectField(app, "executingServices");
XposedHelpers.callMethod(executingServices, "clear");
return null;
}
});
}
}
Perfect. Good work.
Excellent! ^_^ We need more of your kind to fix goggles sloppy work...thanks!
chw9999 said:
Excellent! ^_^ We need more of your kind to fix goggles sloppy work...thanks!
Click to expand...
Click to collapse
just show and I will try )))
Awesome work!
Could you create a module for this fix also? https://android-review.googlesource.com/#/c/98918
a3Dman said:
Awesome work!
Could you create a module for this fix also? https://android-review.googlesource.com/#/c/98918
Click to expand...
Click to collapse
what if we will combine all bugs fixes in one mod?
Beautiful! I had this annoying issue with Skype.
Falseclock said:
what if we will combine all bugs fixes in one mod?
Click to expand...
Click to collapse
Fix working on my S5 Android 4.4.2
Thanks!
Sent from my SM-G900F using XDA Premium 4 mobile app
Hey there! Thank you! This module doesn't change the behaviour of the Google Play Music app when you swipe it from recents on my phone. I've installed it on my phone, and music still stops after clearing the app from recents.
Also, the last few comments on the Google Code issue tracker page say "This has been fixed in 4.4.3. Yay!" and "I just tested on 4.4.4, and can confirm that this appears to be fixed."...
But I'm running 4.4.4 on my Nexus 5, and Play Music still behaves that way. What gives? Any insight?
ZCochrane said:
But I'm running 4.4.4 on my Nexus 5, and Play Music still behaves that way. What gives? Any insight?
Click to expand...
Click to collapse
Affected version: 4.4, 4.4.1, and 4.4.2.
you do not need this mod.
Falseclock said:
Affected version: 4.4, 4.4.1, and 4.4.2.
you do not need this mod.
Click to expand...
Click to collapse
But that's what I'm saying, 4.4.4 is also affected, with Google Play Music behaving in the abnormal way you described.
ZCochrane said:
But that's what I'm saying, 4.4.4 is also affected, with Google Play Music behaving in the abnormal way you described.
Click to expand...
Click to collapse
yep, sorry. this is another issue
and related to 4.4.4
looking for solution
Falseclock said:
yep, sorry. this is another issue
and related to 4.4.4
looking for solution
Click to expand...
Click to collapse
Ooh, cool, gotcha!
Thanks!
ZCochrane said:
Ooh, cool, gotcha!
Thanks!
Click to expand...
Click to collapse
https://android-review.googlesource.com/#/c/53871/
will try to fix... too much coding (((
725 lines of code... looks almost impossible
a3Dman said:
Awesome work!
Could you create a module for this fix also? https://android-review.googlesource.com/#/c/98918
Click to expand...
Click to collapse
tonight :good:
Is HTC Sense 5.5 with Android 4.4.2 also affected?
[size=-2]Send with much love & Android. ( HTC One M7 )[/size]
n0j0e said:
Is HTC Sense 5.5 with Android 4.4.2 also affected?
Click to expand...
Click to collapse
yes
ZCochrane said:
Ooh, cool, gotcha!
Thanks!
Click to expand...
Click to collapse
on HTC 4.4.2 this bug already fixed so can't check by myself
please try with Google Music.
if you will get boot-loop - see OP
Falseclock said:
on HTC 4.4.2 this bug already fixed so can't check by myself
please try with Google Music.
if you will get boot-loop - see OP
Click to expand...
Click to collapse
That almost did it!! You're on the right track though, amazing!!
Now this happens:
1) Open Music & start song playback
2) Open recents, swipe Music away, then tap Home button.
3) Music keeps playing! (YAY!)
4) Open music app again, but do nothing in it. (Notification icon is removed, but the notification icon was never displayed when the app is open, so it's normal behaviour)
5) Tap Recent Tasks, music stops instantly, even without swiping the app away, notification icon stays gone.
6) (interestingly, at this stage, tapping the app's recent thumbnail doesn't open the app, nor does the Back button)
Problem is a step 5.
It's pretty cool to see this problem get attention, though.