package tk.wasdennnoch.androidn_ify.settings.misc; import android.app.ActionBar; import android.app.Activity; import android.app.Fragment; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.provider.Settings; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.Toolbar; import com.android.internal.view.menu.ActionMenuItem; import java.lang.reflect.Method; import java.util.List; import de.robv.android.xposed.XposedHelpers; import tk.wasdennnoch.androidn_ify.R; import tk.wasdennnoch.androidn_ify.XposedHook; import tk.wasdennnoch.androidn_ify.settings.SettingsDrawerHooks; import tk.wasdennnoch.androidn_ify.utils.ResourceUtils; public class SettingsActivityHelper implements View.OnClickListener, SettingsDrawerHooks.RebuildUiListener { private static final String TAG = "SettingsActivityHelper"; private static final String CLASS_UTILS = "com.android.settings.Utils"; private static List<Object> sDashboardCategories; private static Class<?> sClassUtils; private ActionMenuItem mNavItem; private boolean mIsShowingDashboard; private Activity mActivity; private DrawerLayout mDrawerLayout; private SettingsDrawerAdapter mDrawerAdapter; private int mFailCount = 0; private Runnable mUpdateCategories = new Runnable() { @Override public void run() { new CategoriesUpdater().execute(); } }; @SuppressWarnings("ConstantConditions") public SettingsActivityHelper(Activity activity, SettingsDrawerHooks settingsDrawerHooks) { mActivity = activity; if (sClassUtils == null) { try { sClassUtils = XposedHelpers.findClass(CLASS_UTILS, mActivity.getClassLoader()); } catch (Throwable t) { // HTC / Proguard sClassUtils = XposedHelpers.findClass(XposedHook.PACKAGE_SETTINGS + ".sd", mActivity.getClassLoader()); } } LayoutInflater inflater = LayoutInflater.from(activity); inflater.setFactory2(new LayoutInflater.Factory2() { @Override public View onCreateView(String name, Context context, AttributeSet attrs) { if (name.equals(DrawerLayout.class.getCanonicalName())) { return new DrawerLayout(context, attrs); } else if (name.equals(RecyclerView.class.getCanonicalName())) { return new RecyclerView(context, attrs); } else return null; } @Override public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { return onCreateView(name, context, attrs); } }); mIsShowingDashboard = XposedHelpers.getBooleanField(activity, "mIsShowingDashboard"); boolean mDisplayHomeAsUpEnabled = XposedHelpers.getBooleanField(activity, "mDisplayHomeAsUpEnabled"); ViewGroup content = (ViewGroup) XposedHelpers.getObjectField(activity, "mContent"); mDrawerLayout = (DrawerLayout) inflater.inflate(ResourceUtils.getInstance(activity).getLayout(R.layout.settings_with_drawer), content, false); Toolbar toolbar = (Toolbar) mDrawerLayout.findViewById(R.id.action_bar); activity.setActionBar(toolbar); ActionBar actionBar = activity.getActionBar(); actionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled); actionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled); toolbar.setNavigationOnClickListener(this); mNavItem = new ActionMenuItem(activity, 0, android.R.id.home, 0, 0, ""); if (!mIsShowingDashboard) { actionBar.setHomeAsUpIndicator(ResourceUtils.getInstance(activity).getDrawable(R.drawable.ic_menu)); content = (ViewGroup) content.getParent().getParent(); } ViewGroup parent = (ViewGroup) content.getParent(); int index = parent.indexOfChild(content); parent.removeView(content); ((FrameLayout) mDrawerLayout.findViewById(R.id.content_frame)).addView(content); parent.addView(mDrawerLayout, index); mDrawerAdapter = new SettingsDrawerAdapter(activity); mDrawerAdapter.setSettingsActivityHelper(this); RecyclerView recyclerView = (RecyclerView) activity.findViewById(R.id.left_drawer); recyclerView.setLayoutManager(new LinearLayoutManager(mActivity)); recyclerView.setAdapter(mDrawerAdapter); if (mIsShowingDashboard) { settingsDrawerHooks.setRebuildUiListener(this); } else { new CategoriesUpdater().execute(); } } private void onCategoriesChanged() { if (sDashboardCategories != null) { updateDrawer(); } else if (mFailCount < 10) { mFailCount++; mDrawerLayout.postDelayed(mUpdateCategories, 1000); } } private void updateDrawer() { if (mDrawerLayout == null) { return; } mDrawerAdapter.updateCategories(); } void updateDrawerLock() { if (mDrawerAdapter.getItemCount() != 0) { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED); } else { mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); } } private void openDrawer() { if (mDrawerLayout != null) { mDrawerLayout.openDrawer(GravityCompat.START); } } private void closeDrawer() { if (mDrawerLayout != null) { mDrawerLayout.closeDrawers(); } } private boolean openTile(Object tile) { closeDrawer(); if (tile == null) { mActivity.startActivity(new Intent(Settings.ACTION_SETTINGS).addFlags( Intent.FLAG_ACTIVITY_CLEAR_TASK)); return true; } if (!openFragment(tile)) { try { // Show menu on top level items. Intent intent = (Intent) XposedHelpers.getObjectField(tile, "intent"); //tile.intent.putExtra(EXTRA_SHOW_MENU, true); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); mActivity.startActivity(intent); //} } catch (ActivityNotFoundException e) { Intent intent = (Intent) XposedHelpers.getObjectField(tile, "intent"); XposedHook.logE(TAG, "Couldn't find tile " + intent, e); } } return !mIsShowingDashboard; } private boolean openFragment(Object tile) { String fragment = (String) XposedHelpers.getObjectField(tile, "fragment"); if (fragment != null) { Bundle fragmentArguments = (Bundle) XposedHelpers.getObjectField(tile, "fragmentArguments"); int titleRes = XposedHelpers.getIntField(tile, "titleRes"); CharSequence title = (CharSequence) XposedHelpers.callMethod(tile, "getTitle", mActivity.getResources()); try { XposedHelpers.callStaticMethod(sClassUtils, "startWithFragment", new Class[]{Context.class, String.class, Bundle.class, Fragment.class, int.class, int.class, CharSequence.class}, mActivity, fragment, fragmentArguments, null, 0, titleRes, title); } catch (Throwable t) { // HTC / Proguard Method[] methods = XposedHelpers.findMethodsByExactParameters(sClassUtils, void.class, Context.class, String.class, Bundle.class, Fragment.class, int.class, int.class, CharSequence.class); XposedHook.logD(TAG, "Found " + methods.length + " methods matching the parameters of 'startWithFragment'"); if (methods.length > 0) { String name = methods[0].getName(); XposedHook.logD(TAG, "Calling method with name " + name); XposedHelpers.callStaticMethod(sClassUtils, name, new Class[]{Context.class, String.class, Bundle.class, Fragment.class, int.class, int.class, CharSequence.class}, mActivity, fragment, fragmentArguments, null, 0, titleRes, title); } } return true; } return false; } void onTileClicked(Object tile) { if (openTile(tile)) { mActivity.finish(); } } static List<Object> getDashboardCategories() { return sDashboardCategories; } @Override public void onClick(View v) { if (!mIsShowingDashboard && mDrawerLayout != null && mDrawerAdapter.getItemCount() != 0) { openDrawer(); } else { mActivity.onOptionsItemSelected(mNavItem); } } @Override public void onRebuildUiFinished() { new CategoriesUpdater().execute(); } private class CategoriesUpdater extends AsyncTask<Void, Void, List<Object>> { @SuppressWarnings("unchecked") @Override protected List<Object> doInBackground(Void... params) { try { if (sDashboardCategories != null) { return sDashboardCategories; } return (List<Object>) XposedHelpers.callMethod(mActivity, "getDashboardCategories", false); } catch (Throwable t) { XposedHook.logE(TAG, "Can't update categories", t); return null; } } @Override protected void onPostExecute(List<Object> dashboardCategories) { sDashboardCategories = dashboardCategories; onCategoriesChanged(); } } }