package com.mohammadag.disabledeskdock;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.findClass;
import static de.robv.android.xposed.XposedHelpers.getIntField;
import static de.robv.android.xposed.XposedHelpers.setIntField;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import android.content.IntentFilter;
import android.content.res.Configuration;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class DisableDock implements IXposedHookLoadPackage {
private UiModeManager mUiModeManager = null;
private boolean mIsInCarMode = false;
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("android"))
return;
findAndHookMethod("com.android.server.UiModeManagerService", lpparam.classLoader,
"isDeskDockState", int.class, XC_MethodReplacement.returnConstant(false));
Class<?> DockObserver = findClass("com.android.server.DockObserver", lpparam.classLoader);
XposedBridge.hookAllConstructors(DockObserver, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Context context = (Context) XposedHelpers.getObjectField(param.thisObject, "mContext");
mUiModeManager = (UiModeManager) context.getSystemService(Context.UI_MODE_SERVICE);
IntentFilter iF = new IntentFilter();
iF.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
iF.addAction(UiModeManager.ACTION_EXIT_CAR_MODE);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
mIsInCarMode = true;
} else if (UiModeManager.ACTION_EXIT_CAR_MODE.equals(intent.getAction())) {
mIsInCarMode = false;
}
}
}, iF);
}
});
findAndHookMethod(DockObserver, "handleDockStateChange", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
int mActualDockState = getIntField(param.thisObject, "mActualDockState");
int mReportedDockState = getIntField(param.thisObject, "mReportedDockState");
int mPreviousDockState = getIntField(param.thisObject, "mPreviousDockState");
int newFakeState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
switch (mActualDockState) {
case Intent.EXTRA_DOCK_STATE_DESK:
case Intent.EXTRA_DOCK_STATE_HE_DESK:
case Intent.EXTRA_DOCK_STATE_LE_DESK:
default:
newFakeState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
break;
case Intent.EXTRA_DOCK_STATE_CAR:
newFakeState = Intent.EXTRA_DOCK_STATE_CAR;
break;
}
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR || mIsInCarMode) {
newFakeState = Intent.EXTRA_DOCK_STATE_CAR;
setIntField(param.thisObject, "mActualDockState", newFakeState);
// Prevent sound playback
param.setResult(null);
}
String debugString = String.format("Act: %s Prv: %s Rep: %s Fak: %s Car: %s",
getStringFromDockState(mActualDockState), getStringFromDockState(mPreviousDockState),getStringFromDockState(mReportedDockState),
getStringFromDockState(newFakeState), String.valueOf(mIsInCarMode));
// Toast.makeText( context, debugString, Toast.LENGTH_LONG).show();
XposedBridge.log(debugString);
setIntField(param.thisObject, "mActualDockState", newFakeState);
setIntField(param.thisObject, "mReportedDockState", newFakeState);
}
});
}
private static String getStringFromDockState(int dockState) {
switch (dockState) {
case Intent.EXTRA_DOCK_STATE_DESK:
return "Intent.EXTRA_DOCK_STATE_DESK";
case Intent.EXTRA_DOCK_STATE_HE_DESK:
return "Intent.EXTRA_DOCK_STATE_HE_DESK";
case Intent.EXTRA_DOCK_STATE_LE_DESK:
return "Intent.EXTRA_DOCK_STATE_LE_DESK";
case Intent.EXTRA_DOCK_STATE_CAR:
return "Intent.EXTRA_DOCK_STATE_CAR";
case Intent.EXTRA_DOCK_STATE_UNDOCKED:
default:
return "Intent.EXTRA_DOCK_STATE_UNDOCKED";
}
}
}