FORUMS
Remove All Ads from XDA

[XPOSED] [KK] [FIX] KitKat BUGS fixer

552 posts
Thanks Meter: 367
 
Post Reply Email Thread
============== 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.vi....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;
			}
		});
	}
}
Attached Files
File Type: apk Issue63793fix_v1.0.apk - [Click for QR Code] (37.0 KB, 1514 views)
File Type: apk Issue63793fix_v1.2.apk - [Click for QR Code] (37.2 KB, 3790 views)
The Following 16 Users Say Thank You to Falseclock For This Useful Post: [ View ] Gift Falseclock Ad-Free
 
 
28th July 2014, 05:57 PM |#2  
Walter.White's Avatar
Senior Member
Thanks Meter: 2,061
 
Donate to Me
More
Perfect. Good work.
28th July 2014, 06:27 PM |#3  
Senior Member
Flag Bensheim
Thanks Meter: 78
 
More
Excellent! ^_^ We need more of your kind to fix goggles sloppy work...thanks!
28th July 2014, 06:27 PM |#4  
Falseclock's Avatar
OP Senior Member
Flag Almaty
Thanks Meter: 367
 
Donate to Me
More
Quote:
Originally Posted by chw9999

Excellent! ^_^ We need more of your kind to fix goggles sloppy work...thanks!

just show and I will try )))
29th July 2014, 02:42 AM |#5  
Member
Thanks Meter: 17
 
More
Awesome work!
Could you create a module for this fix also? https://android-review.googlesource.com/#/c/98918
29th July 2014, 04:47 AM |#6  
Falseclock's Avatar
OP Senior Member
Flag Almaty
Thanks Meter: 367
 
Donate to Me
More
Quote:
Originally Posted by a3Dman

Awesome work!
Could you create a module for this fix also? https://android-review.googlesource.com/#/c/98918

what if we will combine all bugs fixes in one mod?
The Following 2 Users Say Thank You to Falseclock For This Useful Post: [ View ] Gift Falseclock Ad-Free
29th July 2014, 07:53 AM |#7  
Beautiful! I had this annoying issue with Skype.
29th July 2014, 09:09 AM |#8  
Member
Thanks Meter: 17
 
More
Quote:
Originally Posted by Falseclock

what if we will combine all bugs fixes in one mod?

29th July 2014, 10:38 AM |#9  
Saltwarehouze's Avatar
Member
Thanks Meter: 26
 
More
Fix working on my S5 Android 4.4.2
Thanks!

Sent from my SM-G900F using XDA Premium 4 mobile app
29th July 2014, 10:59 AM |#10  
Member
Thanks Meter: 2
 
More
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?
29th July 2014, 11:03 AM |#11  
Falseclock's Avatar
OP Senior Member
Flag Almaty
Thanks Meter: 367
 
Donate to Me
More
Quote:
Originally Posted by ZCochrane

But I'm running 4.4.4 on my Nexus 5, and Play Music still behaves that way. What gives? Any insight?

Affected version: 4.4, 4.4.1, and 4.4.2.

you do not need this mod.
Post Reply Subscribe to Thread

Guest Quick Reply (no urls or BBcode)
Message:
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes