diff --git a/.gitignore b/.gitignore
index 63e899b..09b993d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,30 +1,8 @@
-# Built application files
-*.apk
-*.ap_
-
-# Files for the Dalvik VM
-*.dex
-
-# Java class files
-*.class
-
-# Generated files
-bin/
-gen/
-
-# Gradle files
-.gradle/
-build/
-/*/build/
-
-# Local configuration file (sdk path, etc)
-local.properties
-
-# Log Files
-*.log
-
-.gradle
-.idea
-.DS_Store
-/captures
*.iml
+.gradle
+/local.properties
+/.idea
+.DS_Store
+/build
+/captures
+.externalNativeBuild
diff --git a/build.gradle b/build.gradle
index 0a7ccae..7accccb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,28 +1,36 @@
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
-
-android {
- compileSdkVersion compileSdk
-
- compileOptions {
- sourceCompatibility JavaVersion.VERSION_1_8
- targetCompatibility JavaVersion.VERSION_1_8
+buildscript {
+ ext.kotlin_version = '1.2.60'
+ repositories {
+ google()
+ jcenter()
}
-
- defaultConfig {
- minSdkVersion 16
+ dependencies {
+ classpath 'com.android.tools.build:gradle:3.1.3'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
-dependencies {
- api project(':libraries:core')
-
- compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
-
- compileOnly "com.android.support:appcompat-v7:$supportLibraryVersion"
- compileOnly "com.android.support:design:$supportLibraryVersion"
- compileOnly "com.android.support:recyclerview-v7:$supportLibraryVersion"
-
- compileOnly "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
- compileOnly "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
+
+ext {
+ versions = [
+ compileSdk : 27,
+ minSdk : 19,
+ supportLibrary: '27.1.1',
+ navigation : '1.0.0-alpha04',
+ lifecycle : '1.1.1',
+ dagger : '2.16',
+ retrofit : '2.4.0',
+ rxJava : '2.1.17',
+ rxAndroid : '2.0.2'
+ ]
}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..e30af81
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,13 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..7a3265e
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..190eeaa
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Aug 05 23:37:20 MSK 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/logging/.gitignore b/logging/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/logging/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/logging/build.gradle b/logging/build.gradle
new file mode 100644
index 0000000..217c17b
--- /dev/null
+++ b/logging/build.gradle
@@ -0,0 +1,18 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion versions.compileSdk
+
+ defaultConfig {
+ minSdkVersion 16
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation "com.android.support:support-annotations:$versions.supportLibrary"
+}
diff --git a/logging/src/main/AndroidManifest.xml b/logging/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8ce26b3
--- /dev/null
+++ b/logging/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/logging/src/main/java/ru/touchin/roboswag/core/log/ConsoleLogProcessor.java b/logging/src/main/java/ru/touchin/roboswag/core/log/ConsoleLogProcessor.java
new file mode 100644
index 0000000..0c05b84
--- /dev/null
+++ b/logging/src/main/java/ru/touchin/roboswag/core/log/ConsoleLogProcessor.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.roboswag.core.log;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+/**
+ * Created by Gavriil Sitnikov on 13/11/2015.
+ * Simple {@link LogProcessor} implementation which is logging messages to console (logcat).
+ */
+public class ConsoleLogProcessor extends LogProcessor {
+
+ private static final int MAX_LOG_LENGTH = 4000;
+
+ public ConsoleLogProcessor(@NonNull final LcLevel lclevel) {
+ super(lclevel);
+ }
+
+ @NonNull
+ private String normalize(@NonNull final String message) {
+ return message.replace("\r\n", "\n").replace("\0", "");
+ }
+
+ @Override
+ @SuppressWarnings({"WrongConstant", "LogConditional"})
+ //WrongConstant, LogConditional: level.getPriority() is not wrong constant!
+ public void processLogMessage(@NonNull final LcGroup group, @NonNull final LcLevel level,
+ @NonNull final String tag, @NonNull final String message, @Nullable final Throwable throwable) {
+ final String messageToLog = normalize(message + (throwable != null ? '\n' + Log.getStackTraceString(throwable) : ""));
+ final int length = messageToLog.length();
+ for (int i = 0; i < length; i++) {
+ int newline = messageToLog.indexOf('\n', i);
+ newline = newline != -1 ? newline : length;
+ do {
+ final int end = Math.min(newline, i + MAX_LOG_LENGTH);
+ Log.println(level.getPriority(), tag, messageToLog.substring(i, end));
+ i = end;
+ }
+ while (i < newline);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/logging/src/main/java/ru/touchin/roboswag/core/log/Lc.java b/logging/src/main/java/ru/touchin/roboswag/core/log/Lc.java
new file mode 100644
index 0000000..3d46668
--- /dev/null
+++ b/logging/src/main/java/ru/touchin/roboswag/core/log/Lc.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.roboswag.core.log;
+
+import android.annotation.SuppressLint;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import ru.touchin.roboswag.core.utils.ShouldNotHappenException;
+
+/**
+ * Created by Gavriil Sitnikov on 13/11/2015.
+ * General logging utility of RoboSwag library.
+ * You can initialize {@link LogProcessor} to intercept log messages and make decision how to show them.
+ * Also you can specify assertions behavior to manually make application more stable in production but intercept illegal states in some
+ * third-party tool to fix them later but not crash in production.
+ */
+@SuppressWarnings({"checkstyle:methodname", "PMD.ShortMethodName", "PMD.ShortClassName"})
+//MethodNameCheck,ShortMethodName: log methods better be 1-symbol
+public final class Lc {
+
+ public static final LcGroup GENERAL_LC_GROUP = new LcGroup("GENERAL");
+
+ public static final int STACK_TRACE_CODE_DEPTH;
+
+ private static boolean crashOnAssertions = true;
+ @NonNull
+ private static LogProcessor logProcessor = new ConsoleLogProcessor(LcLevel.ERROR);
+
+ static {
+ final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+ int stackDepth;
+ for (stackDepth = 0; stackDepth < stackTrace.length; stackDepth++) {
+ if (stackTrace[stackDepth].getClassName().equals(Lc.class.getName())) {
+ break;
+ }
+ }
+ STACK_TRACE_CODE_DEPTH = stackDepth + 1;
+ }
+
+ /**
+ * Flag to crash application or pass it to {@link LogProcessor#processLogMessage(LcGroup, LcLevel, String, String, Throwable)}
+ * on specific {@link LcGroup#assertion(Throwable)} points of code.
+ *
+ * @return True if application should crash on assertion.
+ */
+ public static boolean isCrashOnAssertions() {
+ return crashOnAssertions;
+ }
+
+ /**
+ * Returns {@link LogProcessor} object to intercept incoming log messages (by default it returns {@link ConsoleLogProcessor}).
+ *
+ * @return Specific {@link LogProcessor}.
+ */
+ @NonNull
+ public static LogProcessor getLogProcessor() {
+ return logProcessor;
+ }
+
+ /**
+ * Initialize general logging behavior.
+ *
+ * @param logProcessor {@link LogProcessor} to intercept all log messages;
+ * @param crashOnAssertions Flag to crash application
+ * or pass it to {@link LogProcessor#processLogMessage(LcGroup, LcLevel, String, String, Throwable)}
+ * on specific {@link LcGroup#assertion(Throwable)} points of code.
+ */
+ public static void initialize(@NonNull final LogProcessor logProcessor, final boolean crashOnAssertions) {
+ Lc.crashOnAssertions = crashOnAssertions;
+ Lc.logProcessor = logProcessor;
+ }
+
+ /**
+ * Logs debug message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void d(@NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.d(message, args);
+ }
+
+ /**
+ * Logs debug message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void d(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.d(throwable, message, args);
+ }
+
+ /**
+ * Logs info message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void i(@NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.i(message, args);
+ }
+
+ /**
+ * Logs info message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void i(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.i(throwable, message, args);
+ }
+
+ /**
+ * Logs warning message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void w(@NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.w(message, args);
+ }
+
+ /**
+ * Logs warning message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void w(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.w(throwable, message, args);
+ }
+
+ /**
+ * Logs error message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void e(@NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.e(message, args);
+ }
+
+ /**
+ * Logs error message via {@link #GENERAL_LC_GROUP}.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public static void e(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ GENERAL_LC_GROUP.e(throwable, message, args);
+ }
+
+ /**
+ * Processes assertion. Normally it will throw {@link ShouldNotHappenException} and crash app.
+ * If it should crash or not is specified at {@link Lc#isCrashOnAssertions()}.
+ * In some cases crash on assertions should be switched off and assertion should be processed in {@link LogProcessor}.
+ * It is useful for example to not crash but log it as handled crash in Crashlitycs in production build.
+ *
+ * @param message Message that is describing assertion.
+ */
+ public static void assertion(@NonNull final String message) {
+ GENERAL_LC_GROUP.assertion(message);
+ }
+
+ /**
+ * Processes assertion. Normally it will throw {@link ShouldNotHappenException} and crash app.
+ * If it should crash or not is specified at {@link Lc#isCrashOnAssertions()}.
+ * In some cases crash on assertions should be switched off and assertion should be processed in {@link LogProcessor}.
+ * It is useful for example to not crash but log it as handled crash in Crashlitycs in production build.
+ *
+ * @param throwable Exception that is describing assertion.
+ */
+ public static void assertion(@NonNull final Throwable throwable) {
+ GENERAL_LC_GROUP.assertion(throwable);
+ }
+
+ /**
+ * Throws assertion on main thread (to avoid Rx exceptions e.g.) and cuts top causes by type of exception class.
+ *
+ * @param assertion Source throwable;
+ * @param exceptionsClassesToCut Classes which will be cut from top of causes stack of source throwable.
+ */
+ @SafeVarargs
+ public static void cutAssertion(@NonNull final Throwable assertion, @NonNull final Class extends Throwable>... exceptionsClassesToCut) {
+ new Handler(Looper.getMainLooper()).post(() -> {
+ final List processedExceptions = new ArrayList<>();
+ Throwable result = assertion;
+ boolean exceptionAssignableFromIgnores;
+ do {
+ exceptionAssignableFromIgnores = false;
+ processedExceptions.add(result);
+ for (final Class exceptionClass : exceptionsClassesToCut) {
+ if (result.getClass().isAssignableFrom(exceptionClass)) {
+ exceptionAssignableFromIgnores = true;
+ result = result.getCause();
+ break;
+ }
+ }
+ }
+ while (exceptionAssignableFromIgnores && result != null && !processedExceptions.contains(result));
+ Lc.assertion(result != null ? result : assertion);
+ });
+ }
+
+ /**
+ * Returns line of code from where this method called.
+ *
+ * @param caller Object who is calling for code point;
+ * @return String represents code point.
+ */
+ @NonNull
+ public static String getCodePoint(@Nullable final Object caller) {
+ return getCodePoint(caller, 1);
+ }
+
+ /**
+ * Returns line of code from where this method called.
+ *
+ * @param caller Object who is calling for code point;
+ * @param stackShift caller Shift of stack (e.g. 2 means two elements deeper);
+ * @return String represents code point.
+ */
+ @NonNull
+ public static String getCodePoint(@Nullable final Object caller, final int stackShift) {
+ final StackTraceElement traceElement = Thread.currentThread().getStackTrace()[STACK_TRACE_CODE_DEPTH + stackShift];
+ return traceElement.getMethodName() + '(' + traceElement.getFileName() + ':' + traceElement.getLineNumber() + ')'
+ + (caller != null ? " of object " + caller.getClass().getSimpleName() + '(' + Integer.toHexString(caller.hashCode()) + ')' : "");
+ }
+
+ /**
+ * Prints stacktrace in log with specified tag.
+ *
+ * @param tag Tag to be shown in logs.
+ */
+
+ @SuppressLint("LogConditional")
+ public static void printStackTrace(@NonNull final String tag) {
+ final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
+ if (Log.isLoggable(tag, Log.DEBUG)) {
+ Log.d(tag, TextUtils.join("\n", Arrays.copyOfRange(stackTrace, STACK_TRACE_CODE_DEPTH, stackTrace.length)));
+ }
+ }
+
+ private Lc() {
+ }
+
+}
diff --git a/logging/src/main/java/ru/touchin/roboswag/core/log/LcGroup.java b/logging/src/main/java/ru/touchin/roboswag/core/log/LcGroup.java
new file mode 100644
index 0000000..3ccf1fa
--- /dev/null
+++ b/logging/src/main/java/ru/touchin/roboswag/core/log/LcGroup.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.roboswag.core.log;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import ru.touchin.roboswag.core.utils.ShouldNotHappenException;
+import ru.touchin.roboswag.core.utils.ThreadLocalValue;
+
+/**
+ * Created by Gavriil Sitnikov on 14/05/2016.
+ * Group of log messages with specific tag prefix (name of group).
+ * It could be used in specific {@link LogProcessor} to filter messages by group.
+ */
+@SuppressWarnings({"checkstyle:methodname", "PMD.ShortMethodName"})
+//MethodNameCheck,ShortMethodName: log methods better be 1-symbol
+public class LcGroup {
+
+ /**
+ * Logging group to log UI metrics (like inflation or layout time etc.).
+ */
+ public static final LcGroup UI_METRICS = new LcGroup("UI_METRICS");
+ /**
+ * Logging group to log UI lifecycle (onCreate, onStart, onResume etc.).
+ */
+ public static final LcGroup UI_LIFECYCLE = new LcGroup("UI_LIFECYCLE");
+
+ private static final ThreadLocalValue DATE_TIME_FORMATTER
+ = new ThreadLocalValue<>(() -> new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()));
+
+ @NonNull
+ private final String name;
+ private boolean disabled;
+
+ public LcGroup(@NonNull final String name) {
+ this.name = name;
+ }
+
+ /**
+ * Disables logging of this group.
+ */
+ public void disable() {
+ disabled = true;
+ }
+
+ /**
+ * Enables logging of this group.
+ */
+ public void enable() {
+ disabled = false;
+ }
+
+ @NonNull
+ private String createLogTag() {
+ final StackTraceElement trace = Thread.currentThread().getStackTrace()[Lc.STACK_TRACE_CODE_DEPTH + 3];
+ return trace.getFileName() + ':' + trace.getLineNumber();
+ }
+
+ @SuppressWarnings("PMD.AvoidCatchingThrowable")
+ //AvoidCatchingThrowable: it is needed to safety format message
+ @Nullable
+ private String createFormattedMessage(@Nullable final String message, @NonNull final Object... args) {
+ try {
+ if (args.length > 0 && message == null) {
+ throw new ShouldNotHappenException("Args are not empty but format message is null");
+ }
+ return message != null ? (args.length > 0 ? String.format(message, args) : message) : null;
+ } catch (final Throwable formattingException) {
+ Lc.assertion(formattingException);
+ return null;
+ }
+ }
+
+ @NonNull
+ private String createLogMessage(@Nullable final String formattedMessage) {
+ return DATE_TIME_FORMATTER.get().format(System.currentTimeMillis())
+ + ' ' + Thread.currentThread().getName()
+ + ' ' + name
+ + (formattedMessage != null ? (' ' + formattedMessage) : "");
+ }
+
+ private void logMessage(@NonNull final LcLevel logLevel, @Nullable final String message,
+ @Nullable final Throwable throwable, @NonNull final Object... args) {
+ if (disabled || logLevel.lessThan(Lc.getLogProcessor().getMinLogLevel())) {
+ return;
+ }
+
+ if (throwable == null && args.length > 0 && args[0] instanceof Throwable) {
+ Lc.w("Maybe you've misplaced exception with first format arg? format: %s; arg: %s", message, args[0]);
+ }
+
+ final String formattedMessage = createFormattedMessage(message, args);
+ if (logLevel == LcLevel.ASSERT && Lc.isCrashOnAssertions()) {
+ throw createAssertion(formattedMessage, throwable);
+ }
+
+ Lc.getLogProcessor().processLogMessage(this, logLevel, createLogTag(), createLogMessage(formattedMessage), throwable);
+ }
+
+ @NonNull
+ private ShouldNotHappenException createAssertion(@Nullable final String message, @Nullable final Throwable exception) {
+ return exception != null
+ ? (message != null ? new ShouldNotHappenException(message, exception)
+ : (exception instanceof ShouldNotHappenException ? (ShouldNotHappenException) exception : new ShouldNotHappenException(exception)))
+ : (message != null ? new ShouldNotHappenException(message) : new ShouldNotHappenException());
+ }
+
+ /**
+ * Logs debug message.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void d(@NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.DEBUG, message, null, args);
+ }
+
+ /**
+ * Logs debug message.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void d(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.DEBUG, message, throwable, args);
+ }
+
+ /**
+ * Logs info message.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void i(@NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.INFO, message, null, args);
+ }
+
+ /**
+ * Logs info message.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void i(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.INFO, message, throwable, args);
+ }
+
+ /**
+ * Logs warning message.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void w(@NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.WARN, message, null, args);
+ }
+
+ /**
+ * Logs warning message.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void w(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.WARN, message, throwable, args);
+ }
+
+ /**
+ * Logs error message.
+ *
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void e(@NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.ERROR, message, null, args);
+ }
+
+ /**
+ * Logs error message.
+ *
+ * @param throwable Exception to log;
+ * @param message Message or format of message to log;
+ * @param args Arguments of formatted message.
+ */
+ public void e(@NonNull final Throwable throwable, @NonNull final String message, @NonNull final Object... args) {
+ logMessage(LcLevel.ERROR, message, throwable, args);
+ }
+
+ /**
+ * Processes assertion. Normally it will throw {@link ShouldNotHappenException} and crash app.
+ * If it should crash or not is specified at {@link Lc#isCrashOnAssertions()}.
+ * In some cases crash on assertions should be switched off and assertion should be processed in {@link LogProcessor}.
+ * It is useful for example to not crash but log it as handled crash in Crashlitycs in production build.
+ *
+ * @param message Message that is describing assertion.
+ */
+ public void assertion(@NonNull final String message) {
+ logMessage(LcLevel.ASSERT, "Assertion appears at %s with message: %s", null, Lc.getCodePoint(null, 2), message);
+ }
+
+ /**
+ * Processes assertion. Normally it will throw {@link ShouldNotHappenException} and crash app.
+ * If it should crash or not is specified at {@link Lc#isCrashOnAssertions()}.
+ * In some cases crash on assertions should be switched off and assertion should be processed in {@link LogProcessor}.
+ * It is useful for example to not crash but log it as handled crash in Crashlitycs in production build.
+ *
+ * @param throwable Exception that is describing assertion.
+ */
+ public void assertion(@NonNull final Throwable throwable) {
+ logMessage(LcLevel.ASSERT, "Assertion appears at %s", throwable, Lc.getCodePoint(null, 2));
+ }
+
+}
diff --git a/logging/src/main/java/ru/touchin/roboswag/core/log/LcLevel.java b/logging/src/main/java/ru/touchin/roboswag/core/log/LcLevel.java
new file mode 100644
index 0000000..9dbd5e5
--- /dev/null
+++ b/logging/src/main/java/ru/touchin/roboswag/core/log/LcLevel.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.roboswag.core.log;
+
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+/**
+ * Created by Gavriil Sitnikov on 14/05/2016.
+ * Level of log message.
+ */
+public enum LcLevel {
+
+ VERBOSE(Log.VERBOSE),
+ DEBUG(Log.DEBUG),
+ INFO(Log.INFO),
+ WARN(Log.WARN),
+ ERROR(Log.ERROR),
+ ASSERT(Log.ASSERT);
+
+ private final int priority;
+
+ LcLevel(final int priority) {
+ this.priority = priority;
+ }
+
+ /**
+ * Standard {@link Log} integer value of level represents priority of message.
+ *
+ * @return Integer level.
+ */
+ public int getPriority() {
+ return priority;
+ }
+
+ /**
+ * Compares priorities of LcLevels and returns if current is less than another.
+ *
+ * @param logLevel {@link LcLevel} to compare priority with;
+ * @return True if current level priority less than level passed as parameter.
+ */
+ public boolean lessThan(@NonNull final LcLevel logLevel) {
+ return this.priority < logLevel.priority;
+ }
+
+}
diff --git a/logging/src/main/java/ru/touchin/roboswag/core/log/LogProcessor.java b/logging/src/main/java/ru/touchin/roboswag/core/log/LogProcessor.java
new file mode 100644
index 0000000..6cb34a9
--- /dev/null
+++ b/logging/src/main/java/ru/touchin/roboswag/core/log/LogProcessor.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.roboswag.core.log;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+/**
+ * Created by Gavriil Sitnikov on 13/11/2015.
+ * Abstract object to intercept log messages coming from {@link LcGroup} and {@link Lc} log methods.
+ */
+public abstract class LogProcessor {
+
+ @NonNull
+ private final LcLevel minLogLevel;
+
+ public LogProcessor(@NonNull final LcLevel minLogLevel) {
+ this.minLogLevel = minLogLevel;
+ }
+
+ /**
+ * Minimum logging level.
+ * Any messages with lower priority won't be passed into {@link #processLogMessage(LcGroup, LcLevel, String, String, Throwable)}.
+ *
+ * @return Minimum log level represented by {@link LcLevel} object.
+ */
+ @NonNull
+ public LcLevel getMinLogLevel() {
+ return minLogLevel;
+ }
+
+ /**
+ * Core method to process any incoming log messages from {@link LcGroup} and {@link Lc} with level higher or equals {@link #getMinLogLevel()}.
+ *
+ * @param group {@link LcGroup} where log message came from;
+ * @param level {@link LcLevel} level (priority) of message;
+ * @param tag String mark of message;
+ * @param message Message to log;
+ * @param throwable Exception to log.
+ */
+ public abstract void processLogMessage(@NonNull final LcGroup group, @NonNull final LcLevel level,
+ @NonNull final String tag, @NonNull final String message, @Nullable final Throwable throwable);
+
+}
diff --git a/logging/src/main/java/ru/touchin/roboswag/core/utils/ShouldNotHappenException.java b/logging/src/main/java/ru/touchin/roboswag/core/utils/ShouldNotHappenException.java
new file mode 100644
index 0000000..b3f11f0
--- /dev/null
+++ b/logging/src/main/java/ru/touchin/roboswag/core/utils/ShouldNotHappenException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.roboswag.core.utils;
+
+import android.support.annotation.NonNull;
+
+/**
+ * Created by Gavriil Sitnikov on 13/11/2015.
+ * Exception that should be threw when some unexpected code reached.
+ * E.g. if some value null but it is not legal or in default case in switch if all specific cases should be processed.
+ */
+public class ShouldNotHappenException extends RuntimeException {
+
+ private static final long serialVersionUID = 0;
+
+ public ShouldNotHappenException() {
+ super();
+ }
+
+ public ShouldNotHappenException(@NonNull final String detailMessage) {
+ super(detailMessage);
+ }
+
+ public ShouldNotHappenException(@NonNull final String detailMessage, @NonNull final Throwable throwable) {
+ super(detailMessage, throwable);
+ }
+
+ public ShouldNotHappenException(@NonNull final Throwable throwable) {
+ super(throwable);
+ }
+
+}
diff --git a/logging/src/main/java/ru/touchin/roboswag/core/utils/ThreadLocalValue.java b/logging/src/main/java/ru/touchin/roboswag/core/utils/ThreadLocalValue.java
new file mode 100644
index 0000000..62cf778
--- /dev/null
+++ b/logging/src/main/java/ru/touchin/roboswag/core/utils/ThreadLocalValue.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.roboswag.core.utils;
+
+import android.support.annotation.NonNull;
+
+/**
+ * Created by Gavriil Sitnikov on 13/11/2015.
+ * Thread local value with specified creator of value per thread.
+ */
+public class ThreadLocalValue extends ThreadLocal {
+
+ @NonNull
+ private final Fabric fabric;
+
+ public ThreadLocalValue(@NonNull final Fabric fabric) {
+ super();
+ this.fabric = fabric;
+ }
+
+ @NonNull
+ @Override
+ protected T initialValue() {
+ return fabric.create();
+ }
+
+ /**
+ * Fabric of thread-local objects.
+ *
+ * @param Type of objects.
+ */
+ public interface Fabric {
+
+ /**
+ * Creates object.
+ *
+ * @return new instance of object.
+ */
+ @NonNull
+ T create();
+
+ }
+
+}
diff --git a/navigation/.gitignore b/navigation/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/navigation/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/navigation/build.gradle b/navigation/build.gradle
new file mode 100644
index 0000000..26d4258
--- /dev/null
+++ b/navigation/build.gradle
@@ -0,0 +1,23 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion versions.compileSdk
+
+ defaultConfig {
+ minSdkVersion 16
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ api project(":utils")
+ api project(":logging")
+
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+
+ implementation "com.android.support:appcompat-v7:$versions.supportLibrary"
+}
diff --git a/navigation/src/main/AndroidManifest.xml b/navigation/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..bd2d3ee
--- /dev/null
+++ b/navigation/src/main/AndroidManifest.xml
@@ -0,0 +1,3 @@
+
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.kt b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.kt
similarity index 100%
rename from src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.kt
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.kt
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/OnFragmentStartedListener.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/OnFragmentStartedListener.java
similarity index 99%
rename from src/main/java/ru/touchin/roboswag/components/navigation/OnFragmentStartedListener.java
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/OnFragmentStartedListener.java
index 2dfb580..8d68057 100644
--- a/src/main/java/ru/touchin/roboswag/components/navigation/OnFragmentStartedListener.java
+++ b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/OnFragmentStartedListener.java
@@ -36,4 +36,4 @@ public interface OnFragmentStartedListener {
*/
void onFragmentStarted(@NonNull Fragment fragment);
-}
\ No newline at end of file
+}
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/SerializableBundle.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/SerializableBundle.java
similarity index 100%
rename from src/main/java/ru/touchin/roboswag/components/navigation/SerializableBundle.java
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/SerializableBundle.java
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/SimpleActionBarDrawerToggle.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/SimpleActionBarDrawerToggle.java
similarity index 100%
rename from src/main/java/ru/touchin/roboswag/components/navigation/SimpleActionBarDrawerToggle.java
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/SimpleActionBarDrawerToggle.java
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/activities/BaseActivity.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/activities/BaseActivity.java
similarity index 83%
rename from src/main/java/ru/touchin/roboswag/components/navigation/activities/BaseActivity.java
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/activities/BaseActivity.java
index 7a3f0b7..ee39486 100644
--- a/src/main/java/ru/touchin/roboswag/components/navigation/activities/BaseActivity.java
+++ b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/activities/BaseActivity.java
@@ -29,8 +29,8 @@ import android.view.MenuItem;
import java.util.Set;
-import ru.touchin.roboswag.components.utils.UiUtils;
import ru.touchin.roboswag.core.log.Lc;
+import ru.touchin.roboswag.core.log.LcGroup;
/**
* Created by Gavriil Sitnikov on 08/03/2016.
@@ -44,54 +44,54 @@ public abstract class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, @Nullable final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this) + " requestCode: " + requestCode + "; resultCode: " + resultCode);
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this) + " requestCode: " + requestCode + "; resultCode: " + resultCode);
}
@Override
protected void onStart() {
super.onStart();
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
}
@Override
protected void onResume() {
super.onResume();
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
}
@Override
protected void onPause() {
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
super.onPause();
}
@Override
protected void onSaveInstanceState(@NonNull final Bundle stateToSave) {
super.onSaveInstanceState(stateToSave);
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
}
@Override
public void onLowMemory() {
super.onLowMemory();
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
}
@Override
protected void onStop() {
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
super.onStop();
}
@Override
protected void onDestroy() {
- UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
+ LcGroup.UI_LIFECYCLE.i(Lc.getCodePoint(this));
super.onDestroy();
}
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewControllerFragment.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewControllerFragment.java
similarity index 95%
rename from src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewControllerFragment.java
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewControllerFragment.java
index 74f290d..065f06b 100644
--- a/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewControllerFragment.java
+++ b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewControllerFragment.java
@@ -30,7 +30,6 @@ import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
-import android.support.v4.view.ViewCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -42,10 +41,9 @@ import android.widget.FrameLayout;
import java.lang.reflect.Constructor;
-import ru.touchin.roboswag.components.R;
import ru.touchin.roboswag.components.navigation.viewcontrollers.ViewController;
-import ru.touchin.roboswag.components.utils.UiUtils;
import ru.touchin.roboswag.core.log.Lc;
+import ru.touchin.roboswag.core.log.LcGroup;
import ru.touchin.roboswag.core.utils.ShouldNotHappenException;
/**
@@ -182,7 +180,7 @@ public class ViewControllerFragment acceptableUiCalculationTime) {
- UiUtils.UI_METRICS_LC_GROUP.w("Creation of %s took too much: %dms", viewControllerClass, creationPeriod);
+ LcGroup.UI_METRICS.w("Creation of %s took too much: %dms", viewControllerClass, creationPeriod);
}
}
}
@@ -212,11 +210,6 @@ public class ViewControllerFragment 0) {
final long layoutTime = SystemClock.uptimeMillis() - lastMeasureTime;
if (layoutTime > acceptableUiCalculationTime) {
- UiUtils.UI_METRICS_LC_GROUP.w("Measure and layout of %s took too much: %dms", tagName, layoutTime);
+ LcGroup.UI_METRICS.w("Measure and layout of %s took too much: %dms", tagName, layoutTime);
}
lastMeasureTime = 0;
}
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewFragment.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewFragment.java
similarity index 99%
rename from src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewFragment.java
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewFragment.java
index 5cd873f..bca1f28 100644
--- a/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewFragment.java
+++ b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/fragments/ViewFragment.java
@@ -30,9 +30,9 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import io.reactivex.functions.BiConsumer;
import ru.touchin.roboswag.components.navigation.OnFragmentStartedListener;
import ru.touchin.roboswag.core.log.Lc;
+import ru.touchin.roboswag.core.utils.BiConsumer;
/**
* Created by Gavriil Sitnikov on 21/10/2015.
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/DefaultViewController.kt b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/DefaultViewController.kt
similarity index 100%
rename from src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/DefaultViewController.kt
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/DefaultViewController.kt
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/EmptyState.kt b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/EmptyState.kt
similarity index 100%
rename from src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/EmptyState.kt
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/EmptyState.kt
diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/ViewController.java b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/ViewController.java
similarity index 93%
rename from src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/ViewController.java
rename to navigation/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/ViewController.java
index 363e628..8e4c7d0 100644
--- a/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/ViewController.java
+++ b/navigation/src/main/java/ru/touchin/roboswag/components/navigation/viewcontrollers/ViewController.java
@@ -46,18 +46,19 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-
import android.view.animation.Animation;
+
import ru.touchin.roboswag.components.navigation.fragments.ViewControllerFragment;
import ru.touchin.roboswag.components.utils.UiUtils;
import ru.touchin.roboswag.core.log.Lc;
+import ru.touchin.roboswag.core.log.LcGroup;
/**
* Created by Gavriil Sitnikov on 21/10/2015.
* Class to control view of specific fragment, activity and application by logic bridge.
*
* @param Type of activity where such {@link ViewController} could be;
- * @param Type of state;
+ * @param Type of state;
*/
public class ViewController implements LifecycleOwner {
@@ -221,7 +222,7 @@ public class ViewController
*
Starting in {@link android.os.Build.VERSION_CODES#M}, the returned
* color state list will be styled for the specified Context's theme.
*
@@ -275,7 +276,7 @@ public class ViewController
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/java/ru/touchin/roboswag/components/MainActivity.kt b/sample/src/main/java/ru/touchin/roboswag/components/MainActivity.kt
new file mode 100644
index 0000000..ebf42b3
--- /dev/null
+++ b/sample/src/main/java/ru/touchin/roboswag/components/MainActivity.kt
@@ -0,0 +1,12 @@
+package ru.touchin.roboswag.components
+
+import android.support.v7.app.AppCompatActivity
+import android.os.Bundle
+
+class MainActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_main)
+ }
+}
diff --git a/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml b/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..3e810c0
--- /dev/null
+++ b/sample/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/src/main/res/drawable/ic_launcher_background.xml b/sample/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..5713f34
--- /dev/null
+++ b/sample/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/src/main/res/layout/activity_main.xml b/sample/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..7539a01
--- /dev/null
+++ b/sample/src/main/res/layout/activity_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..f4bc9d9
--- /dev/null
+++ b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..f4bc9d9
--- /dev/null
+++ b/sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher.png b/sample/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a2f5908
Binary files /dev/null and b/sample/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..1b52399
Binary files /dev/null and b/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher.png b/sample/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..ff10afd
Binary files /dev/null and b/sample/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..115a4c7
Binary files /dev/null and b/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..dcd3cd8
Binary files /dev/null and b/sample/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..459ca60
Binary files /dev/null and b/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..8ca12fe
Binary files /dev/null and b/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..8e19b41
Binary files /dev/null and b/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..b824ebd
Binary files /dev/null and b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..4c19a13
Binary files /dev/null and b/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/sample/src/main/res/values/colors.xml b/sample/src/main/res/values/colors.xml
new file mode 100644
index 0000000..3ab3e9c
--- /dev/null
+++ b/sample/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/sample/src/main/res/values/strings.xml b/sample/src/main/res/values/strings.xml
new file mode 100644
index 0000000..f6470ae
--- /dev/null
+++ b/sample/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Components
+
diff --git a/sample/src/main/res/values/styles.xml b/sample/src/main/res/values/styles.xml
new file mode 100644
index 0000000..5885930
--- /dev/null
+++ b/sample/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..9e1f446
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':sample', ':utils', ':logging', ':navigation', ':storable'
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
deleted file mode 100644
index c76023c..0000000
--- a/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/src/main/java/ru/touchin/roboswag/components/adapters/AdapterDelegate.java b/src/main/java/ru/touchin/roboswag/components/adapters/AdapterDelegate.java
deleted file mode 100644
index 25be0c9..0000000
--- a/src/main/java/ru/touchin/roboswag/components/adapters/AdapterDelegate.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2017 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
- *
- * This file is part of RoboSwag library.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package ru.touchin.roboswag.components.adapters;
-
-import android.support.annotation.NonNull;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.RecyclerView;
-import android.view.ViewGroup;
-
-import java.util.List;
-
-/**
- * Objects of such class controls creation and binding of specific type of RecyclerView's ViewHolders.
- * Default {@link #getItemViewType} is generating on construction of object.
- *
- * @param Type of {@link RecyclerView.ViewHolder} of delegate.
- */
-public abstract class AdapterDelegate {
-
- private final int defaultItemViewType = ViewCompat.generateViewId();
-
- /**
- * Unique ID of AdapterDelegate.
- *
- * @return Unique ID.
- */
- public int getItemViewType() {
- return defaultItemViewType;
- }
-
- /**
- * Returns if object is processable by this delegate.
- *
- * @param items Items to check;
- * @param adapterPosition Position of item in adapter;
- * @param collectionPosition Position of item in collection;
- * @return True if item is processable by this delegate.
- */
- public abstract boolean isForViewType(@NonNull final List