From 75ee1d7b1637d672d224e0162f2f9437094a785f Mon Sep 17 00:00:00 2001
From: Li
Date: Mon, 29 Apr 2024 00:52:34 +1200
Subject: [PATCH] improve backup function
---
app/src/main/AndroidManifest.xml | 4 +
.../com/psmreborn/nopsmdrm/DumpAllRifs.java | 77 ++++++++++++++++++
.../java/com/psmreborn/nopsmdrm/Helper.java | 6 ++
.../com/psmreborn/nopsmdrm/MainActivity.java | 52 +++++++++---
.../psmreborn/nopsmdrm/NoPsmDrmInstaller.java | 64 +++++++++++----
.../java/com/psmreborn/nopsmdrm/Root.java | 28 +++++--
.../java/com/psmreborn/nopsmdrm/Startup.java | 30 +++++--
.../pscertified/PsCertificatesInstaller.java | 16 +++-
app/src/main/res/layout/activity_main.xml | 11 +++
app/src/main/res/raw/libdefault.so | Bin 12664 -> 12800 bytes
app/src/main/res/values/strings.xml | 2 +-
libsuperuser/build.gradle | 2 +-
12 files changed, 246 insertions(+), 46 deletions(-)
create mode 100644 app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f06ec5b..9704c5f 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,6 +1,10 @@
+
+
+
+
diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java b/app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java
new file mode 100644
index 0000000..d713221
--- /dev/null
+++ b/app/src/main/java/com/psmreborn/nopsmdrm/DumpAllRifs.java
@@ -0,0 +1,77 @@
+package com.psmreborn.nopsmdrm;
+
+import android.app.Activity;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.net.wifi.WifiManager;
+import android.os.Environment;
+import android.os.Handler;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+
+public class DumpAllRifs {
+ public static void setDumpAllFlagAndStartPsm(Activity ctx) {
+ ProgressDialog dialog = new ProgressDialog(ctx);
+ dialog.setTitle("Starting PSM ...");
+ dialog.setMessage("Please Wait ...");
+ dialog.setIndeterminate(true);
+ dialog.setCancelable(false);
+ dialog.show();
+
+ new Thread(() -> {
+ Handler handler = new Handler(ctx.getMainLooper());
+ File psmFolder = new File(Environment.getExternalStorageDirectory(), "psm");
+ File psmDumpAllFlagFile = new File(psmFolder, "dump_all");
+ File psmAndroidFolder = new File(new File(new File(new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data"), "com.playstation.psstore"), "files"), "psm");
+
+ // stop psm
+ Helper.killPsm();
+
+ try {
+ psmDumpAllFlagFile.createNewFile();
+ } catch (IOException e) {
+ return;
+ }
+
+ // get a games title id..
+ String titleId = "";
+ String[] allGames = psmAndroidFolder.list();
+ for(String chkTitleId : allGames) {
+ File appInfoFile = new File(new File(new File(psmAndroidFolder, chkTitleId), "Application"), "app.info");
+ if(appInfoFile.exists()){
+ titleId = chkTitleId;
+ }
+ }
+
+ if(titleId.equals("")){
+ return;
+ }
+
+ Log.d("DUMPALLRIFS", "Using TitleID: "+titleId);
+
+ WifiManager wifiManager = (WifiManager) ctx.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+ if(wifiManager != null){
+ Intent intent = new Intent("com.playstation.psm.intent.action.START_CONTENT");
+ intent.putExtra("titleId", titleId);
+ intent.setData(Uri.parse("psgmpsm:play?titleId="+titleId));
+
+ handler.post(() -> {
+ // disable wifi
+ wifiManager.setWifiEnabled(false);
+
+ // start psm ...
+ ctx.startActivity(intent);
+
+ dialog.dismiss();
+ });
+ }
+ else{
+ return;
+ }
+ }).start();
+ }
+}
diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java b/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java
index 791ed67..ac01934 100644
--- a/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java
+++ b/app/src/main/java/com/psmreborn/nopsmdrm/Helper.java
@@ -1,5 +1,7 @@
package com.psmreborn.nopsmdrm;
+import android.app.Activity;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
@@ -40,6 +42,10 @@ public class Helper {
return true;
}
+ public static void killPsm(){
+ ActivityManager am = (ActivityManager) ctx.getSystemService(Activity.ACTIVITY_SERVICE);
+ am.killBackgroundProcesses("com.playstation.psstore");
+ }
public static ApplicationInfo getAppInfo(String pkg) throws PackageManager.NameNotFoundException {
ApplicationInfo appInfo = ctx.getPackageManager().getApplicationInfo(pkg, 0);
return appInfo;
diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java b/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java
index c0f7a73..c3ec98d 100644
--- a/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java
+++ b/app/src/main/java/com/psmreborn/nopsmdrm/MainActivity.java
@@ -3,8 +3,14 @@ package com.psmreborn.nopsmdrm;
import android.app.Activity;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.net.wifi.WifiManager;
import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@@ -13,9 +19,12 @@ import android.view.View;
import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified;
import com.psmreborn.nopsmdrm.pscertified.PsCertificatesInstaller;
+import java.io.File;
+
public class MainActivity extends Activity {
+ /*
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
@@ -37,6 +46,7 @@ public class MainActivity extends Activity {
return super.onOptionsItemSelected(item);
}
}
+ */
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -54,23 +64,43 @@ public class MainActivity extends Activity {
super.onBackPressed();
}
+ private void psCertifiedAlert(){
+ new AlertDialog.Builder((Activity)this)
+ .setTitle("PS Certification Missing")
+ .setMessage("Your device appears to not be\"PlayStation Certified\"\nDo you want to certify it?\n(Warning: modifies /system/)")
+ .setCancelable(false)
+ .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ (new PsCertificatesInstaller(MainActivity.this)).execute();
+ }
+ })
+ .setNegativeButton("No", null).show();
+ }
public void installStart(View view) {
PlayStationCertified playStationCertified = new PlayStationCertified(this);
if(!playStationCertified.isPlaystationCertified()){
- new AlertDialog.Builder((Activity)this)
- .setTitle("PS Certification Missing")
- .setMessage("Your device appears to not be\"PlayStation Certified\"\nDo you want to certify it?\n(Warning: modifies /system/)")
- .setCancelable(false)
- .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- (new PsCertificatesInstaller(MainActivity.this)).execute();
- }
- })
- .setNegativeButton("No", null).show();
+ psCertifiedAlert();
}
else {
(new NoPsmDrmInstaller(this)).execute();
}
}
+
+ public void dumpAllRifs(View view){
+ String rifOutput = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath();
+ new AlertDialog.Builder((Activity)this)
+ .setTitle("Backup licenses")
+ .setMessage("This will show a black screen for awhile\nthen a PlayStation Mobile game will start\nOnce the game starts, a backup of all your PSM licenses can be found at\n\""+rifOutput+"\"\nDo you want to do this?")
+ .setCancelable(false)
+ .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ DumpAllRifs.setDumpAllFlagAndStartPsm(MainActivity.this);
+ }
+ })
+ .setNegativeButton("No", null).show();
+
+ }
+
}
diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java b/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java
index ac36f54..f284c4c 100644
--- a/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java
+++ b/app/src/main/java/com/psmreborn/nopsmdrm/NoPsmDrmInstaller.java
@@ -11,14 +11,17 @@ import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
+import android.os.Handler;
import android.telephony.TelephonyManager;
import android.util.Log;
+import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
import java.util.Locale;
import eu.chainfire.libsuperuser.Shell;
@@ -30,10 +33,13 @@ public class NoPsmDrmInstaller extends AsyncTask {
private String errorMsg = "";
private ProgressDialog dialog = null;
private Context ctx = null;
+ private Handler handler = null;
private StringEncryptor stringEncryptor = null;
public NoPsmDrmInstaller(Context context){
this.ctx = context;
+ this.handler = new Handler(ctx.getMainLooper());
+
this.stringEncryptor = new StringEncryptor(this.ctx);
}
@@ -98,27 +104,50 @@ public class NoPsmDrmInstaller extends AsyncTask {
writer.close();
}
- private void backupPsm() throws Exception {
+
+ private void backupPsm() throws Exception {
String psmFilesDir = new File(getPsmApp().dataDir, "files").getAbsolutePath();
String psmKdcDir = new File(psmFilesDir, "kdc").getAbsolutePath();
String psmActFile = new File(psmKdcDir, "act.dat").getAbsolutePath();
+ String psmAndroidFolder = new File(new File(new File(new File(new File(Environment.getExternalStorageDirectory(), "Android"), "data"), "com.playstation.psstore"), "files"), "psm").getAbsolutePath();
+ String psmSdcardFolder = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath();
- // check if "act.dat" exists -- they've been here before ...
- if(fileExistRoot(psmActFile)) {
- String psmSdcardFolder = new File(Environment.getExternalStorageDirectory(), "psm").getAbsolutePath();
+ String devinfoFile = new File(ctx.getCacheDir(), "devinfo.txt").getAbsolutePath();
+ String tarFilename = new File(psmSdcardFolder, "psm_"+getDateTime() + ".tar").getAbsolutePath();
+
+
+ // check if "act.dat" exists -- they've used PSM before ...
+ if(Root.fileExistRoot(psmActFile)) {
new File(psmSdcardFolder).mkdirs();
- String filename = "psm_"+getDateTime();
-
- // tar up the files
- tarRoot(getPsmApp().dataDir,new File(psmSdcardFolder, filename+".tar").getAbsolutePath());
+ File psmAndroidFile = new File(psmAndroidFolder);
// generate device fingerprint file
- generateDeviceFingerprint(new File(psmSdcardFolder, filename + "_DEV.txt").getAbsolutePath());
+ generateDeviceFingerprint(devinfoFile);
+
+ ArrayList filesToTar = new ArrayList();
+ filesToTar.add(getPsmApp().dataDir);
+ filesToTar.add(devinfoFile);
+
+ // add all license folders ....
+ if(psmAndroidFile.exists()){
+ for(String gameFolder : psmAndroidFile.list()){
+ File licenseFolder = new File(new File(psmAndroidFile, gameFolder), "License");
+ if(licenseFolder.exists()){
+ filesToTar.add(licenseFolder.toString());
+ }
+ }
+ }
+
+ // tar up the files
+ tarRoot(filesToTar, tarFilename);
+
+ handler.post(() -> {
+ Toast.makeText(ctx.getApplicationContext(),"Backed up existing PSM Data to:\n\""+tarFilename+"\"", Toast.LENGTH_LONG).show();
+ });
}
}
-
private void makeDirs() throws PackageManager.NameNotFoundException, Shell.ShellDiedException {
mkdirAndChmodChown(new File(getPsmApp().dataDir, "cache").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid()));
mkdirAndChmodChown(new File(getPsmApp().dataDir, "shared_prefs").getAbsolutePath(), 771, String.valueOf(stringEncryptor.getPsmUid()));
@@ -133,8 +162,8 @@ public class NoPsmDrmInstaller extends AsyncTask {
// check if signininfo.xml file exists or not ...
boolean signinInfoExist = fileExistRoot(new File(sharedPrefsPath, "SigninInfo.xml").getAbsolutePath());
- if (!signinInfoExist) { // if file not found ...
- // then generate our own shared_prefs
+ if (!signinInfoExist) { // if no psmdrm activation file was found
+ // then generate our own shared_prefs
// encrypt the actual strings, username, password, etc
String emailAddress = stringEncryptor.encryptString(Helper.sharedPrefs.getString("saveAccountEmail","nopsmdrm@transrights.lgbt"));
@@ -242,10 +271,11 @@ public class NoPsmDrmInstaller extends AsyncTask {
}
@Override
protected void onPreExecute() {
- Shell.setRedirectDeprecated(false);
-
dialog = new ProgressDialog(ctx);
- dialog.setTitle("Installing NoPsmDrm ...");
+ if(!Helper.isNoPsmDrmAlreadyInstalled())
+ dialog.setTitle("Installing NoPsmDrm ...");
+ else
+ dialog.setTitle("Updating NoPsmDrm ...");
dialog.setMessage("Please Wait ...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
@@ -258,7 +288,7 @@ public class NoPsmDrmInstaller extends AsyncTask {
try {
Root.setContext(ctx);
- killApplication("com.playstation.psstore");
+ Helper.killPsm();
if (isPsmInstalled()) {
backupPsm();
@@ -295,7 +325,7 @@ public class NoPsmDrmInstaller extends AsyncTask {
}
else{
new AlertDialog.Builder((Activity)ctx)
- .setTitle("Installed!")
+ .setTitle("Finished!")
.setMessage("Your PSM Application was patched successfully!\n\nNote: WI-FI has to be turned off for games to work.")
.setCancelable(false)
.setPositiveButton("Ok", null).show();
diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/Root.java b/app/src/main/java/com/psmreborn/nopsmdrm/Root.java
index 97a1899..5e4063e 100644
--- a/app/src/main/java/com/psmreborn/nopsmdrm/Root.java
+++ b/app/src/main/java/com/psmreborn/nopsmdrm/Root.java
@@ -9,6 +9,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
import eu.chainfire.libsuperuser.Shell;
@@ -16,9 +17,9 @@ public class Root {
private static String busyboxBinary = null;
private static Context ctx = null;
- public static void killApplication(String processName) throws Shell.ShellDiedException {
- Log.i("ROOT", "Killing process: " + processName);
- Shell.Pool.SU.run(new String[] { busyboxBinary + " pkill -9 '" + processName +"'" });
+ public static void reboot() throws Shell.ShellDiedException {
+ Log.i("ROOT", "Rebooting");
+ Shell.Pool.SU.run(new String[] { busyboxBinary + " reboot" });
}
public static boolean fileExistRoot(String filename) throws Shell.ShellDiedException {
Log.i("ROOT", "FileExistRoot: " + filename);
@@ -26,12 +27,24 @@ public class Root {
return res == 0;
}
- public static void tarRoot(String src, String dst) throws IOException, Shell.ShellDiedException {
- Log.i("ROOT", "TarRoot: " + src + " : "+ dst);
- int res = Shell.Pool.SU.run(new String[]{busyboxBinary + " tar c '" + src + "' -f '" + dst +"'"});
+ public static void tarRoot(ArrayList src, String dst) throws IOException, Shell.ShellDiedException {
+ if(src.size() <= 0){
+ throw new IOException("tar src was empty.");
+ };
+
+ Log.i("ROOT", "TarRoot: "+ dst);
+
+ StringBuilder tarFiles = new StringBuilder();
+ for(String file : src) {
+ tarFiles.append("'");
+ tarFiles.append(file);
+ tarFiles.append("' ");
+ }
+
+ int res = Shell.Pool.SU.run(new String[]{busyboxBinary + " tar -cf '" + dst + "' "+tarFiles.toString()});
if (res != 0) {
Log.e("ROOT", "error (" + String.valueOf(res) +")");
- throw new IOException("Failed to tar " + src);
+ throw new IOException("Failed to tar " + dst);
}
}
public static void remountRo(String foldername) throws IOException, Shell.ShellDiedException {
@@ -136,6 +149,7 @@ public class Root {
public static void setContext(Context context) throws IOException {
ctx = context;
+ Shell.setRedirectDeprecated(false);
setupBusyBox();
}
}
diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java b/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java
index a98cf2d..6787779 100644
--- a/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java
+++ b/app/src/main/java/com/psmreborn/nopsmdrm/Startup.java
@@ -5,12 +5,16 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Environment;
+import android.os.Handler;
import android.widget.Button;
import android.widget.TextView;
import eu.chainfire.libsuperuser.Shell;
import static com.psmreborn.nopsmdrm.Helper.*;
+import com.psmreborn.nopsmdrm.pscertified.PlayStationCertified;
+import com.psmreborn.nopsmdrm.pscertified.PsCertificatesInstaller;
+
import java.io.File;
public class Startup extends AsyncTask {
@@ -29,20 +33,26 @@ public class Startup extends AsyncTask {
if(!Shell.SU.available()){
wasError = true;
errorMsg = "Unable to get root permission.";
+ return null;
}
if(!Helper.isPsmInstalled()){
wasError = true;
errorMsg = "PSM Application is not installed, please install it first!";
+ return null;
}
if(!(getPsmApp().sourceDir.startsWith("/data/") || getPsmApp().sourceDir.startsWith("/system/"))){
wasError = true;
errorMsg = "PSM Application is installed to the SD Card not internal storage.";
+ return null;
}
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
wasError = true;
errorMsg = "No SD Card inserted.";
+ return null;
}
+ Root.setContext(this.ctx);
+
} catch (Exception e) {
wasError = true;
errorMsg = e.getMessage();
@@ -54,19 +64,25 @@ public class Startup extends AsyncTask {
protected void onPostExecute(Void result) {
TextView statusTV = (TextView) ((Activity)ctx).findViewById(R.id.errorMsg);
Button installButton = (Button) ((Activity)ctx).findViewById(R.id.installPsm);
+ Button backupGamesButton = (Button) ((Activity)ctx).findViewById(R.id.dumpGames);
+ Handler handler = new Handler(this.ctx.getMainLooper());
if(!wasError) {
- statusTV.setText("");
+ handler.post(() -> {
+ statusTV.setText("");
- if(isNoPsmDrmAlreadyInstalled()){
- installButton.setText("Update NoPsmDrm");
- };
-
- installButton.setEnabled(true);
+ if(Helper.isNoPsmDrmAlreadyInstalled()){
+ installButton.setText("Update NoPsmDrm");
+ };
+ installButton.setEnabled(true);
+ backupGamesButton.setEnabled(true);
+ });
}
else{
- statusTV.setText("Error: "+errorMsg);
+ handler.post(() -> {
+ statusTV.setText("Error: " + errorMsg);
+ });
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java b/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java
index 221bb15..55d3942 100644
--- a/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java
+++ b/app/src/main/java/com/psmreborn/nopsmdrm/pscertified/PsCertificatesInstaller.java
@@ -13,6 +13,7 @@ import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
+import android.os.Handler;
import android.os.PowerManager;
@@ -84,9 +85,20 @@ public class PsCertificatesInstaller extends AsyncTask {
else{
new AlertDialog.Builder((Activity)ctx)
.setTitle("Installed!")
- .setMessage("Your device is now \"Playstation Certified\"\n(You may have to reboot for changes to take effect)")
+ .setMessage("Your device is now \"Playstation Certified\"\n(You have to reboot for changes to take effect)\nReboot?")
.setCancelable(false)
- .setPositiveButton("Ok",null).show();
+ .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Handler handler = new Handler(PsCertificatesInstaller.this.ctx.getMainLooper());
+ handler.post(() -> {
+ try {
+ Root.reboot();
+ } catch (Shell.ShellDiedException e) {}
+ });
+ }
+ })
+ .setNegativeButton("No", null).show();
}
}
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 44c70b0..e013f7b 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -29,4 +29,15 @@
android:layout_below="@+id/errorMsg"
android:text="Install NoPsmDrm"/>
+
+
\ No newline at end of file
diff --git a/app/src/main/res/raw/libdefault.so b/app/src/main/res/raw/libdefault.so
index 72b53a70a5764bf03a73d2f3967b39a15c8ba0ea..09aef59a96aaf69fd7acd10e5ca6036c7c6f0ce9 100644
GIT binary patch
delta 3114
zcmY+G4^&gv8Nk0s5`vaL5d;D}@g)HaiXjLpDvkVkK1l+~9HUw5Dq5$ZLt#=KBAQrR
zkL~d&dg%^W=diXL72Dzz=jnki+vz;kvvpxQ#{t)Zit^_%y82gVRg0DY8c0JkWO0E3k20Cy?p1B_5E01zp$Fnp9I
zfJc;AQj?Ts7r;}hWMc|&M{$b*l$1-bwkVeZgi~T|Xed_z%%;Rb(o*IFu#`mr93>Bs
zLb(dSNLdV!L21RfgA0e1gTEY(96UN0=KE}T#Ef>{lCsxOVvVh_8DX0{UQ(-WQ~M
zgY>IGx+h4#9He&!>Fq&!TaaGT64Yo4(hmjc?jXHBNUsgjov4#@;XdMwJj4u;hmorn
zkKk!OLb-`@7bP+QU?0jM%zhKLPoUn0Qh|C7@(;+*$+oDZHD6Cf*`tbw98vaq{yZHuw53k^4scAydB1_`L0RfDq-levs
z_FQXjX_L?@ye&-fd-;F!Q@lfvrCk$XeBPT~qF`gPt9g!I+mpVv*7_MXro_+XqFr?h9b_*(}X=H!hk+j0;SUhcCjs_LuL+
zd^cdbc>2C9)r%fMd?w2@{e}1`3&THvudpgDCPJqy@~yAqrMMi7fJ&P
zW8cGTD{EK(hU}i5fN(isVr5Ok9EvmoH26#mSy9n=Y{66!Zh%?5Rih
zJ;EvcTAMJ^auh9!rfa61VKJ%`jNx8cDihUKH5M4H`RM{viX5xyd4^*J{1E5h_)r|@
z>pDPUV&}w;jnfrig-dO+qSM#&bQZupvMRP`E|w$Psd1OTt(Cl9PmvqHE~W^x<-cLVwg?jahz^J*|;*Nbk&W47*2gk
zmKw&_3Xl@=PPUnCcBg@INiFp7Sm>Xl9^K=bkXeqk0wLlAK
z&nFwSnd*`;!1>C^JKFCvjbv0?SDKTGeGjdc
zo_aEr@KT65g;)|RRD%Y9Pf2UyVocUw64MKAjo_c0m&3}ErQ}gCrh5wndJ6MLHF|nG
z$42lXv2^j=DCjh}p}~>%!mqA>Qh2Mc3@^lTvMgz#UBoC~_PTW(`vt5+>q%^TdTD>$
zC~*Cl-fJTs;aB?UmbF-sP%dSaL~*&%hDE7#Qr#<7$eH~ZtBLzMDv9%_DuN7%{#Z%R&C$PZLF^5c2sSt
z<4h(Kms-dDY-1g_rDo^$&Dh2}2$^-8U)i{0b7pPbwoE!^0}enlc_FY@{a84?Cf-}_p{x771@OLzPqxk8F_hF
zcC{cU?@jwVN2dL&ksV>@-5!6t-R-072yt_xwEwKT9a)d#n#ZU8c#+!M-DSuQjeC*%
zq~CDX9X>Jb@CK#E?e0U;02%+3T|5TJe?S8(-MJ(yqmF4JA7s3O@8TH?e;vOb-#6tb
zKgCxbeaOB`(@%M_
u!>m{N-|VE-Y*01f+pLNF9=mDOG7}jyr-dM*v(lKeWLefc<~rG!75`r%6gZy%
delta 2930
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
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5fd6bd5..37582f6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,3 @@
- NoPsmDrm Installer
+ NoPsmDrm
\ No newline at end of file
diff --git a/libsuperuser/build.gradle b/libsuperuser/build.gradle
index cd78e4a..d2f7d76 100644
--- a/libsuperuser/build.gradle
+++ b/libsuperuser/build.gradle
@@ -12,7 +12,7 @@ android {
buildTypes {
release {
- minifyEnabled false
+ minifyEnabled true
}
}
compileOptions {