/* * Copyright (C) 2017 The AOKP Project * * 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 com.aokp.romcontrol.util; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.AsyncTask; import android.os.SystemProperties; import android.util.Log; import android.widget.Toast; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Date; import com.aokp.romcontrol.R; // don't show unavoidable warnings @SuppressWarnings({ "UnusedDeclaration", "MethodWithMultipleReturnPoints", "ReturnOfNull", "NestedAssignment", "DynamicRegexReplaceableByCompiledPattern", "BreakStatement"}) public class Helpers { // avoids hardcoding the tag private static final String TAG = Thread.currentThread().getStackTrace()[1].getClassName(); public Helpers() { // dummy constructor } /** * Checks device for SuperUser permission * * @return If SU was granted or denied */ @SuppressWarnings("MethodWithMultipleReturnPoints") public static boolean checkSu() { if (!new File("/system/bin/su").exists() && !new File("/system/xbin/su").exists()) { Log.e(TAG, "su binary does not exist!!!"); return false; // tell caller to bail... } try { if (CMDProcessor.runSuCommand("ls /data/app-private").success()) { Log.i(TAG, " SU exists and we have permission"); return true; } else { Log.i(TAG, " SU exists but we don't have permission"); return false; } } catch (NullPointerException e) { Log.e(TAG, "NullPointer throw while looking for su binary", e); return false; } } /** * Checks device for network connectivity * * @return If the device has data connectivity */ public static boolean isNetworkAvailable(Context context) { boolean state = false; if (context != null) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnected()) { Log.i(TAG, "The device currently has data connectivity"); state = true; } else { Log.i(TAG, "The device does not currently have data connectivity"); state = false; } } return state; } /** * Checks to see if Busybox is installed in "/system/" * * @return If busybox exists */ public static boolean checkBusybox() { if (!new File("/system/bin/busybox").exists() && !new File("/system/xbin/busybox").exists()) { Log.e(TAG, "Busybox not in xbin or bin!"); return false; } try { if (!CMDProcessor.runSuCommand("busybox mount").success()) { Log.e(TAG, "Busybox is there but it is borked! "); return false; } } catch (NullPointerException e) { Log.e(TAG, "NullpointerException thrown while testing busybox", e); return false; } return true; } public static String[] getMounts(CharSequence path) { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader("/proc/mounts"), 256); String line; while ((line = bufferedReader.readLine()) != null) { if (line.contains(path)) { return line.split(" "); } } } catch (FileNotFoundException ignored) { Log.d(TAG, "/proc/mounts does not exist"); } catch (IOException ignored) { Log.d(TAG, "Error reading /proc/mounts"); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException ignored) { // ignored } } } return null; } public static boolean getMount(String mount) { String[] mounts = getMounts("/system"); if (mounts != null && mounts.length >= 3) { String device = mounts[0]; String path = mounts[1]; String point = mounts[2]; String preferredMountCmd = new String( "mount -o " + mount + ",remount -t " + point + ' ' + device + ' ' + path); if (CMDProcessor.runSuCommand(preferredMountCmd).success()) { return true; } } String fallbackMountCmd = new String("busybox mount -o remount," + mount + " /system"); return CMDProcessor.runSuCommand(fallbackMountCmd).success(); } public static String readOneLine(String fname) { BufferedReader br = null; String line = null; try { br = new BufferedReader(new FileReader(fname), 1024); line = br.readLine(); } catch (FileNotFoundException ignored) { Log.d(TAG, "File was not found! trying via shell..."); return readFileViaShell(fname, true); } catch (IOException e) { Log.d(TAG, "IOException while reading system file", e); return readFileViaShell(fname, true); } finally { if (br != null) { try { br.close(); } catch (IOException ignored) { // failed to close reader } } } return line; } public static String readFileViaShell(String filePath, boolean useSu) { String command = new String("cat " + filePath); return useSu ? CMDProcessor.runSuCommand(command).getStdout() : CMDProcessor.runShellCommand(command).getStdout(); } public static boolean writeOneLine(String filename, String value) { FileWriter fileWriter = null; try { fileWriter = new FileWriter(filename); fileWriter.write(value); } catch (IOException e) { String Error = "Error writing { " + value + " } to file: " + filename; Log.e(TAG, Error, e); return false; } finally { if (fileWriter != null) { try { fileWriter.close(); } catch (IOException ignored) { // failed to close writer } } } return true; } public static String[] getAvailableIOSchedulers() { String[] schedulers = null; String[] aux = readStringArray("/sys/block/mmcblk0/queue/scheduler"); if (aux != null) { schedulers = new String[aux.length]; for (int i = 0; i < aux.length; i++) { schedulers[i] = aux[i].charAt(0) == '[' ? aux[i].substring(1, aux[i].length() - 1) : aux[i]; } } return schedulers; } private static String[] readStringArray(String fname) { String line = readOneLine(fname); if (line != null) { return line.split(" "); } return null; } public static String getIOScheduler() { String scheduler = null; String[] schedulers = readStringArray("/sys/block/mmcblk0/queue/scheduler"); if (schedulers != null) { for (String s : schedulers) { if (s.charAt(0) == '[') { scheduler = s.substring(1, s.length() - 1); break; } } } return scheduler; } /** * Long toast message * * @param context Application Context * @param msg Message to send */ public static void msgLong(Context context, String msg) { if (context != null && msg != null) { Toast.makeText(context, msg.trim(), Toast.LENGTH_LONG).show(); } } /** * Short toast message * * @param context Application Context * @param msg Message to send */ public static void msgShort(Context context, String msg) { if (context != null && msg != null) { Toast.makeText(context, msg.trim(), Toast.LENGTH_SHORT).show(); } } /** * Long toast message * * @param context Application Context * @param msg Message to send */ public static void sendMsg(Context context, String msg) { if (context != null && msg != null) { msgLong(context, msg); } } /** * Return a timestamp * * @param context Application Context */ @SuppressWarnings("UnnecessaryFullyQualifiedName") public static String getTimestamp(Context context) { String timestamp = "unknown"; Date now = new Date(); java.text.DateFormat dateFormat = android.text.format.DateFormat.getDateFormat(context); java.text.DateFormat timeFormat = android.text.format.DateFormat.getTimeFormat(context); if (dateFormat != null && timeFormat != null) { timestamp = dateFormat.format(now) + ' ' + timeFormat.format(now); } return timestamp; } public static boolean isPackageInstalled(String packageName, PackageManager pm) { try { String mVersion = pm.getPackageInfo(packageName, 0).versionName; if (mVersion == null) { return false; } } catch (NameNotFoundException notFound) { Log.e(TAG, "Package could not be found!", notFound); return false; } return true; } public static void restartSystemUI() { CMDProcessor.startSuCommand("pkill -TERM -f com.android.systemui"); } public static void showSystemUIrestartDialog(Activity a) { final AlertDialog.Builder builder = new AlertDialog.Builder(a); builder.setTitle(R.string.systemui_restart_title); builder.setMessage(R.string.systemui_restart_message); builder.setPositiveButton(R.string.print_restart, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { @Override protected void onPreExecute() { ProgressDialog dialog = new ProgressDialog(a); dialog.setMessage(a.getResources().getString(R.string.restarting_ui)); dialog.setCancelable(false); dialog.setIndeterminate(true); dialog.show(); } @Override protected Void doInBackground(Void... params) { // Give the user a second to see the dialog try { Thread.sleep(1000); } catch (InterruptedException e) { // Ignore } // Restart the UI CMDProcessor.startSuCommand("pkill -f com.android.systemui"); a.finish(); return null; } }; task.execute(); } }); builder.setNegativeButton(android.R.string.cancel, null); builder.show(); } public static void setSystemProp(String prop, String val) { CMDProcessor.startSuCommand("setprop " + prop + " " + val); } public static String getSystemProp(String prop, String def) { String result = null; try { result = SystemProperties.get(prop, def); } catch (IllegalArgumentException iae) { Log.e(TAG, "Failed to get prop: " + prop); } return result == null ? def : result; } }