package org.exalm.tabletkat.settings;
import android.app.ActionBar;
import android.app.Activity;
import android.app.FragmentBreadCrumbs;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.XModuleResources;
import android.content.res.XResources;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import org.exalm.tabletkat.IMod;
import org.exalm.tabletkat.TabletKatModule;
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_LayoutInflated;
public class MultiPaneSettingsMod implements IMod {
private static int id_loading_container;
private static int id_storage_color_bar;
private static int id_tabs;
@Override
public void addHooks(ClassLoader cl) {
Class dataUsageSummaryClass = XposedHelpers.findClass("com.android.settings.DataUsageSummary", cl);
// final Class homeSettingsClass = XposedHelpers.findClass("com.android.settings.HomeSettings", cl);
Class manageApplicationsClass = XposedHelpers.findClass("com.android.settings.applications.ManageApplications", cl);
Class manageApplicationsTabInfoClass = XposedHelpers.findClass("com.android.settings.applications.ManageApplications.TabInfo", cl);
final Class settingsClass = XposedHelpers.findClass("com.android.settings.Settings", cl);
XposedHelpers.findAndHookMethod(Activity.class, "onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Activity a = (Activity) param.thisObject;
String name = a.getResources().getResourceName(a.getThemeResId());
if (name.endsWith(":style/Theme.Settings")) {
a.setTheme(TabletKatModule.shouldUseLightTheme()
? android.R.style.Theme_DeviceDefault_Light
: android.R.style.Theme_DeviceDefault);
}
}
});
XposedHelpers.findAndHookMethod(settingsClass, "onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Activity a = (Activity) param.thisObject;
View v = a.findViewById(android.R.id.list);
View v2 = (View) v.getParent();
int top = v2.getPaddingTop();
int bottom = v2.getPaddingBottom();
v.setPaddingRelative(v.getPaddingStart(), top, v.getPaddingEnd(), bottom);
v2.setPaddingRelative(v2.getPaddingStart(), 0, v2.getPaddingEnd(), 0);
}
});
XposedHelpers.findAndHookMethod(Activity.class, "onApplyThemeResource",
Resources.Theme.class, int.class, boolean.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Activity a = (Activity) param.thisObject;
if (!settingsClass.isInstance(a)){
return;
}
ActionBar ab = a.getActionBar();
Context newContext = new ContextThemeWrapper(a, android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
XposedHelpers.setObjectField(ab, "mThemedContext", newContext);
}
});
XposedHelpers.findAndHookMethod(Activity.class, "setTitle", int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Activity a = (Activity) param.thisObject;
if (!settingsClass.isInstance(a)){
return;
}
PreferenceActivity p = (PreferenceActivity) a;
if (!p.onIsMultiPane() || p.onIsHidingHeaders()) {
return;
}
Object o = XposedHelpers.getObjectField(p, "mFragmentBreadCrumbs");
if (o == null) {
return;
}
param.args[0] = a.getResources().getIdentifier("settings_label", "string",
TabletKatModule.SETTINGS_PACKAGE);
}
});
XposedHelpers.findAndHookMethod(Activity.class, "setTitle", CharSequence.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Activity a = (Activity) param.thisObject;
if (!settingsClass.isInstance(a)){
return;
}
PreferenceActivity p = (PreferenceActivity) a;
if (!p.onIsMultiPane() || p.onIsHidingHeaders()) {
return;
}
Object o = XposedHelpers.getObjectField(p, "mFragmentBreadCrumbs");
if (o == null) {
return;
}
param.args[0] = a.getString(a.getResources().getIdentifier("settings_label", "string",
TabletKatModule.SETTINGS_PACKAGE));
}
});
XposedHelpers.findAndHookMethod(settingsClass, "isValidFragment", String.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return true;
}
});
/*
XposedHelpers.findAndHookMethod(settingsClass, "isValidFragment", String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
boolean b = (Boolean) param.getResult();
param.setResult(b || param.args[0].equals(homeSettingsClass.getName()));
}
});
*/
XposedHelpers.findAndHookMethod(settingsClass, "onIsMultiPane", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
return isMultiPane((Resources) XposedHelpers.callMethod(methodHookParam.thisObject, "getResources"));
}
});
XposedHelpers.findAndHookMethod(manageApplicationsClass, "onCreateView",
LayoutInflater.class, ViewGroup.class, Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ViewGroup rootView = (ViewGroup) param.getResult();
int i = (int) rootView.getContext().getResources().getDimension(com.android.internal.R.dimen.preference_fragment_padding_side); //TODO
View tabs = rootView.findViewById(id_tabs);
tabs.setPadding(i, 0, i, 0);
}
});
XposedHelpers.findAndHookMethod(manageApplicationsTabInfoClass, "build",
LayoutInflater.class, ViewGroup.class, View.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ViewGroup mRootView = (ViewGroup) param.getResult();
View v = mRootView.findViewById(id_loading_container);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v.getLayoutParams();
int i = (int) v.getContext().getResources().getDimension(com.android.internal.R.dimen.preference_fragment_padding_side); //TODO
params.leftMargin = i;
params.rightMargin = i;
v.setLayoutParams(params);
v.requestLayout();
DisplayMetrics d = v.getContext().getResources().getDisplayMetrics();
int end = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, d);
int bottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, d);
View v2 = mRootView.findViewById(id_storage_color_bar);
if (v2 != null) {
v2.setPaddingRelative(v2.getPaddingStart(), v2.getPaddingTop(), end, bottom);
}
}
});
XposedHelpers.findAndHookMethod(dataUsageSummaryClass, "onCreateView",
LayoutInflater.class, ViewGroup.class, Bundle.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
ListView mListView = (ListView) XposedHelpers.getObjectField(param.thisObject, "mListView");
View mHeader = (View) XposedHelpers.getObjectField(param.thisObject, "mHeader");
Object mAdapter = XposedHelpers.getObjectField(param.thisObject, "mAdapter");
final boolean shouldInset = mListView.getScrollBarStyle()
== View.SCROLLBARS_OUTSIDE_OVERLAY;
int mInsetSide = 0;
if (shouldInset) {
mInsetSide = mListView.getResources().getDimensionPixelOffset(
com.android.internal.R.dimen.preference_fragment_padding_side); //TODO
}
XposedHelpers.setIntField(param.thisObject, "mInsetSide", mInsetSide);
if (mInsetSide > 0) {
// inset selector and divider drawables
XposedHelpers.callMethod(param.thisObject, "insetListViewDrawables", mListView, mInsetSide);
mHeader.setPaddingRelative(mInsetSide, 0, mInsetSide, 0);
}
XposedHelpers.setIntField(mAdapter, "mInsetSide", mInsetSide);
}
});
}
@Override
public void initResources(XResources res, XModuleResources res2) {
id_loading_container = res.getIdentifier("loading_container", "id", TabletKatModule.SETTINGS_PACKAGE);
id_tabs = res.getIdentifier("tabs", "id", TabletKatModule.SETTINGS_PACKAGE);
id_storage_color_bar = res.getIdentifier("storage_color_bar", "id", TabletKatModule.SETTINGS_PACKAGE);
res.setReplacement(TabletKatModule.SETTINGS_PACKAGE, "dimen", "settings_side_margin",
res2.fwd(com.android.internal.R.dimen.preference_fragment_padding_side)); //TODO
res.setReplacement(TabletKatModule.SETTINGS_PACKAGE, "dimen", "pager_tabs_padding",
res2.fwd(com.android.internal.R.dimen.preference_fragment_padding_side)); //TODO
}
private boolean isMultiPane(Resources r){
return true;//r.getBoolean(com.android.internal.R.bool.preferences_prefer_dual_pane); //TODO
}
public static void hookBreadcrumbs(XResources res) {
res.hookLayout("android", "layout", "breadcrumbs_in_fragment", new XC_LayoutInflated() {
@Override
public void handleLayoutInflated(XC_LayoutInflated.LayoutInflatedParam layoutInflatedParam) throws Throwable {
if (!TabletKatModule.shouldForceBreadcrumbs()) {
return;
}
ViewGroup v = (ViewGroup) layoutInflatedParam.view;
if (v instanceof LinearLayout) {
return; //The breadcrumbs are already there
}
if (! (v.getContext() instanceof PreferenceActivity)) {
return; //Not a preference activity
}
try {
PreferenceActivity a = (PreferenceActivity) v.getContext();
if (!a.onIsMultiPane()) {
return; //Single pane
}
} catch (Throwable t) {
XposedBridge.log(t);
return;
}
v.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
DisplayMetrics d = v.getResources().getDisplayMetrics();
int padding = v.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.preference_fragment_padding_side); //TODO
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 72, d);
int top = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, d);
int bottom = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, d);
int iheight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, d);
LinearLayout l = new LinearLayout(v.getContext());
l.setOrientation(LinearLayout.VERTICAL);
l.setPadding(padding, 0, padding, 0);
FrameLayout.LayoutParams lparams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
lparams.leftMargin = padding;
lparams.rightMargin = padding;
FragmentBreadCrumbs bc = new FragmentBreadCrumbs(l.getContext());
bc.setId(android.R.id.title);
bc.setPadding(0, top, 0, bottom);
LinearLayout.LayoutParams bcparams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, height);
bcparams.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
l.addView(bc, bcparams);
ImageView i = new ImageView(l.getContext());
i.setImageDrawable(new ColorDrawable(0xFF404040));
l.addView(i, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, iheight));
v.addView(l);
v.setVisibility(View.VISIBLE);
v.requestLayout();
}
});
}
}