diff --git a/ImageSteganographyLibrary/build.gradle b/ImageSteganographyLibrary/build.gradle index 882190d..b177ab8 100644 --- a/ImageSteganographyLibrary/build.gradle +++ b/ImageSteganographyLibrary/build.gradle @@ -3,8 +3,6 @@ apply plugin: 'com.android.library' android { compileSdkVersion 26 - - defaultConfig { minSdkVersion 19 targetSdkVersion 26 @@ -13,8 +11,6 @@ android { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - - } buildTypes { @@ -22,10 +18,29 @@ android { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } + + checkTypes { + javaCompileOptions.annotationProcessorOptions. + classNames.add("org.checkerframework.checker.nullness.NullnessChecker") + // You can pass options like so: + // javaCompileOptions.annotationProcessorOptions.arguments.put("warns", "") + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } } +configurations { + checkerFrameworkAnnotatedJDK { + description = 'a copy of JDK classes with Checker Framework type qualifers inserted' + } +} + + configurations.all { resolutionStrategy { force 'com.android.support:support-annotations:23.1.1' @@ -33,10 +48,23 @@ configurations.all { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - + implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'com.android.support:appcompat-v7:26.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + ext.checkerFrameworkVersion = '2.7.0' + implementation "org.checkerframework:checker-qual:${checkerFrameworkVersion}" + annotationProcessor "org.checkerframework:checker:${checkerFrameworkVersion}" + checkerFrameworkAnnotatedJDK "org.checkerframework:jdk8:${checkerFrameworkVersion}" } + +gradle.projectsEvaluated { + tasks.withType(JavaCompile).all { compile -> + if (compile.name.contains("checkTypes")) { + compile.options.compilerArgs += [ + "-Xbootclasspath/p:${configurations.checkerFrameworkAnnotatedJDK.asPath}" + ] + } + } +} \ No newline at end of file diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextDecodingCallback.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextDecodingCallback.java index f257565..f99c9a8 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextDecodingCallback.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextDecodingCallback.java @@ -2,6 +2,8 @@ import com.ayush.imagesteganographylibrary.Text.ImageSteganography; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + /** * This the callback interface for TextDecoding AsyncTask. */ @@ -10,6 +12,7 @@ public interface TextDecodingCallback { void onStartTextEncoding(); +// @RequiresNonNull("#1") void onCompleteTextEncoding(ImageSteganography result); } diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextEncodingCallback.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextEncodingCallback.java index 3d65d24..f8f9d37 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextEncodingCallback.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/AsyncTaskCallback/TextEncodingCallback.java @@ -2,6 +2,8 @@ import com.ayush.imagesteganographylibrary.Text.ImageSteganography; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + /** * This the callback interface for TextEncoding AsyncTask. */ @@ -10,6 +12,7 @@ public interface TextEncodingCallback { void onStartTextEncoding(); +// @RequiresNonNull("#1") void onCompleteTextEncoding(ImageSteganography result); } diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/EncodeDecode.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/EncodeDecode.java index 1ae5904..1d76d92 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/EncodeDecode.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/EncodeDecode.java @@ -2,10 +2,13 @@ import android.graphics.Bitmap; import android.graphics.Color; +import android.support.annotation.Nullable; import android.util.Log; import com.ayush.imagesteganographylibrary.Utils.Utility; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; @@ -32,8 +35,9 @@ class EncodeDecode { * @parameter : progressHandler {A handler interface, for the progress bar} */ +// @RequiresNonNull({"#1", "#4"}) private static byte[] encodeMessage(int[] integer_pixel_array, int image_columns, int image_rows, - MessageEncodingStatus messageEncodingStatus, ProgressHandler progressHandler) { + MessageEncodingStatus messageEncodingStatus, @Nullable ProgressHandler progressHandler) { //denotes RGB channels int channels = 3; @@ -105,8 +109,9 @@ private static byte[] encodeMessage(int[] integer_pixel_array, int image_columns * @parameter : encrypted_message {string} * @parameter : progressHandler {Progress bar handler} */ +// @RequiresNonNull({"#1"}) public static List encodeMessage(List splitted_images, - String encrypted_message, ProgressHandler progressHandler) { + String encrypted_message, @Nullable ProgressHandler progressHandler) { //Making result method @@ -191,6 +196,7 @@ public static List encodeMessage(List splitted_images, * @parameter : image_rows {Image height} * @parameter : messageDecodingStatus {object} */ +// @RequiresNonNull({"#1", "#4"}) private static void decodeMessage(byte[] byte_pixel_array, int image_columns, int image_rows, MessageDecodingStatus messageDecodingStatus) { @@ -231,7 +237,6 @@ private static void decodeMessage(byte[] byte_pixel_array, int image_columns, String stra = new String(temp, Charset.forName("ISO-8859-1")); - messageDecodingStatus.setMessage(stra.substring(0, stra.length() - 1)); //end fixing @@ -279,6 +284,7 @@ private static void decodeMessage(byte[] byte_pixel_array, int image_columns, * @parameter : encodedImages {list of encode chunk images} */ +// @RequiresNonNull("#1") public static String decodeMessage(List encodedImages) { //Creating object @@ -309,7 +315,7 @@ public static String decodeMessage(List encodedImages) { * @return : The number of pixel {integer} * @parameter : message {Message to encode} */ - public static int numberOfPixelForMessage(String message) { + public static int numberOfPixelForMessage(@Nullable String message) { int result = -1; if (message != null) { message += END_MESSAGE_COSTANT; @@ -323,8 +329,10 @@ public static int numberOfPixelForMessage(String message) { //Progress handler class public interface ProgressHandler { +// @RequiresNonNull("#1") void setTotal(int tot); + // @RequiresNonNull("#1") void increment(int inc); void finished(); @@ -352,6 +360,7 @@ String getMessage() { return message; } +// @RequiresNonNull("#1") void setMessage(String message) { this.message = message; } @@ -365,6 +374,7 @@ private static class MessageEncodingStatus { private byte[] byteArrayMessage; private String message; +// @RequiresNonNull({"#1", "#2"}) MessageEncodingStatus(byte[] byteArrayMessage, String message) { this.messageEncoded = false; this.currentMessageIndex = 0; @@ -380,6 +390,7 @@ public String getMessage() { return message; } +// @RequiresNonNull("#1") public void setMessage(String message) { this.message = message; } @@ -396,6 +407,7 @@ int getCurrentMessageIndex() { return currentMessageIndex; } +// @RequiresNonNull("#1") public void setCurrentMessageIndex(int currentMessageIndex) { this.currentMessageIndex = currentMessageIndex; } @@ -404,6 +416,7 @@ byte[] getByteArrayMessage() { return byteArrayMessage; } +// @RequiresNonNull("#1") public void setByteArrayMessage(byte[] byteArrayMessage) { this.byteArrayMessage = byteArrayMessage; } diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/ImageSteganography.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/ImageSteganography.java index e8bfdcf..f6e14c2 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/ImageSteganography.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/ImageSteganography.java @@ -6,6 +6,8 @@ import com.ayush.imagesteganographylibrary.Utils.Crypto; import com.ayush.imagesteganographylibrary.Utils.Utility; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + /** * This main class of the text steganography */ @@ -36,6 +38,7 @@ public ImageSteganography() { this.encrypted_zip = new byte[0]; } +// @RequiresNonNull({"#1", "#2", "#3"}) public ImageSteganography(String message, String secret_key, Bitmap image) { this.message = message; @@ -58,6 +61,7 @@ public ImageSteganography(String message, String secret_key, Bitmap image) { } +// @RequiresNonNull({"#1", "#2"}) public ImageSteganography(String secret_key, Bitmap image) { this.secret_key = convertKeyTo128bit(secret_key); this.image = image; @@ -110,6 +114,7 @@ public static String decryptMessage(String message, String secret_key) { return decrypted_message; } +// @RequiresNonNull("#1") private static String convertKeyTo128bit(String secret_key) { StringBuilder result = new StringBuilder(secret_key); @@ -131,6 +136,7 @@ public Bitmap getEncoded_image() { return encoded_image; } +// @RequiresNonNull("#1") public void setEncoded_image(Bitmap encoded_image) { this.encoded_image = encoded_image; } @@ -139,6 +145,7 @@ public String getMessage() { return message; } +// @RequiresNonNull("#1") public void setMessage(String message) { this.message = message; } @@ -147,6 +154,7 @@ public String getSecret_key() { return secret_key; } +// @RequiresNonNull("#1") public void setSecret_key(String secret_key) { this.secret_key = secret_key; } @@ -155,6 +163,7 @@ public byte[] getEncrypted_zip() { return encrypted_zip; } +// @RequiresNonNull("#1") public void setEncrypted_zip(byte[] encrypted_zip) { this.encrypted_zip = encrypted_zip; } @@ -163,6 +172,7 @@ public String getEncrypted_message() { return encrypted_message; } +// @RequiresNonNull("#1") public void setEncrypted_message(String encrypted_message) { this.encrypted_message = encrypted_message; } @@ -171,6 +181,7 @@ public Bitmap getImage() { return image; } +// @RequiresNonNull("#1") public void setImage(Bitmap image) { this.image = image; } diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/TextDecoding.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/TextDecoding.java index 9dc0be4..bc8ccf0 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/TextDecoding.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Text/TextDecoding.java @@ -9,6 +9,9 @@ import com.ayush.imagesteganographylibrary.Text.AsyncTaskCallback.TextDecodingCallback; import com.ayush.imagesteganographylibrary.Utils.Utility; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + import java.util.List; /** @@ -23,17 +26,21 @@ public class TextDecoding extends AsyncTask src_list = Utility.splitImage(bitmap); //encoding encrypted compressed message into image - List encoded_list = EncodeDecode.encodeMessage(src_list, textStegnography.getEncrypted_message(), new EncodeDecode.ProgressHandler() { //Progress Handler @Override public void setTotal(int tot) { maximumProgress = tot; - progressDialog.setMax(maximumProgress); + if (progressDialog != null) { + progressDialog.setMax(maximumProgress); + } Log.d(TAG, "Total Length : " + tot); } @@ -111,7 +118,9 @@ public void increment(int inc) { @Override public void finished() { Log.d(TAG, "Message Encoding end...."); - progressDialog.setIndeterminate(true); + if (progressDialog != null) { + progressDialog.setIndeterminate(true); + } } }); diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Crypto.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Crypto.java index ff9fe0c..94eaf7c 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Crypto.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Crypto.java @@ -2,6 +2,8 @@ import android.util.Log; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + import java.util.Arrays; import javax.crypto.Cipher; @@ -14,6 +16,7 @@ public class Crypto { @parameter : Message {String}, Secret key {String} @return : Encrypted Message {String} */ +// @RequiresNonNull({"#1", "#2"}) public static String encryptMessage(String message, String secret_key) throws Exception { // Creating key and cipher @@ -42,6 +45,7 @@ public static String encryptMessage(String message, String secret_key) throws Ex @parameter : Encrypted Message {String}, Secret key {String} @return : Message {String} */ +// @RequiresNonNull({"#1", "#2"}) public static String decryptMessage(String encrypted_message, String secret_key) throws Exception { Log.d("Decrypt", "message: + " + encrypted_message); diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Utility.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Utility.java index d0016c5..3c1dabc 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Utility.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Utility.java @@ -5,6 +5,9 @@ import android.graphics.Paint; import android.util.Log; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + import java.util.ArrayList; import java.util.List; @@ -41,6 +44,7 @@ public static int squareBlockNeeded(int pixels) { * @return : List of splitted images {List} * @parameter : Image {Bitmap} */ +// @RequiresNonNull("#1") public static List splitImage(Bitmap bitmap) { //For height and width of the small image chunks @@ -101,6 +105,7 @@ public static List splitImage(Bitmap bitmap) { * @return : Merged Image {Bitmap} * @parameter : List {Bitmap}, Original Height {Integer}, Original Width {Integer} */ +// @RequiresNonNull({"#1"}) public static Bitmap mergeImage(List images, int original_height, int original_width) { //Calculating number of Rows and columns of that matrix @@ -145,6 +150,7 @@ public static Bitmap mergeImage(List images, int original_height, int or * @parameter : b {the byte array} */ +// @RequiresNonNull("#1") public static int[] byteArrayToIntArray(byte[] b) { Log.v("Size byte array", b.length + ""); @@ -176,6 +182,7 @@ public static int[] byteArrayToIntArray(byte[] b) { * @return : Integer * @parameter : b {the byte array} */ +// @RequiresNonNull("#1") public static int byteArrayToInt(byte[] b) { return byteArrayToInt(b, 0); @@ -188,6 +195,7 @@ public static int byteArrayToInt(byte[] b) { * @return : Integer * @parameter : b {the byte array}, offset {integer} */ +// @RequiresNonNull({"#1"}) private static int byteArrayToInt(byte[] b, int offset) { int value = 0x00000000; @@ -209,6 +217,7 @@ private static int byteArrayToInt(byte[] b, int offset) { * @return : byte Array representing [rgb] values. * @parameter : Integer array representing [argb] values. */ +// @RequiresNonNull("#1") public static byte[] convertArray(int[] array) { byte[] newarray = new byte[array.length * 3]; @@ -230,7 +239,7 @@ public static byte[] convertArray(int[] array) { * @return : true or false {boolean} * @parameter : String */ - public static boolean isStringEmpty(String str) { + public static boolean isStringEmpty(@Nullable String str) { boolean result = true; if (str == null) ; diff --git a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Zipping.java b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Zipping.java index fde500e..ac4e1db 100644 --- a/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Zipping.java +++ b/ImageSteganographyLibrary/src/main/java/com/ayush/imagesteganographylibrary/Utils/Zipping.java @@ -1,5 +1,7 @@ package com.ayush.imagesteganographylibrary.Utils; +import org.checkerframework.checker.nullness.qual.RequiresNonNull; + import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -21,6 +23,7 @@ class Zipping { @return : Compressed byte array */ +// @RequiresNonNull("#1") public static byte[] compress(String string) throws Exception { ByteArrayOutputStream os = new ByteArrayOutputStream(string.length()); @@ -41,6 +44,7 @@ public static byte[] compress(String string) throws Exception { @parameter : byte array @return : Uncompressed encrypted_message {String} */ +// @RequiresNonNull("#1") public static String decompress(byte[] compressed) throws Exception { ByteArrayInputStream bis = new ByteArrayInputStream(compressed); diff --git a/app/build.gradle b/app/build.gradle index 7bd537b..86d0090 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,6 +18,10 @@ android { } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } configurations.all { diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2c134a1..3d238fc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon May 07 21:22:54 IST 2018 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +#Mon Mar 18 01:09:02 IST 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip