|
|
@@ -1,6 +1,7 @@
|
|
|
package com.example.modifier.fragments;
|
|
|
|
|
|
import android.annotation.SuppressLint;
|
|
|
+import android.content.Intent;
|
|
|
import android.os.Bundle;
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
@@ -9,39 +10,57 @@ import androidx.fragment.app.Fragment;
|
|
|
|
|
|
import android.os.Handler;
|
|
|
import android.os.Looper;
|
|
|
+import android.util.Log;
|
|
|
import android.view.LayoutInflater;
|
|
|
import android.view.View;
|
|
|
import android.view.ViewGroup;
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
+import com.android.volley.Request;
|
|
|
+import com.android.volley.RequestQueue;
|
|
|
+import com.android.volley.toolbox.JsonObjectRequest;
|
|
|
+import com.android.volley.toolbox.RequestFuture;
|
|
|
+import com.android.volley.toolbox.Volley;
|
|
|
import com.example.modifier.Global;
|
|
|
import com.example.modifier.Config;
|
|
|
+import com.example.modifier.MainActivity;
|
|
|
import com.example.modifier.ModifierService;
|
|
|
import com.example.modifier.R;
|
|
|
import com.example.modifier.Utils;
|
|
|
import com.example.modifier.databinding.FragmentSettingsBinding;
|
|
|
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
|
import com.google.gson.Gson;
|
|
|
|
|
|
import org.apache.commons.lang3.RandomStringUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.json.JSONObject;
|
|
|
|
|
|
import java.io.File;
|
|
|
import java.io.FileReader;
|
|
|
import java.io.FileWriter;
|
|
|
+import java.io.IOException;
|
|
|
+import java.time.Instant;
|
|
|
import java.util.Objects;
|
|
|
import java.util.Optional;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
import java.util.concurrent.Executors;
|
|
|
+import java.util.concurrent.ScheduledFuture;
|
|
|
+import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.TimeoutException;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
|
|
public class SettingsFragment extends Fragment {
|
|
|
|
|
|
private FragmentSettingsBinding binding;
|
|
|
|
|
|
Handler handler = new Handler(Looper.getMainLooper());
|
|
|
- ExecutorService executor = Executors.newFixedThreadPool(4);
|
|
|
+ ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(8);
|
|
|
|
|
|
public SettingsFragment() {
|
|
|
-
|
|
|
+ Log.i("SettingsFragment", "SettingsFragment");
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -55,6 +74,9 @@ public class SettingsFragment extends Fragment {
|
|
|
@Override
|
|
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
|
|
Bundle savedInstanceState) {
|
|
|
+ if (binding != null) {
|
|
|
+ return binding.getRoot();
|
|
|
+ }
|
|
|
binding = FragmentSettingsBinding.inflate(inflater, container, false);
|
|
|
binding.tlIccid.setEndIconOnClickListener(v -> {
|
|
|
binding.etIccid.setText(RandomStringUtils.randomNumeric(20));
|
|
|
@@ -102,6 +124,129 @@ public class SettingsFragment extends Fragment {
|
|
|
}, 500);
|
|
|
});
|
|
|
|
|
|
+ binding.btnRequest.setOnClickListener(v -> {
|
|
|
+
|
|
|
+ Utils.addProgressIndicator(getContext(), binding.btnRequest);
|
|
|
+ binding.btnRequest.setEnabled(false);
|
|
|
+ executor.submit(() -> {
|
|
|
+ try {
|
|
|
+
|
|
|
+ RequestQueue queue = Volley.newRequestQueue(getContext());
|
|
|
+ RequestFuture<JSONObject> future = RequestFuture.newFuture();
|
|
|
+ JsonObjectRequest request = new JsonObjectRequest(Request.Method.PUT, Global.serverUrl + "/api/rcs-number", null, future, future);
|
|
|
+ queue.add(request);
|
|
|
+
|
|
|
+ JSONObject jsonObject = future.get(60, TimeUnit.SECONDS);
|
|
|
+ Integer id = jsonObject.getInt("id");
|
|
|
+ String expiryTimeStr = jsonObject.getString("expiryTime");
|
|
|
+ Instant expiryTime = Instant.parse(expiryTimeStr);
|
|
|
+ String number = jsonObject.getString("number");
|
|
|
+ String mcc = jsonObject.getString("mcc");
|
|
|
+ String mnc = jsonObject.getString("mnc");
|
|
|
+ String country = jsonObject.getString("country");
|
|
|
+ String iccid = RandomStringUtils.randomNumeric(20);
|
|
|
+ String imsi = mcc + mnc + RandomStringUtils.randomNumeric(15 - mcc.length() - mnc.length());
|
|
|
+ String imei = Utils.generateIMEI();
|
|
|
+ Global.save(new Config(number, mcc, mnc, iccid, imsi, imei, country));
|
|
|
+
|
|
|
+ Global.stop(false, true, true);
|
|
|
+
|
|
|
+ handler.post(() -> {
|
|
|
+ Config config = Global.config;
|
|
|
+ binding.etNumber.setText(config.getNumber());
|
|
|
+ binding.etMcc.setText(config.getMcc());
|
|
|
+ binding.etMnc.setText(config.getMnc());
|
|
|
+ binding.etIccid.setText(config.getIccid());
|
|
|
+ binding.etImsi.setText(config.getImsi());
|
|
|
+ binding.etImei.setText(config.getImei());
|
|
|
+ binding.etCountry.setText(config.getCountry());
|
|
|
+ binding.btnRequest.setText("Waiting for OTP...");
|
|
|
+ });
|
|
|
+
|
|
|
+ try {
|
|
|
+ Utils.runAsRoot("am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER com.google.android.apps.messaging");
|
|
|
+ Thread.sleep(1000);
|
|
|
+ Utils.runAsRoot("am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.SettingsActivity;");
|
|
|
+ Utils.runAsRoot("am start com.google.android.apps.messaging/com.google.android.apps.messaging.ui.appsettings.RcsSettingsActivity;");
|
|
|
+ Thread.sleep(1000);
|
|
|
+ Intent intent = new Intent(getContext(), MainActivity.class);
|
|
|
+ intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
|
|
+ startActivity(intent);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean success = false;
|
|
|
+ while (Instant.now().isBefore(expiryTime)) {
|
|
|
+ try {
|
|
|
+ Log.i("SettingsFragment", "Waiting for OTP...");
|
|
|
+ RequestFuture<JSONObject> future1 = RequestFuture.newFuture();
|
|
|
+ JsonObjectRequest request1 = new JsonObjectRequest(Request.Method.GET, Global.serverUrl + "/api/rcs-number/" + id, null, future1, future1);
|
|
|
+ queue.add(request1);
|
|
|
+ JSONObject jsonObject1 = null;
|
|
|
+ try {
|
|
|
+ jsonObject1 = future1.get(60, TimeUnit.SECONDS);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ if (jsonObject1 == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String status = jsonObject1.optString("status");
|
|
|
+ if ("success".equals(status)) {
|
|
|
+ String message = jsonObject1.optString("message");
|
|
|
+ Matcher matcher = Pattern.compile("Your Messenger verification code is G-(\\d{6})")
|
|
|
+ .matcher(message);
|
|
|
+ if (matcher.find()) {
|
|
|
+ String otp = matcher.group(1);
|
|
|
+ Intent intent = new Intent();
|
|
|
+ intent.setAction("com.example.modifier.sms");
|
|
|
+ intent.putExtra("sender", "3538");
|
|
|
+ intent.putExtra("message", "Your Messenger verification code is G-" + otp);
|
|
|
+ getContext().sendBroadcast(intent);
|
|
|
+ success = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Thread.sleep(2000);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!success) {
|
|
|
+ handler.post(() -> {
|
|
|
+ new MaterialAlertDialogBuilder(getContext())
|
|
|
+ .setTitle("Error")
|
|
|
+ .setMessage("Failed to get OTP")
|
|
|
+ .setPositiveButton("OK", (dialog, which) -> {
|
|
|
+ dialog.dismiss();
|
|
|
+ })
|
|
|
+ .show();
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ handler.post(() -> {
|
|
|
+ new MaterialAlertDialogBuilder(getContext())
|
|
|
+ .setTitle("Success")
|
|
|
+ .setMessage("OTP sent successfully")
|
|
|
+ .setPositiveButton("OK", (dialog, which) -> {
|
|
|
+ dialog.dismiss();
|
|
|
+ })
|
|
|
+ .show();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ handler.post(() -> {
|
|
|
+ binding.btnRequest.setEnabled(true);
|
|
|
+ binding.btnRequest.setIcon(null);
|
|
|
+ binding.btnRequest.setText("Request");
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
executor.execute(() -> {
|
|
|
Global.load();
|
|
|
handler.post(() -> {
|