From ab6c021c1c844ed37150d7ebc91c8480b7583460 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 12 Nov 2019 18:48:26 -0500 Subject: [PATCH] Added comments and summaries to DialogFrag.java, SignApk.java and WriteApk.java --- .../smapiandroidinstaller/DialogFrag.java | 42 +++++++++++++++++++ .../smapiandroidinstaller/SignApk.java | 19 ++++++++- .../smapiandroidinstaller/WriteApk.java | 40 ++++++++++++++++-- 3 files changed, 95 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/MartyrPher/smapiandroidinstaller/DialogFrag.java b/app/src/main/java/com/MartyrPher/smapiandroidinstaller/DialogFrag.java index ffdb1af..8f5ba7c 100644 --- a/app/src/main/java/com/MartyrPher/smapiandroidinstaller/DialogFrag.java +++ b/app/src/main/java/com/MartyrPher/smapiandroidinstaller/DialogFrag.java @@ -16,34 +16,63 @@ import android.widget.TextView; import java.util.Random; import java.util.concurrent.TimeUnit; +/** + * The dialog that is shown in different situations + */ public class DialogFrag extends DialogFragment { + //The alert dialog public static AlertDialog mAlertDialog; + //Progress bar that is used... to show progress. private static ProgressBar mProgressBar; + + //Text view used to show the install message private static TextView mTextView; + /** + * Empty Constructor + * Do I even need this? + */ public DialogFrag() { } + /** + * Shows the required dialog + * @param context = The activities context + * @param message = The message to show + * @param tag = Which dialog to show (Install or Can't find the app) + */ public static void showDialog(Context context, int message, int tag) { + //Build the dialog AlertDialog.Builder builder = new AlertDialog.Builder(context); + + //Two different cases to show two different dialogs switch(tag) { case 0: + //Dialog for showing the install progress + //Create the layout inflater and inflate it LayoutInflater mLayoutInflater = LayoutInflater.from(context); View dialogView = mLayoutInflater.inflate(R.layout.progress_bar_dialog, null); + + //Set the view, message and is cancelable builder.setView(dialogView); builder.setMessage(message); builder.setCancelable(false); + + //Create the dialog and show it mAlertDialog = builder.create(); mAlertDialog.show(); + + //Set the progress bar and install text mProgressBar = dialogView.findViewById(R.id.progressBar); mTextView = dialogView.findViewById(R.id.install_message); break; case 1: + //Dialog for not finding the app on the device builder.setMessage(message); builder.setPositiveButton("Okay", null); builder.show(); @@ -51,18 +80,31 @@ public class DialogFrag extends DialogFragment { } } + /** + * Updates the progress bar + * @param progress = The progress measured in an int + * @param message = The fun little message to show + */ public static void updateProgressBar(int progress, int message) { mProgressBar.setProgress(progress); mTextView.setText(message); } + /** + * Dismisses the dialog + */ public static void dismissDialog() { if (mAlertDialog.isShowing()) mAlertDialog.dismiss(); } + /** + * This is never used. Not sure why it's still here + * @param context = The activities context + * @param message = The message to show + */ public static void dismissDialogString(Context context, String message) { if(mAlertDialog.isShowing()) diff --git a/app/src/main/java/com/MartyrPher/smapiandroidinstaller/SignApk.java b/app/src/main/java/com/MartyrPher/smapiandroidinstaller/SignApk.java index 88e9ad4..b2ce6c8 100644 --- a/app/src/main/java/com/MartyrPher/smapiandroidinstaller/SignApk.java +++ b/app/src/main/java/com/MartyrPher/smapiandroidinstaller/SignApk.java @@ -13,29 +13,44 @@ import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.X509Certificate; - +/** + * Allows the new APK to be signed using JAR signing + */ public class SignApk { + //TAG used for private static final String TAG = "SignApk"; + + //Path of the keystore private static final String KEYSTORE_LOCATION = Environment.getExternalStorageDirectory() + "/SMAPI Installer/ApkFiles/debug.keystore"; + + //The password for the keystore private static final String KEYSTORE_PASSWORD = "android"; + //Empty Constructor public SignApk() { } + /** + * Attempt tp sign the APK using ZIP Signer + */ public void commitSignApk() { try { + //Input APK and Output APK String inputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/" + ApkExtractor.sourceApkFilename + "_patched.apk"; String outputFile = Environment.getExternalStorageDirectory() + "/SMAPI Installer/base_signed.apk"; - + + //Set the keystore and alias KeyStore keyStore = KeyStoreFileManager.loadKeyStore(KEYSTORE_LOCATION,KEYSTORE_PASSWORD.toCharArray()); String alias = keyStore.aliases().nextElement(); + //get the Cert from the keystore X509Certificate publicKey = (X509Certificate) keyStore.getCertificate(alias); try { + //Grab the private key and then use ZipSigner to sign the apk PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, KEYSTORE_PASSWORD.toCharArray()); ZipSigner.signZip(publicKey, privateKey, "SHA1withRSA", inputFile, outputFile); } diff --git a/app/src/main/java/com/MartyrPher/smapiandroidinstaller/WriteApk.java b/app/src/main/java/com/MartyrPher/smapiandroidinstaller/WriteApk.java index 7115d14..2f3bc3d 100644 --- a/app/src/main/java/com/MartyrPher/smapiandroidinstaller/WriteApk.java +++ b/app/src/main/java/com/MartyrPher/smapiandroidinstaller/WriteApk.java @@ -1,6 +1,5 @@ package com.MartyrPher.smapiandroidinstaller; -import android.nfc.Tag; import android.util.Log; import java.io.BufferedInputStream; @@ -14,9 +13,12 @@ import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; - +/** + * Writes files to the APK + */ public class WriteApk { + //TAG used for debug purposes private static final String TAG = "WriteApk"; //Blank Constructor @@ -24,19 +26,28 @@ public class WriteApk { { } + /** + * Adds the files to the APK + * @param source = The file source + * @param files = The file array to add to the APK + * @param path = The paths where the files need to go in the APK + * @param compression = Whether the file needs to be compressed inside the APK + */ public void addFilesToApk(File source, File[] files, String[] path, boolean[] compression){ try { - byte[] buffer = new byte[4096]; + //Hmmmmmmmmm + byte[] buffer = new byte[2048]; + //Create new Input and Output stream ZipInputStream zin = new ZipInputStream(new FileInputStream(source)); ZipOutputStream out = new ZipOutputStream(new FileOutputStream( source + "_patched.apk")); + //Create new CRC32 CRC32 crc = new CRC32(); for(int i = 0; i < files.length; i++) { - if (!compression[i]) { int bytesRead; @@ -51,6 +62,7 @@ public class WriteApk { InputStream in = new FileInputStream(files[i]); ZipEntry compress = new ZipEntry(path[i] + files[i].getName()); + //If the file doesn't need to be compressed then STORE them if (!compression[i]) { compress.setMethod(ZipEntry.STORED); @@ -66,10 +78,13 @@ public class WriteApk { out.closeEntry(); in.close(); } + for(ZipEntry ze = zin.getNextEntry(); ze != null; ze = zin.getNextEntry()){ if(!apkEntryMatch(ze.getName(), files, path)){ ZipEntry loc_ze = new ZipEntry(ze.getName()); loc_ze.setMethod(ZipEntry.DEFLATED); + + //STORE these type of files {Assemblies, resources and typemap} if (loc_ze.getName().contains("assemblies") || loc_ze.getName().contains("resources.arsc") || loc_ze.getName().contains("typemap")) { loc_ze.setMethod(ZipEntry.STORED); @@ -77,15 +92,19 @@ public class WriteApk { loc_ze.setCompressedSize(ze.getCompressedSize()); loc_ze.setCrc(ze.getCrc()); } + out.putNextEntry(loc_ze); ZipFile zipFile = new ZipFile(source); InputStream stream = zipFile.getInputStream(ze); + for(int read = stream.read(buffer); read > -1; read = stream.read(buffer)){ out.write(buffer, 0, read); } out.closeEntry(); } } + + //Close everything and delete the source file out.close(); zin.close(); source.delete(); @@ -95,6 +114,19 @@ public class WriteApk { } } + /*********************************************************************************** + | Check if the current entry matches a file that needs to be placed in the APK + | zeName = The ZipEntry Name + | files = The files that are being checked + | path = The path that is being checked + ***********************************************************************************/ + /** + * Check if the current entry matches a file that needs to be placed in the APK + * @param zeName = The ZipEntry Name + * @param files = The files that are being checked + * @param path = The path that is being checked + * @return true is the entry matches the file in the APK + */ private boolean apkEntryMatch(String zeName, File[] files, String[] path){ for(int i = 0; i < files.length; i++){ if((path[i] + files[i].getName()).equals(zeName)){