Skip to content

Commit

Permalink
Added Hooks Explanation
Browse files Browse the repository at this point in the history
  • Loading branch information
DHD2280 committed May 2, 2024
1 parent def7958 commit 05e050b
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 76 deletions.
147 changes: 72 additions & 75 deletions app/src/main/java/it/dhd/oxygencustomizer/ui/fragments/Hooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import static it.dhd.oxygencustomizer.utils.Constants.Packages.FRAMEWORK;
import static it.dhd.oxygencustomizer.utils.Constants.Packages.SYSTEM_UI;
import static it.dhd.oxygencustomizer.xposed.XPrefs.Xprefs;
import static it.dhd.oxygencustomizer.xposed.utils.BootLoopProtector.LOAD_TIME_KEY_KEY;
import static it.dhd.oxygencustomizer.xposed.utils.BootLoopProtector.PACKAGE_STRIKE_KEY_KEY;

import android.content.BroadcastReceiver;
Expand All @@ -19,10 +17,17 @@
import android.os.CountDownTimer;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
Expand All @@ -34,16 +39,17 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.view.MenuHost;
import androidx.core.view.MenuProvider;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Lifecycle;

import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.topjohnwu.superuser.Shell;
import com.topjohnwu.superuser.ipc.RootService;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

Expand All @@ -54,7 +60,6 @@
import it.dhd.oxygencustomizer.utils.AppUtils;
import it.dhd.oxygencustomizer.utils.Constants;
import it.dhd.oxygencustomizer.utils.PreferenceHelper;
import it.dhd.oxygencustomizer.xposed.utils.BootLoopProtector;

public class Hooks extends Fragment {

Expand All @@ -63,7 +68,6 @@ public class Hooks extends Fragment {
IntentFilter intentFilterHookedPackages = new IntentFilter();
private final List<String> hookedPackageList = new ArrayList<>();
private List<String> monitorPackageList;
private final String LSPosedDB = "/data/adb/lspd/config/modules_config.db";
private int dotCount = 0;
private ServiceConnection mCoreRootServiceConnection;
private IRootProviderService mRootServiceIPC = null;
Expand Down Expand Up @@ -220,25 +224,7 @@ private void initListItem(List<String> pack) {

int finalI = i;

MaterialButton activateInLSPosed = list.findViewById(R.id.activate_in_lsposed);
activateInLSPosed.setOnClickListener(view -> {
activateInLSPosed.setEnabled(false);
try {
if (mRootServiceIPC.activateInLSPosed(pack.get(finalI))) {
activateInLSPosed.animate().setDuration(300).withEndAction(() -> activateInLSPosed.setVisibility(View.GONE)).start();
Toast.makeText(getContext(), getText(R.string.package_activated), Toast.LENGTH_SHORT).show();
binding.rebootButton.show();
rebootPending = true;
} else {
Toast.makeText(getContext(), getText(R.string.package_activation_failed), Toast.LENGTH_SHORT).show();
activateInLSPosed.setEnabled(true);
}
} catch (RemoteException e) {
Toast.makeText(getContext(), getText(R.string.package_activation_failed), Toast.LENGTH_SHORT).show();
activateInLSPosed.setEnabled(true);
e.printStackTrace();
}
});


list.setOnClickListener(view -> {
// show ripple effect and do nothing
Expand Down Expand Up @@ -313,19 +299,11 @@ private void refreshListItem() {

desc.setText(getText(
isAppInstalled(pkgName)
? checkLSPosedDB(pkgName)
? isBootLooped(pkgName)
? R.string.package_hook_bootlooped
: R.string.package_hook_no_response
: R.string.package_not_hook_enabled
: R.string.package_not_found));
}

if (desc.getText() == getText(R.string.package_not_hook_enabled)) {
MaterialButton activateInLSPosed = list.findViewById(R.id.activate_in_lsposed);
activateInLSPosed.setVisibility(View.VISIBLE);
activateInLSPosed.setEnabled(true);
}
}
}

Expand All @@ -345,27 +323,13 @@ private Drawable getAppIcon(String packageName) {
}
}

private boolean checkLSPosedDB(String pkgName) {
try {
return mRootServiceIPC.checkLSPosedDB(pkgName);
} catch (RemoteException e) {
return false;
}
}

private boolean isBootLooped(String pkgName) {
if (PreferenceHelper.getModulePrefs() != null) {
SharedPreferences prefs = PreferenceHelper.getModulePrefs();
String loadTimeKey = String.format("%s%s", LOAD_TIME_KEY_KEY, pkgName);
String strikeKey = String.format("%s%s", PACKAGE_STRIKE_KEY_KEY, pkgName);
long currentTime = Calendar.getInstance().getTime().getTime();
long lastLoadTime = prefs.getLong(loadTimeKey, 0);
int strikeCount = prefs.getInt(strikeKey, 0);

if (strikeCount >= 3) {
return true;
}
return false;
return strikeCount >= 3;
}
return false;
}
Expand All @@ -374,32 +338,6 @@ private int dp2px(Context context, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}

@SuppressWarnings("unused")
public static class StringBooleanMap {
private final HashMap<String, Boolean> map = new HashMap<>();

public void put(String key, boolean value) {
map.put(key, value);
}

public boolean get(String key) {
Boolean value = map.get(key);
return value != null ? value : false;
}

public boolean containsKey(String key) {
return map.containsKey(key);
}

public void remove(String key) {
map.remove(key);
}

public void clear() {
map.clear();
}
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
outState.putBoolean(reboot_key, rebootPending);
Expand All @@ -414,6 +352,65 @@ public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
}
}

@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MenuHost menuHost = requireActivity();
// Add menu items without using the Fragment Menu APIs
// Note how we can tie the MenuProvider to the viewLifecycleOwner
// and an optional Lifecycle.State (here, RESUMED) to indicate when
// the menu should be visible
menuHost.addMenuProvider(new MenuProvider() {
@Override
public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
// Add menu items here
menu.add(0, 1, 0, R.string.info_hooks)
.setIcon(R.drawable.settingslib_ic_info_outline_24)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}

@Override
public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
// Handle the menu selection
if (menuItem.getItemId() == 1) {
showInfoDialog();
return true;
}
return true;
}
}, getViewLifecycleOwner(), Lifecycle.State.RESUMED);
}

