diff --git a/app/build.gradle b/app/build.gradle index da509ca2091a103db26ff158564529d7b6f7d31c..3a873f408c1a688feda4236366da2576bb0fc044 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,8 +10,8 @@ android { minSdkVersion 8 targetSdkVersion 23 - versionCode 113 - versionName "6.0g" + versionCode 117 + versionName "6.1c" } buildTypes { @@ -47,4 +47,7 @@ android { output.outputFile.name.replace("app-release.apk", "${x}/${variant.applicationId}_${variant.versionName}_${new Date().format("dd-MM_hh.mm.ss")}.apk")) } } +} +dependencies { + compile files('libs/anrwatchdog-1.3.0.jar') } \ No newline at end of file diff --git a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java index 5ace3e550cb339753b8a64c2c1aec81e5cddfa9f..026e47350083c0f0b3bb22fd5134d8dabe6b6696 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java +++ b/app/src/main/java/ohi/andre/consolelauncher/LauncherActivity.java @@ -11,7 +11,6 @@ import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.content.LocalBroadcastManager; @@ -24,6 +23,9 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Toast; +import com.github.anrwatchdog.ANRError; +import com.github.anrwatchdog.ANRWatchDog; + import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -65,8 +67,14 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable { private CommandExecuter ex = new CommandExecuter() { @Override - public String exec(String input, String alias) { - if(main != null) main.onCommand(input, alias); + public String exec(String cmd, String aliasName) { + if(main != null) main.onCommand(cmd, aliasName); + return null; + } + + @Override + public String exec(String input) { + if(main != null) main.onCommand(input, null); return null; } }; @@ -142,6 +150,19 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable { private void finishOnCreate() { + new ANRWatchDog(5000) + .setANRListener(new ANRWatchDog.ANRListener() { + @Override + public void onAppNotResponding(ANRError anrError) { + Tuils.log(anrError); + Tuils.toFile(anrError); + + Toast.makeText(LauncherActivity.this, R.string.anr, Toast.LENGTH_LONG).show(); + } + }) + .setReportMainThreadOnly() + .start(); + Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { @@ -195,7 +216,12 @@ public class LauncherActivity extends AppCompatActivity implements Reloadable { if(notifications) { LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, new IntentFilter("Msg")); if(!Tuils.hasNotificationAccess(this)) { - startActivity(new Intent(Build.VERSION.SDK_INT >= 22 ? Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS : "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")); + Intent i = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"); + if(i.resolveActivity(getPackageManager()) == null) { + Toast.makeText(this, R.string.no_notification_access, Toast.LENGTH_LONG).show(); + } else { + startActivity(i); + } } } diff --git a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java index 309afe16c4b407c1fc073330adfa680582163ca5..23df1559dddb413cd6a4c8f0bb176b7192645c90 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/MainManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/MainManager.java @@ -6,7 +6,6 @@ import android.os.Environment; import android.text.SpannableString; import android.text.Spanned; import android.text.style.ForegroundColorSpan; -import android.util.Log; import java.io.File; import java.util.List; @@ -90,7 +89,6 @@ public class MainManager { new AliasTrigger(), new TuiCommandTrigger(), new AppTrigger(), -// keep this as last trigger new SystemCommandTrigger() }; private MainPack mainPack; @@ -103,6 +101,8 @@ public class MainManager { private boolean showAliasValue; private boolean showAppHistory; + private String multipleCmdSeparator; + public static Shell.Interactive interactive; private Hintable hintable; @@ -116,6 +116,8 @@ public class MainManager { showAliasValue = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.show_alias_content); showAppHistory = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.show_launch_history); + multipleCmdSeparator = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.multiple_cmd_separator); + CommandGroup group = new CommandGroup(mContext, COMMANDS_PKG); ContactManager cont = null; @@ -125,8 +127,14 @@ public class MainManager { CommandExecuter executer = new CommandExecuter() { @Override - public String exec(String input, String alias) { - onCommand(input, alias); + public String exec(String aliasValue, String alias) { + onCommand(aliasValue, alias); + return null; + } + + @Override + public String exec(String input) { + onCommand(input, null); return null; } }; @@ -172,20 +180,29 @@ public class MainManager { } if(alias != null && showAliasValue) { - out.onOutput(alias + " --> " + "[" + input + "]"); + out.onOutput(mainPack.aliasManager.formatLabel(alias, input)); + } + + String[] cmds; + if(multipleCmdSeparator.length() > 0) { + cmds = input.split(multipleCmdSeparator); + } else { + cmds = new String[] {input}; } - for (CmdTrigger trigger : triggers) { - boolean r; - try { - r = trigger.trigger(mainPack, input); - } catch (Exception e) { - out.onOutput(Tuils.getStackTrace(e)); - return; + for(String cmd : cmds) { + for (CmdTrigger trigger : triggers) { + boolean r; + try { + r = trigger.trigger(mainPack, cmd); + } catch (Exception e) { + out.onOutput(Tuils.getStackTrace(e)); + break; + } + if (r) { + break; + } } - if (r) { - return; - } else {} } } @@ -223,14 +240,23 @@ public class MainManager { } private class AliasTrigger implements CmdTrigger { + + @Override - public boolean trigger(ExecutePack info, String alias) { - String aliasValue = mainPack.aliasManager.getAlias(alias); - if (aliasValue == null) { + public boolean trigger(ExecutePack info, String input) { + String alias[] = mainPack.aliasManager.getAlias(input, true); + + String aliasValue = alias[0]; + if (alias[0] == null) { return false; } - mainPack.executer.exec(aliasValue, alias); + String aliasName = alias[1]; + String residual = alias[2]; + + aliasValue = mainPack.aliasManager.format(aliasValue, residual); + + mainPack.executer.exec(aliasValue, aliasName); return true; } @@ -364,8 +390,9 @@ public class MainManager { } } } catch (Exception e) { - out.onOutput(e.toString()); - Log.e("andre", "", e); + out.onOutput(Tuils.getStackTrace(e)); + Tuils.log(e); + Tuils.toFile(e); } } }.start(); diff --git a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java index 929af44f77d7f3085aaf213e5a9fb1714f2e7142..58ab51bce65c6d642b2a1b9124b49f8aa620a7bf 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/UIManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/UIManager.java @@ -82,6 +82,26 @@ public class UIManager implements OnTouchListener { String batteryFormat; // boolean batteryCharging; + private String multipleCmdSeparator; + + private boolean selectFirstSuggestionEnter = false; + private OnNewInputListener inputListener = new OnNewInputListener() { + @Override + public void onNewInput(String input) { + if(suggestionsView != null) { +// if(suggestionsView.getChildCount() > 0 && selectFirstSuggestionEnter) { +// View v = suggestionsView.getChildAt(0); +// v.performClick(); +// return; +// } + suggestionsView.removeAllViews(); + + } + trigger.exec(input); + + } + }; + private Runnable batteryRunnable = new Runnable() { @Override public void run() { @@ -306,10 +326,28 @@ public class UIManager implements OnTouchListener { boolean execOnClick = suggestion.exec; String text = suggestion.getText(); + String input = mTerminalAdapter.getInput(); + if(suggestion.type == SuggestionsManager.Suggestion.TYPE_PERMANENT) { - mTerminalAdapter.setInput(mTerminalAdapter.getInput() + text); + mTerminalAdapter.setInput(input + text); } else { - mTerminalAdapter.setInput(text); + if(multipleCmdSeparator.length() > 0) { + String[] split = input.split(multipleCmdSeparator); + if(split.length == 0) return; + if(split.length == 1) mTerminalAdapter.setInput(text); + else { + split[split.length - 1] = Tuils.EMPTYSTRING; + + String beforeInputs = Tuils.EMPTYSTRING; + for(int count = 0; count < split.length - 1; count++) { + beforeInputs = beforeInputs + split[count] + multipleCmdSeparator; + } + + mTerminalAdapter.setInput(beforeInputs + text); + } + } else { + mTerminalAdapter.setInput(text); + } } if (execOnClick) { @@ -320,21 +358,12 @@ public class UIManager implements OnTouchListener { } }; - public void requestSuggestion(String text) { + public void requestSuggestion(final String input) { + if (suggestionsView == null || suggestionsManager == null || !showSuggestions) { return; } - int lastSpace = text.lastIndexOf(Tuils.SPACE); - - String lastWord = text.substring(lastSpace != -1 ? lastSpace + 1 : 0); - String before = text.substring(0, lastSpace != -1 ? lastSpace + 1 : 0); - - requestSuggestion(before, lastWord); - } - - private void requestSuggestion(final String before, final String lastWord) { - if (suggestionViewParams == null) { suggestionViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); suggestionViewParams.setMargins(SkinManager.SUGGESTION_MARGIN, 0, SkinManager.SUGGESTION_MARGIN, 0); @@ -368,7 +397,34 @@ public class UIManager implements OnTouchListener { public void run() { super.run(); - final SuggestionsManager.Suggestion[] suggestions = suggestionsManager.getSuggestions(info, before, lastWord); + String before, lastWord; + String lastInput; + if(multipleCmdSeparator.length() > 0) { + String[] split = input.split(multipleCmdSeparator); + if(split.length == 0) lastInput = input; + else lastInput = split[split.length - 1]; + } else { + lastInput = input; + } + + int lastSpace = lastInput.lastIndexOf(Tuils.SPACE); + if(lastSpace == -1) { + before = Tuils.EMPTYSTRING; + lastWord = lastInput; + } else { + before = lastInput.substring(0,lastSpace); + lastWord = lastInput.substring(lastSpace + 1,lastInput.length()); + } + + + final SuggestionsManager.Suggestion[] suggestions; + try { + suggestions = suggestionsManager.getSuggestions(info, before, lastWord); + } catch (Exception e) { + Tuils.log(e); + Tuils.toFile(e); + return; + } if(suggestions.length == 0) { ((Activity) mContext).runOnUiThread(removeAllSuggestions); @@ -430,6 +486,9 @@ public class UIManager implements OnTouchListener { policy = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); component = new ComponentName(context, PolicyReceiver.class); + multipleCmdSeparator = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.multiple_cmd_separator); + selectFirstSuggestionEnter = XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.enter_first_suggestion); + mContext = context; this.info = (MainPack) info; @@ -678,15 +737,7 @@ public class UIManager implements OnTouchListener { } else initDetector(); mTerminalAdapter = new TerminalManager(terminalView, inputView, prefixView, submitView, backView, nextView, deleteView, pasteView, skinManager, context, mainPack); - mTerminalAdapter.setInputListener(new OnNewInputListener() { - @Override - public void onNewInput(String input) { - if(suggestionsView != null) { - suggestionsView.removeAllViews(); - } - trigger.exec(input, null); - } - }); + mTerminalAdapter.setInputListener(inputListener); if(XMLPrefsManager.get(boolean.class, XMLPrefsManager.Behavior.donation_message)) { mTerminalAdapter.addMessager(new TerminalManager.Messager(20, context.getString(R.string.rate_donate_text))); } diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java index d1714868d00af2d0bc5959c349b4c596e72e2049..79cdbd8b43578744a57813acedda375cc7bc922e 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java +++ b/app/src/main/java/ohi/andre/consolelauncher/commands/CommandTuils.java @@ -6,6 +6,7 @@ import android.graphics.Color; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import ohi.andre.consolelauncher.commands.main.MainPack; @@ -381,16 +382,17 @@ public class CommandTuils { if(xmlPrefsEntrys == null) { xmlPrefsEntrys = new ArrayList<>(); - for(XMLPrefsManager.XMLPrefsRoot element : XMLPrefsManager.XMLPrefsRoot.values()) - for(XMLPrefsManager.XMLPrefsSave save : element.copy) - xmlPrefsEntrys.add(save); - for(XMLPrefsManager.XMLPrefsSave save : AppsManager.Options.values()) xmlPrefsEntrys.add(save); - for(XMLPrefsManager.XMLPrefsSave save : NotificationManager.Options.values()) xmlPrefsEntrys.add(save); + + for(XMLPrefsManager.XMLPrefsRoot element : XMLPrefsManager.XMLPrefsRoot.values()) Collections.addAll(element.copy); + Collections.addAll(xmlPrefsEntrys, AppsManager.Options.values()); + Collections.addAll(xmlPrefsEntrys, NotificationManager.Options.values()); } String candidate = index == -1 ? input : input.substring(0,index); for(XMLPrefsManager.XMLPrefsSave xs : xmlPrefsEntrys) { - if(xs.is(candidate)) return new ArgInfo(xs, input.substring(index + 1,input.length()), true, 1); + if(xs.is(candidate)) { + return new ArgInfo(xs, index == -1 ? null : input.substring(index + 1,input.length()), true, 1); + } } return new ArgInfo(null, input, false, 0); } diff --git a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java index 47a7e690f851266050020f42af783eeaf1117224..c2bfd707c16e7f4d7c6e9c2e01f49f5d9a92565c 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java +++ b/app/src/main/java/ohi/andre/consolelauncher/commands/main/raw/config.java @@ -57,7 +57,9 @@ public class config extends ParamCommand { @Override public String exec(ExecutePack pack) { XMLPrefsManager.XMLPrefsSave save = pack.get(XMLPrefsManager.XMLPrefsSave.class, 1); - return XMLPrefsManager.get(String.class, save); + String s = XMLPrefsManager.get(String.class, save); + if(s.length() == 0) return "\"\""; + return s; } }; @@ -127,6 +129,11 @@ public class config extends ParamCommand { @Override public String onNotArgEnough(ExecutePack pack, int nArgs) { + if(nArgs == 2 && pack.get(ohi.andre.consolelauncher.commands.main.Param.class, 0).equals(Param.set)) { + pack.args = new Object[] {pack.args[0], pack.args[1], Tuils.EMPTYSTRING}; + return Param.set.exec(pack); + } + return pack.context.getString(helpRes()); } } diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java index 57615ac87fa4b54de1dc34978422a96b6faf1e9f..3c9fb41747496054665b4dbbfe2b4237985e3efa 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AliasManager.java @@ -1,7 +1,5 @@ package ohi.andre.consolelauncher.managers; -import android.util.Log; - import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -14,6 +12,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.regex.Pattern; import ohi.andre.consolelauncher.tuils.Tuils; import ohi.andre.consolelauncher.tuils.interfaces.Reloadable; @@ -24,8 +23,14 @@ public class AliasManager implements Reloadable { private Map<String, String> aliases; + private String paramMarker, paramSeparator, aliasLabelFormat; + public AliasManager() { reload(); + + paramMarker = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.alias_param_marker); + paramSeparator = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.alias_param_separator); + aliasLabelFormat = XMLPrefsManager.get(String.class, XMLPrefsManager.Behavior.alias_content_format); } public String printAliases() { @@ -37,8 +42,61 @@ public class AliasManager implements Reloadable { return output.trim(); } - public String getAlias(String s) { - return aliases.get(s); +// [0] = aliasValue +// [1] = aliasName +// [2] = residualString + public String[] getAlias(String alias, boolean supportSpaces) { + if(supportSpaces) { + + String[] split = alias.split(Tuils.SPACE); + String name = Tuils.EMPTYSTRING; + + for(int count = 0; count < split.length; count++) { + name += Tuils.SPACE + split[count]; + name = name.trim(); + + String a = aliases.get(name); + + if(a != null) { + String residual = Tuils.EMPTYSTRING; + for(int c = count + 1; c < split.length; c++) { + residual += split[c] + Tuils.SPACE; + } + + return new String[] {a, name, residual.trim()}; + } + } + + return new String[] {null, null, alias}; + } else { + return new String[] {aliases.get(alias), alias, Tuils.EMPTYSTRING}; + } + } + + public String format(String aliasValue, String params) { + params = params.trim(); + + String quoted = Pattern.quote(paramSeparator); + + if(params.length() == 0) return aliasValue; + String[] split = params.split(quoted); + + for(String s : split) { + aliasValue = aliasValue.replaceFirst(quoted, s); + } + + return aliasValue; + } + + private final Pattern pn = Pattern.compile("%n", Pattern.CASE_INSENSITIVE); + private final Pattern pv = Pattern.compile("%v", Pattern.CASE_INSENSITIVE); + private final Pattern pa = Pattern.compile("%a", Pattern.CASE_INSENSITIVE); + public String formatLabel(String aliasName, String aliasValue) { + String a = aliasLabelFormat; + a = pn.matcher(a).replaceAll(Tuils.NEWLINE); + a = pv.matcher(a).replaceAll(aliasValue); + a = pa.matcher(a).replaceAll(aliasName); + return a; } @Override @@ -57,13 +115,21 @@ public class AliasManager implements Reloadable { while((line = reader.readLine()) != null) { String[] splatted = line.split("="); if(splatted.length < 2) continue; - aliases.put(splatted[0], splatted[1]); + + String name, value = Tuils.EMPTYSTRING; + name = splatted[0]; + + for(int c = 1; c < splatted.length; c++) { + value += splatted[c]; + if(c != splatted.length - 1) value += "="; + } + + aliases.put(name, value); } } catch (Exception e) {} } public boolean add(String name, String value) { - Log.e("andre", "adding: " + name + " ---> " + value); FileOutputStream fos; try { diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java index 5c0708c3ca79558e6a848e93e7c0dcc0b07ff25c..0ce46709bb7d6b3043e064bc5d613062dde8cce5 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/AppsManager.java @@ -382,6 +382,8 @@ public class AppsManager implements XMLPrefsManager.XmlPrefsElement { } private void appUninstalled(String packageName) { + if(outputable == null || appsHolder == null || context == null) return; + outputable.onOutput(context.getString(R.string.app_uninstalled) + Tuils.SPACE + packageName); List<LaunchInfo> infos = AppUtils.findLaunchInfosWithPackage(packageName, appsHolder.getApps()); diff --git a/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java b/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java index 4ed6db6ecf06bf797907408ced71033d6bf26cea..834cf049f6db9149c17230955c295a32f5b96425 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java +++ b/app/src/main/java/ohi/andre/consolelauncher/managers/XMLPrefsManager.java @@ -655,6 +655,36 @@ public class XMLPrefsManager { public String defaultValue() { return "@"; } + }, + alias_param_marker { + @Override + public String defaultValue() { + return "%"; + } + }, + alias_param_separator { + @Override + public String defaultValue() { + return ","; + } + }, + multiple_cmd_separator { + @Override + public String defaultValue() { + return ";"; + } + }, + alias_content_format { + @Override + public String defaultValue() { + return "%a --> [%v]"; + } + }, + enter_first_suggestion { + @Override + public String defaultValue() { + return "true"; + } }; @Override @@ -845,15 +875,6 @@ public class XMLPrefsManager { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); -// BufferedReader oldStream = null; -// HashMap<XMLPrefsSave, String> oldValues = null; -// -// File old = new File(folder, "settings.txt"); -// if(old.exists()) { -// oldStream = new BufferedReader(new FileReader(old)); -// oldValues = getOld(oldStream); -// } - for(XMLPrefsRoot element : XMLPrefsRoot.values()) { File file = new File(folder, element.path); if(!file.exists() && !file.createNewFile()) continue; @@ -925,17 +946,7 @@ public class XMLPrefsManager { if(e.getValue().equals(s)) value = e.getKey(); } if(value == null) { - -// if(oldValues != null) { -// for(Map.Entry<XMLPrefsSave, String> sm : oldValues.entrySet()) { -// if(sm.getKey().equals(s)) { -// value = sm.getValue(); -// } -// } -// } - -// if(value == null) - value = s.defaultValue(); + value = s.defaultValue(); } Element em = d.createElement(s.label()); @@ -947,8 +958,6 @@ public class XMLPrefsManager { writeTo(d, file); } - -// if(old.exists()) old.delete(); } public static Object transform(String s, Class<?> c) { diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Compare.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Compare.java index 6f6849d63943527b953ef349e7c7fc6a1a1d7cd8..8c4dc89962af74ea380104a77fbc5b36d04563cd 100644 --- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Compare.java +++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Compare.java @@ -3,6 +3,8 @@ package ohi.andre.consolelauncher.tuils; import java.text.Normalizer; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.regex.Pattern; @@ -13,44 +15,79 @@ import java.util.regex.Pattern; public class Compare { static final char[] allowed_separators = {' ', '-', '_'}; - private static final String ACCENTS_PATTERN = "\\p{InCombiningDiacriticalMarks}+"; + + static Pattern unconsideredSymbols = Pattern.compile("[\\s_-]"); + static Pattern accentPattern = Pattern.compile(ACCENTS_PATTERN); + public static String removeAccents(String s) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) { - Pattern pattern = Pattern.compile(ACCENTS_PATTERN); String decomposed = Normalizer.normalize(s, Normalizer.Form.NFD); - return pattern.matcher(decomposed).replaceAll(Tuils.EMPTYSTRING); + return accentPattern.matcher(decomposed).replaceAll(Tuils.EMPTYSTRING); } return s; } public static int matches(String compared, String comparator, boolean allowSkip) { +// Tuils.log("compared: " + compared + ", comparator: " + comparator); + compared = removeAccents(compared).toLowerCase().trim(); comparator = removeAccents(comparator).toLowerCase().trim(); - List<String> s = new ArrayList<>(); + double minRate = (double) comparator.length() / 2d; +// Tuils.log("min: " + minRate); + + List<ComparePack> s = new ArrayList<>(); if(allowSkip) { for(char sep : allowed_separators) { String[] split = compared.split(String.valueOf(sep)); - s.addAll(Arrays.asList(split)); + if(split.length > 1) { + for(int count = 1; count < split.length; count++) { + s.add(new ComparePack(split[count], count, split.length)); + } + } } } - s.add(compared); + + String unconsidered = unconsideredSymbols.matcher(compared).replaceAll(Tuils.EMPTYSTRING); + if(unconsidered.length() != compared.length()) { + s.add(new ComparePack(unconsidered, 0, 1)); + } + + s.add(new ComparePack(compared, 0, 1)); float maxRate = -1; - for(String st : s) { - float rate = 0; - for(int i = 0; i < st.length() && i < comparator.length(); i++) { - char c1 = st.charAt(i); + Main: + for(ComparePack cmp : s) { +// Tuils.log("s: " + cmp.s); + + int stop = Math.min(cmp.s.length(), comparator.length()); + float minus = (float) (0.5 * (comparator.length() / 5)); + + float rate = cmp.coefficient() * -1; +// Tuils.log("initialRate: " + rate); + for(int i = 0; i < stop; i++) { + char c1 = cmp.s.charAt(i); char c2 = comparator.charAt(i); if(c1 == c2) { - rate += (double) (st.length() - i) / (double) st.length(); + rate++; + } else { + rate -= minus; + + if(rate + (stop - 1 - i) < minRate) { +// Tuils.log("continue"); + continue Main; + } } +// Tuils.log("rate: " + rate); } - if(rate >= (double) comparator.length() / 2d) maxRate = Math.max(maxRate, rate); + if(rate >= minRate) { + maxRate = Math.max(maxRate, rate); +// Tuils.log("maxRate changed"); + } } return Math.round(maxRate); @@ -81,12 +118,12 @@ public class Compare { if(rate != -1) ms.add(new SimpleMutableEntry<>(s, rate)); } -// Collections.sort(ms, new Comparator<SimpleMutableEntry<String, Integer>>() { -// @Override -// public int compare(SimpleMutableEntry<String, Integer> o1, SimpleMutableEntry<String, Integer> o2) { -// return o1.getValue() - o2.getValue(); -// } -// }); + Collections.sort(ms, new Comparator<SimpleMutableEntry<String, Integer>>() { + @Override + public int compare(SimpleMutableEntry<String, Integer> o1, SimpleMutableEntry<String, Integer> o2) { + return o1.getValue() - o2.getValue(); + } + }); return ms; } @@ -94,4 +131,20 @@ public class Compare { public static List<SimpleMutableEntry<String, Integer>> matchesWithRate(String[] compared, String comparator, boolean allowSkip) { return matchesWithRate(Arrays.asList(compared), comparator, allowSkip); } + + private static class ComparePack { + String s; + int index; + int total; + + public ComparePack(String s, int index, int total) { + this.s = s; + this.index = index; + this.total = total; + } + + public int coefficient() { + return index; + } + } } diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java index 5b1568ab404940eb979acec7f9aa6d260f0e614d..99a280ab6fa7e5683d31a2b0144e6d64016bbd7f 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java +++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/Tuils.java @@ -267,7 +267,6 @@ public class Tuils { public static final int MEGA = 2; public static final int KILO = 3; public static final int BYTE = 4; - public static final int PERCENTAGE = 5; private static long total = -1; @@ -295,11 +294,15 @@ public class Tuils { } public static double round(double value, int places) { - if (places < 0) throw new IllegalArgumentException(); + if (places < 0) places = 0; - BigDecimal bd = new BigDecimal(value); - bd = bd.setScale(places, RoundingMode.HALF_UP); - return bd.doubleValue(); + try { + BigDecimal bd = new BigDecimal(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); + } catch (Exception e) { + return value; + } } public static List<String> getClassesInPackage(String packageName, Context c) throws IOException { diff --git a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java index ca2fc99ac8cb739048d6e42780bf545a182e03d4..e0d8d0e7052d3dfcee14c46016f56ce0869e8377 100755 --- a/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java +++ b/app/src/main/java/ohi/andre/consolelauncher/tuils/interfaces/CommandExecuter.java @@ -5,5 +5,6 @@ package ohi.andre.consolelauncher.tuils.interfaces; */ public interface CommandExecuter { - String exec(String input, String alias); + String exec(String aliasValue, String aliasName); + String exec(String input); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0f08e2628dfd0ec835f3bb6c430f0c82998e91ba..1134ffe584b23cded5f5faf5ba6a582c5a7ccd22 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -10,6 +10,7 @@ <string name="output_rate">Thank you!</string> <string name="start_notification">T-UI started</string> <string name="tui_running">T-UI is running</string> + <string name="anr">t-ui is having some issues. Please send to the developer your file crash.txt</string> <!-- files --> <string name="output_error">An unknown error has occurred</string> @@ -18,6 +19,7 @@ <!-- notifications --> <string name="notification_reader">Notification Reader</string> + <string name="no_notification_access">Unfortunately t-ui can\'t redirect you to the \"Notification access\" page of your system settings</string> <!-- helps texts --> <string name="rate_donate_text">\nDo you like my work? Rate on Play Store (command: >>rate) or offer me a coffee (command: >>donate). Thank you for using T-UI. diff --git a/build.gradle b/build.gradle index e21e380e49c41ef64b48689e77b87241f7fba6ef..59542799c65fa737c405c66c4f7d45e4fc388c4b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,3 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - buildscript { repositories { @@ -9,9 +7,6 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:2.3.1' - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files } }