Utils.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. package com.example.modifier;
  2. import android.accessibilityservice.AccessibilityServiceInfo;
  3. import android.accounts.AccountManager;
  4. import android.accounts.AuthenticatorDescription;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.content.SharedPreferences;
  8. import android.content.pm.PackageManager;
  9. import android.content.pm.ServiceInfo;
  10. import android.content.res.AssetManager;
  11. import android.content.res.Resources;
  12. import android.content.res.XmlResourceParser;
  13. import android.os.Bundle;
  14. import android.provider.Settings;
  15. import android.text.TextUtils;
  16. import android.util.Log;
  17. import android.view.accessibility.AccessibilityManager;
  18. import com.example.modifier.service.ModifierService;
  19. import com.google.android.material.button.MaterialButton;
  20. import com.google.android.material.progressindicator.CircularProgressIndicatorSpec;
  21. import com.google.android.material.progressindicator.IndeterminateDrawable;
  22. import org.apache.commons.io.IOUtils;
  23. import org.apache.commons.lang3.RandomStringUtils;
  24. import org.apache.commons.lang3.StringUtils;
  25. import org.xmlpull.v1.XmlPullParser;
  26. import java.io.DataOutputStream;
  27. import java.io.File;
  28. import java.io.IOException;
  29. import java.io.InputStream;
  30. import java.io.OutputStream;
  31. import java.lang.reflect.Method;
  32. import java.nio.charset.StandardCharsets;
  33. import java.nio.file.Files;
  34. import java.nio.file.Paths;
  35. import java.util.ArrayList;
  36. import java.util.Arrays;
  37. import java.util.HashMap;
  38. import java.util.List;
  39. import java.util.Objects;
  40. public class Utils {
  41. private static final String TAG = "Modifier";
  42. public static Context getContext() {
  43. try {
  44. Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
  45. Method currentActivityThreadMethod = activityThreadClass.getMethod("currentActivityThread");
  46. currentActivityThreadMethod.setAccessible(true);
  47. Object currentActivityThread = currentActivityThreadMethod.invoke(null);
  48. Method getApplicationMethod = activityThreadClass.getMethod("getApplication");
  49. getApplicationMethod.setAccessible(true);
  50. return (Context) getApplicationMethod.invoke(currentActivityThread);
  51. } catch (Exception e) {
  52. e.printStackTrace();
  53. }
  54. return null;
  55. }
  56. public static String runAsRoot(String... cmds) throws IOException, InterruptedException {
  57. Log.i(TAG, "Trying to run as root");
  58. Process p = new ProcessBuilder("su", "-M").start();
  59. StringBuilder res = new StringBuilder();
  60. StringBuilder err = new StringBuilder();
  61. new Thread(() -> {
  62. try {
  63. res.append(IOUtils.toString(p.getInputStream(), StandardCharsets.UTF_8));
  64. } catch (IOException ignored) {
  65. }
  66. }).start();
  67. new Thread(() -> {
  68. try {
  69. err.append(IOUtils.toString(p.getErrorStream(), StandardCharsets.UTF_8));
  70. } catch (IOException ignored) {
  71. }
  72. }).start();
  73. DataOutputStream outputStream = new DataOutputStream(p.getOutputStream());
  74. for (String cmd : cmds) {
  75. outputStream.writeBytes(cmd + "\n");
  76. outputStream.flush();
  77. Log.i(TAG, "Running command: " + cmd);
  78. }
  79. Thread.sleep(500);
  80. outputStream.writeBytes("exit\n");
  81. outputStream.flush();
  82. p.waitFor();
  83. Log.i(TAG, "Output: " + res);
  84. if (err.length() > 0) {
  85. Log.i(TAG, "Error: " + err);
  86. }
  87. return res.toString();
  88. }
  89. public static boolean isAccessibilityEnabled() {
  90. Context context = getContext();
  91. AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
  92. List<AccessibilityServiceInfo> enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
  93. for (AccessibilityServiceInfo enabledService : enabledServices) {
  94. Log.i(TAG, "Enabled service: " + enabledService.getResolveInfo().serviceInfo.packageName + "/" + enabledService.getResolveInfo().serviceInfo.name);
  95. ServiceInfo enabledServiceInfo = enabledService.getResolveInfo().serviceInfo;
  96. if (enabledServiceInfo.packageName.equals(context.getPackageName()) && enabledServiceInfo.name.equals(ModifierService.NAME))
  97. return true;
  98. }
  99. return false;
  100. }
  101. public static boolean hasRootAccess() {
  102. boolean rootAccess = false;
  103. try {
  104. String res = runAsRoot("echo \"imrooted\"");
  105. if (res.contains("imrooted")) {
  106. rootAccess = true;
  107. }
  108. } catch (Exception e) {
  109. e.printStackTrace();
  110. }
  111. return rootAccess;
  112. }
  113. public static boolean enableAccessibility() {
  114. Context context = getContext();
  115. AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
  116. List<AccessibilityServiceInfo> enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
  117. List<String> names = new ArrayList<>();
  118. for (AccessibilityServiceInfo enabledService : enabledServices) {
  119. names.add(enabledService.getResolveInfo().serviceInfo.packageName + "/" + enabledService.getResolveInfo().serviceInfo.name);
  120. }
  121. names.add(context.getPackageName() + "/" + ModifierService.NAME);
  122. try {
  123. runAsRoot("settings put secure enabled_accessibility_services " + TextUtils.join(":", names),
  124. "settings put secure accessibility_enabled 1");
  125. return true;
  126. } catch (Exception e) {
  127. e.printStackTrace();
  128. }
  129. return false;
  130. }
  131. public static void enableOverlay() {
  132. try {
  133. runAsRoot("appops set " + BuildConfig.APPLICATION_ID + " SYSTEM_ALERT_WINDOW allow");
  134. } catch (Exception e) {
  135. e.printStackTrace();
  136. }
  137. }
  138. public static String getUniqueID() {
  139. Context context = getContext();
  140. Objects.requireNonNull(context);
  141. SharedPreferences sharedPrefs = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE);
  142. String uniqueID = sharedPrefs.getString("unique_id", null);
  143. if (StringUtils.isBlank(uniqueID)) {
  144. try {
  145. uniqueID = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
  146. } catch (Exception e) {
  147. e.printStackTrace();
  148. }
  149. }
  150. if (StringUtils.isBlank(uniqueID)) {
  151. uniqueID = java.util.UUID.randomUUID().toString();
  152. }
  153. sharedPrefs.edit().putString("unique_id", uniqueID).apply();
  154. return uniqueID;
  155. }
  156. public static String generateIMEI() {
  157. int pos;
  158. int[] str = Arrays.stream(("35684610" + RandomStringUtils.randomNumeric(7)).split("")).mapToInt(Integer::parseInt).toArray();
  159. int sum = 0;
  160. int final_digit;
  161. int t;
  162. int len_offset;
  163. int len = 15;
  164. String imei = "";
  165. len_offset = (len + 1) % 2;
  166. for (pos = 0; pos < len - 1; pos++) {
  167. if ((pos + len_offset) % 2 != 0) {
  168. t = str[pos] * 2;
  169. if (t > 9) {
  170. t -= 9;
  171. }
  172. sum += t;
  173. } else {
  174. sum += str[pos];
  175. }
  176. }
  177. final_digit = (10 - (sum % 10)) % 10;
  178. str[len - 1] = final_digit;
  179. for (int d : str) {
  180. imei += String.valueOf(d);
  181. }
  182. return imei;
  183. }
  184. public static String generateIMEI1() {
  185. int pos;
  186. int[] str = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  187. int sum = 0;
  188. int final_digit;
  189. int t;
  190. int len_offset;
  191. int len = 15;
  192. String imei = "";
  193. String[] rbi = new String[]{"01", "10", "30", "33", "35", "44", "45", "49", "50", "51", "52", "53", "54", "86", "91", "98", "99"};
  194. String[] arr = rbi[(int) Math.floor(Math.random() * rbi.length)].split("");
  195. str[0] = Integer.parseInt(arr[0]);
  196. str[1] = Integer.parseInt(arr[1]);
  197. pos = 2;
  198. while (pos < len - 1) {
  199. str[pos++] = (int) (Math.floor(Math.random() * 10) % 10);
  200. }
  201. len_offset = (len + 1) % 2;
  202. for (pos = 0; pos < len - 1; pos++) {
  203. if ((pos + len_offset) % 2 != 0) {
  204. t = str[pos] * 2;
  205. if (t > 9) {
  206. t -= 9;
  207. }
  208. sum += t;
  209. } else {
  210. sum += str[pos];
  211. }
  212. }
  213. final_digit = (10 - (sum % 10)) % 10;
  214. str[len - 1] = final_digit;
  215. for (int d : str) {
  216. imei += String.valueOf(d);
  217. }
  218. return imei;
  219. }
  220. public static void makeLoadingButton(Context context, MaterialButton button) {
  221. CircularProgressIndicatorSpec spec = new CircularProgressIndicatorSpec(context, null, 0,
  222. com.google.android.material.R.style.Widget_Material3_CircularProgressIndicator_ExtraSmall);
  223. IndeterminateDrawable progressIndicatorDrawable = IndeterminateDrawable.createCircularDrawable(context, spec);
  224. button.setIcon(progressIndicatorDrawable);
  225. button.setEnabled(false);
  226. }
  227. public static boolean copyAssetFolder(AssetManager assetManager,
  228. String fromAssetPath, String toPath) {
  229. try {
  230. String[] files = assetManager.list(fromAssetPath);
  231. new File(toPath).mkdirs();
  232. boolean res = true;
  233. for (String file : files)
  234. if (file.contains("."))
  235. res &= copyAsset(assetManager,
  236. fromAssetPath + "/" + file,
  237. toPath + "/" + file);
  238. else
  239. res &= copyAssetFolder(assetManager,
  240. fromAssetPath + "/" + file,
  241. toPath + "/" + file);
  242. return res;
  243. } catch (Exception e) {
  244. e.printStackTrace();
  245. return false;
  246. }
  247. }
  248. public static boolean copyAsset(AssetManager assetManager,
  249. String fromAssetPath, String toPath) {
  250. if (new File(toPath).exists())
  251. return true;
  252. InputStream in = null;
  253. OutputStream out = null;
  254. try {
  255. in = assetManager.open(fromAssetPath);
  256. new File(toPath).createNewFile();
  257. out = Files.newOutputStream(Paths.get(toPath));
  258. IOUtils.copy(in, out);
  259. in.close();
  260. out.flush();
  261. out.close();
  262. return true;
  263. } catch (Exception e) {
  264. e.printStackTrace();
  265. return false;
  266. }
  267. }
  268. public static int dp2px(Context context, int dp) {
  269. float scale = context.getResources().getDisplayMetrics().density;
  270. return (int) (dp * scale + 0.5f);
  271. }
  272. public static void startPreferenceActivity(String type) {
  273. Context context = getContext();
  274. AccountManager accountManager = AccountManager.get(context);
  275. AuthenticatorDescription[] descriptions = accountManager.getAuthenticatorTypes();
  276. AuthenticatorDescription neededDescription = null;
  277. for (AuthenticatorDescription description : descriptions) {
  278. if (description.type.equals(type)) {
  279. neededDescription = description;
  280. break;
  281. }
  282. }
  283. if (neededDescription != null) {
  284. String packageName = neededDescription.packageName;
  285. int prefsId = neededDescription.accountPreferencesId;
  286. try {
  287. Resources resources = context.getPackageManager().getResourcesForApplication(packageName);
  288. XmlResourceParser xpp = resources.getLayout(prefsId);
  289. xpp.next();
  290. String action = null;
  291. String targetPackage = packageName; //default to the account pref package name...?
  292. String targetClass = null;
  293. int eventType = xpp.getEventType();
  294. while (eventType != XmlPullParser.END_DOCUMENT) {
  295. if (eventType == XmlPullParser.START_TAG) {
  296. if (xpp.getName().equals("intent")) {
  297. int count = xpp.getAttributeCount();
  298. for (int i = 0; i < count; i++) {
  299. String name = xpp.getAttributeName(i);
  300. if (name.equals("action")) {
  301. action = xpp.getAttributeValue(i);
  302. } else if (name.equals("targetPackage")) {
  303. targetPackage = xpp.getAttributeValue(i);
  304. } else if (name.equals("targetClass")) {
  305. targetClass = xpp.getAttributeValue(i);
  306. }
  307. }
  308. }
  309. }
  310. eventType = xpp.next();
  311. }
  312. if (action != null) {
  313. context.startActivity(new Intent(action));
  314. } else if (targetClass != null) {
  315. context.startActivity(new Intent(context.createPackageContext(targetPackage, Context.CONTEXT_IGNORE_SECURITY), Class.forName(targetClass)));
  316. }
  317. } catch (PackageManager.NameNotFoundException e) {
  318. e.printStackTrace();
  319. } catch (Exception e) {
  320. e.printStackTrace();
  321. }
  322. }
  323. }
  324. }