private void showInfoDialog() {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
builder.setTitle(R.string.info_hooks);
builder.setMessage(getSpannedDescription());
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss());
builder.show();
}

private SpannableStringBuilder getSpannedDescription() {
String description = getString(R.string.info_hooks_desc);
int startSpan = 0, endSpan = 0;
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(description);
List<Object[]> targets = new ArrayList<>();
targets.add(new Object[]{getString(R.string.package_hooked_successful), getContext().getColor(android.R.color.system_accent1_400)});
targets.add(new Object[]{getString(R.string.package_hook_no_response), getContext().getColor(R.color.error)});
targets.add(new Object[]{getString(R.string.package_hook_bootlooped), getContext().getColor(R.color.error)});
for (Object[] target : targets) {
String targetText = (String) target[0];
int color = (int) target[1];
Log.i(TAG, "getSpannedDescription: " + targetText);
int startIndex = description.indexOf(targetText);
int endIndex = startIndex + targetText.length();

if (startIndex != -1) {
spannableStringBuilder.setSpan(new ForegroundColorSpan(color), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return spannableStringBuilder;
}

@Override
public void onStop() {
super.onStop();
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -708,8 +708,13 @@
<string name="package_hooked_successful">Package responsive</string>
<string name="package_not_hook_enabled">Package not enabled in LSposed</string>
<string name="package_hook_no_response">Package not responding</string>
<string name="package_hook_bootlooped">Package disable because bootloops</string>
<string name="package_hook_bootlooped">Package disabled because bootloops</string>
<string name="package_not_found">Package not found</string>
<string name="info_hooks">Hooks Info</string>
<string name="info_hooks_desc">Explanation\n\n
Package responsive means that everything works fine,\n\n
Package disabled because bootloops means that there are errors in hooking, so the package is disabled from hooking. Get in touch with the dev to solve.\n\n
Package not responding means that the app probably isn\'t enabled in LSPosed or is closed, try to launch the app and check if package is responsive.</string>
<string name="package_checking">Loading %s</string>
<string name="package_activated">Package successfully activated</string>
<string name="package_activation_failed">Package activation failed</string>
Expand Down

0 comments on commit 05e050b

Please sign in to comment.