From cc8addd4c27102cbf9a69dacdd0b613d1ebe7366 Mon Sep 17 00:00:00 2001 From: sunilpaulmathew Date: Thu, 15 Apr 2021 13:04:10 +0200 Subject: [PATCH] I/O: Added a seperate page to control all the I/O blocks Linkied to main I/O page Issue #100 Signed-off-by: sunilpaulmathew --- app/src/main/AndroidManifest.xml | 3 +- .../activities/AdvancedIOActivity.java | 46 ++++ .../activities/NavigationActivity.java | 6 +- .../fragments/ApplyOnBootFragment.java | 4 + .../fragments/kernel/IOAdvancedFragment.java | 253 ++++++++++++++++++ .../fragments/kernel/IOFragment.java | 15 ++ .../utils/kernel/io/IOAdvanced.java | 201 ++++++++++++++ app/src/main/res/values/strings.xml | 6 + 8 files changed, 530 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/smartpack/kernelmanager/activities/AdvancedIOActivity.java create mode 100644 app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOAdvancedFragment.java create mode 100644 app/src/main/java/com/smartpack/kernelmanager/utils/kernel/io/IOAdvanced.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 93394d280..bfefc3c4d 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -69,8 +69,9 @@ - + + diff --git a/app/src/main/java/com/smartpack/kernelmanager/activities/AdvancedIOActivity.java b/app/src/main/java/com/smartpack/kernelmanager/activities/AdvancedIOActivity.java new file mode 100644 index 000000000..d9acfebf7 --- /dev/null +++ b/app/src/main/java/com/smartpack/kernelmanager/activities/AdvancedIOActivity.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021-2022 sunilpaulmathew + * + * This file is part of SmartPack Kernel Manager, which is a heavily modified version of Kernel Adiutor, + * originally developed by Willi Ye + * + * Both SmartPack Kernel Manager & Kernel Adiutor are free softwares: you can redistribute it + * and/or modify it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SmartPack Kernel Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SmartPack Kernel Manager. If not, see . + * + */ + +package com.smartpack.kernelmanager.activities; + +import android.os.Bundle; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; + +import com.smartpack.kernelmanager.R; +import com.smartpack.kernelmanager.fragments.kernel.IOAdvancedFragment; + +/* + * Created by sunilpaulmathew on April 14, 2021 + */ +public class AdvancedIOActivity extends BaseActivity { + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_launchfragment); + + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, + new IOAdvancedFragment()).commit(); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/smartpack/kernelmanager/activities/NavigationActivity.java b/app/src/main/java/com/smartpack/kernelmanager/activities/NavigationActivity.java index 640b8b595..fe6a5bf80 100644 --- a/app/src/main/java/com/smartpack/kernelmanager/activities/NavigationActivity.java +++ b/app/src/main/java/com/smartpack/kernelmanager/activities/NavigationActivity.java @@ -118,9 +118,9 @@ public class NavigationActivity extends BaseActivity implements NavigationView.OnNavigationItemSelectedListener { private ArrayList mFragments = new ArrayList<>(); - private Map> mActualFragments = new LinkedHashMap<>(); + private final Map> mActualFragments = new LinkedHashMap<>(); - private Handler mHandler = new Handler(); + private final Handler mHandler = new Handler(); private DrawerLayout mDrawer; private NavigationView mNavigationView; private boolean mExit; @@ -146,7 +146,7 @@ protected void onCreate(Bundle savedInstanceState) { private static class FragmentLoader extends AsyncTask { - private WeakReference mRefActivity; + private final WeakReference mRefActivity; private FragmentLoader(NavigationActivity activity) { mRefActivity = new WeakReference<>(activity); diff --git a/app/src/main/java/com/smartpack/kernelmanager/fragments/ApplyOnBootFragment.java b/app/src/main/java/com/smartpack/kernelmanager/fragments/ApplyOnBootFragment.java index 2661d485c..96031a8aa 100644 --- a/app/src/main/java/com/smartpack/kernelmanager/fragments/ApplyOnBootFragment.java +++ b/app/src/main/java/com/smartpack/kernelmanager/fragments/ApplyOnBootFragment.java @@ -38,6 +38,7 @@ import com.smartpack.kernelmanager.fragments.kernel.DisplayLEDFragment; import com.smartpack.kernelmanager.fragments.kernel.EntropyFragment; import com.smartpack.kernelmanager.fragments.kernel.GPUFragment; +import com.smartpack.kernelmanager.fragments.kernel.IOAdvancedFragment; import com.smartpack.kernelmanager.fragments.kernel.IOFragment; import com.smartpack.kernelmanager.fragments.kernel.KLapseFragment; import com.smartpack.kernelmanager.fragments.kernel.KSMFragment; @@ -55,6 +56,7 @@ import com.smartpack.kernelmanager.fragments.tools.CustomControlsFragment; import com.smartpack.kernelmanager.utils.Prefs; import com.smartpack.kernelmanager.utils.Utils; +import com.smartpack.kernelmanager.utils.kernel.io.IOAdvanced; import java.util.HashMap; @@ -78,6 +80,7 @@ public class ApplyOnBootFragment extends BaseFragment { public static final String BATTERY = "battery_onboot"; public static final String LED = "led_onboot"; public static final String IO = "io_onboot"; + public static final String IO_ADVANCED = "ioadv_onboot"; public static final String KSM = "ksm_onboot"; public static final String LMK = "lmk_onboot"; public static final String WAKELOCKS = "wakelocks_onboot"; @@ -104,6 +107,7 @@ public class ApplyOnBootFragment extends BaseFragment { sAssignments.put(BatteryFragment.class, BATTERY); sAssignments.put(DisplayLEDFragment.class, LED); sAssignments.put(IOFragment.class, IO); + sAssignments.put(IOAdvancedFragment.class, IO_ADVANCED); sAssignments.put(KSMFragment.class, KSM); sAssignments.put(LMKFragment.class, LMK); sAssignments.put(WakelockFragment.class, WAKELOCKS); diff --git a/app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOAdvancedFragment.java b/app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOAdvancedFragment.java new file mode 100644 index 000000000..d36efb97a --- /dev/null +++ b/app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOAdvancedFragment.java @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2021-2022 sunilpaulmathew + * + * This file is part of SmartPack Kernel Manager, which is a heavily modified version of Kernel Adiutor, + * originally developed by Willi Ye + * + * Both SmartPack Kernel Manager & Kernel Adiutor are free softwares: you can redistribute it + * and/or modify it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SmartPack Kernel Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SmartPack Kernel Manager. If not, see . + * + */ + +package com.smartpack.kernelmanager.fragments.kernel; + +import android.annotation.SuppressLint; +import android.os.AsyncTask; +import android.text.InputType; + +import com.smartpack.kernelmanager.R; +import com.smartpack.kernelmanager.fragments.ApplyOnBootFragment; +import com.smartpack.kernelmanager.fragments.RecyclerViewFragment; +import com.smartpack.kernelmanager.utils.kernel.io.IOAdvanced; +import com.smartpack.kernelmanager.views.recyclerview.CardView; +import com.smartpack.kernelmanager.views.recyclerview.GenericSelectView; +import com.smartpack.kernelmanager.views.recyclerview.RecyclerViewItem; +import com.smartpack.kernelmanager.views.recyclerview.SeekBarView; +import com.smartpack.kernelmanager.views.recyclerview.SelectView; +import com.smartpack.kernelmanager.views.recyclerview.SwitchView; + +import java.util.ArrayList; +import java.util.List; + +/* + * Created by sunilpaulmathew on April 14, 2021 + */ +public class IOAdvancedFragment extends RecyclerViewFragment { + + private IOAdvanced mIOAdvanced; + + private AsyncTask> mLoader; + + @Override + protected void init() { + super.init(); + + mIOAdvanced = IOAdvanced.getInstance(); + addViewPagerFragment(ApplyOnBootFragment.newInstance(this)); + } + + @Override + protected void addItems(List items) { + reload(); + } + + private void reload() { + if (mLoader == null) { + getHandler().postDelayed(new Runnable() { + @SuppressLint("StaticFieldLeak") + @Override + public void run() { + clearItems(); + mLoader = new AsyncTask>() { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + showProgress(); + } + + @Override + protected List doInBackground(Void... voids) { + List items = new ArrayList<>(); + if (IOAdvanced.getIOBlockList().size() > 0) { + IOBlocksInit(items); + } + return items; + } + + @Override + protected void onPostExecute(List recyclerViewItems) { + super.onPostExecute(recyclerViewItems); + for (RecyclerViewItem item : recyclerViewItems) { + addItem(item); + } + hideProgress(); + mLoader = null; + } + }; + mLoader.execute(); + } + }, 250); + } + } + + private void IOBlocksInit(List items) { + CardView blocksCard = new CardView(getActivity()); + blocksCard.setTitle(getString(R.string.io_blocks, IOAdvanced.getCurrentBlock(requireActivity()))); + + SelectView ioBlocks = new SelectView(); + ioBlocks.setTitle(getString(R.string.io_blocks_select)); + ioBlocks.setSummary(getString(R.string.io_blocks_select_summary)); + ioBlocks.setItems(IOAdvanced.getIOBlockList()); + ioBlocks.setItem(IOAdvanced.getCurrentBlock(requireActivity())); + ioBlocks.setOnItemSelected((selectView, position, item) -> { + if (!IOAdvanced.getCurrentBlock(requireActivity()).equals(IOAdvanced.getIOBlockList().get(position))) { + IOAdvanced.setCurrentBlock(position, requireActivity()); + reload(); + } + }); + + blocksCard.addItem(ioBlocks); + + if (IOAdvanced.hasScheduler(requireActivity()) && !IOAdvanced.getScheduler(requireActivity()).equals("")) { + SelectView scheduler = new SelectView(); + scheduler.setSummary(getString(R.string.scheduler)); + scheduler.setItems(IOAdvanced.getSchedulers(requireActivity())); + scheduler.setItem(IOAdvanced.getScheduler(requireActivity())); + scheduler.setOnItemSelected((selectView, position, item) -> { + mIOAdvanced.setScheduler(item, getActivity()); + getHandler().postDelayed(() -> scheduler.setItem(IOAdvanced.getScheduler(requireActivity())),500); + }); + + blocksCard.addItem(scheduler); + } + + if (IOAdvanced.hasReadAhead(requireActivity())) { + SeekBarView readahead = new SeekBarView(); + readahead.setSummary(getString(R.string.read_ahead)); + readahead.setUnit(getString(R.string.kb)); + readahead.setMax(8192); + readahead.setMin(64); + readahead.setOffset(64); + readahead.setProgress(IOAdvanced.getReadAhead(requireActivity()) / 64 - 1); + readahead.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + mIOAdvanced.setReadAhead((position + 1) * 64, getActivity()); + getHandler().postDelayed(() -> readahead.setProgress(IOAdvanced.getReadAhead(requireActivity()) / 64 - 1), + 500); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + blocksCard.addItem(readahead); + } + + if (IOAdvanced.hasRotational(requireActivity())) { + SwitchView rotational = new SwitchView(); + rotational.setSummary(getString(R.string.rotational)); + rotational.setChecked(IOAdvanced.isRotationalEnabled(requireActivity())); + rotational.addOnSwitchListener((switchView, isChecked) -> { + mIOAdvanced.enableRotational(isChecked, getActivity()); + getHandler().postDelayed(() -> rotational.setChecked(IOAdvanced.isRotationalEnabled(requireActivity())),500); + }); + + blocksCard.addItem(rotational); + } + + if (IOAdvanced.hasIOStats(requireActivity())) { + SwitchView iostats = new SwitchView(); + iostats.setSummary(getString(R.string.iostats)); + iostats.setChecked(IOAdvanced.isIOStatsEnabled(requireActivity())); + iostats.addOnSwitchListener((switchView, isChecked) -> { + mIOAdvanced.enableIOStats(isChecked, getActivity()); + getHandler().postDelayed(() -> iostats.setChecked(IOAdvanced.isIOStatsEnabled(requireActivity())),500); + }); + + blocksCard.addItem(iostats); + } + + if (IOAdvanced.hasRandom(requireActivity())) { + SwitchView addRandom = new SwitchView(); + addRandom.setSummary(getString(R.string.add_random)); + addRandom.setChecked(IOAdvanced.isRandomEnabled(requireActivity())); + addRandom.addOnSwitchListener((switchView, isChecked) -> { + mIOAdvanced.enableRandom(isChecked, getActivity()); + getHandler().postDelayed(() -> addRandom.setChecked(IOAdvanced.isRandomEnabled(requireActivity())),500); + }); + + blocksCard.addItem(addRandom); + } + + if (IOAdvanced.hasAffinity(requireActivity())) { + SeekBarView rqAffinity = new SeekBarView(); + rqAffinity.setSummary(getString(R.string.rq_affitiny)); + rqAffinity.setMax(2); + rqAffinity.setProgress(IOAdvanced.getAffinity(requireActivity())); + rqAffinity.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + mIOAdvanced.setAffinity(position, getActivity()); + getHandler().postDelayed(() -> rqAffinity.setProgress(IOAdvanced.getAffinity(requireActivity())),500); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + blocksCard.addItem(rqAffinity); + } + + if (IOAdvanced.hasNoMerges(requireActivity())) { + SeekBarView Nomerges = new SeekBarView(); + Nomerges.setSummary(getString(R.string.nomerges)); + Nomerges.setMax(2); + Nomerges.setProgress(IOAdvanced.getNoMerges(requireActivity())); + Nomerges.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() { + @Override + public void onStop(SeekBarView seekBarView, int position, String value) { + mIOAdvanced.setNoMerges(position, getActivity()); + getHandler().postDelayed(() -> Nomerges.setProgress(IOAdvanced.getNoMerges(requireActivity())),500); + } + + @Override + public void onMove(SeekBarView seekBarView, int position, String value) { + } + }); + + blocksCard.addItem(Nomerges); + } + + if (IOAdvanced.hasNRRequests(requireActivity())) { + GenericSelectView NrRequests = new GenericSelectView(); + NrRequests.setSummary(getString(R.string.nr_requests)); + NrRequests.setValue(IOAdvanced.getNRRequests(requireActivity())); + NrRequests.setValueRaw(NrRequests.getValue()); + NrRequests.setInputType(InputType.TYPE_CLASS_NUMBER); + NrRequests.setOnGenericValueListener((genericSelectView, value) -> { + mIOAdvanced.setNRRequests(value, getActivity()); + genericSelectView.setValue(value); + getHandler().postDelayed(() -> NrRequests.setValueRaw(NrRequests.getValue()),500); + }); + + blocksCard.addItem(NrRequests); + } + + items.add(blocksCard); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOFragment.java b/app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOFragment.java index 214909dbf..26396dfe4 100644 --- a/app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOFragment.java +++ b/app/src/main/java/com/smartpack/kernelmanager/fragments/kernel/IOFragment.java @@ -19,9 +19,11 @@ */ package com.smartpack.kernelmanager.fragments.kernel; +import android.content.Intent; import android.text.InputType; import com.smartpack.kernelmanager.R; +import com.smartpack.kernelmanager.activities.AdvancedIOActivity; import com.smartpack.kernelmanager.fragments.ApplyOnBootFragment; import com.smartpack.kernelmanager.fragments.BaseFragment; import com.smartpack.kernelmanager.fragments.RecyclerViewFragment; @@ -59,6 +61,19 @@ protected void init() { @Override protected void addItems(List items) { + CardView advCard = new CardView(getActivity()); + advCard.setTitle(getString(R.string.adv_sett)); + + DescriptionView advancedIO = new DescriptionView(); + advancedIO.setSummary(getString(R.string.io_blocks_summary)); + advancedIO.setOnItemClickListener(item -> { + Intent intent = new Intent(getActivity(), AdvancedIOActivity.class); + startActivity(intent); + }); + + advCard.addItem(advancedIO); + items.add(advCard); + storageInit(IO.Storage.Internal, items); if (mIO.hasExternal()) { storageInit(IO.Storage.External, items); diff --git a/app/src/main/java/com/smartpack/kernelmanager/utils/kernel/io/IOAdvanced.java b/app/src/main/java/com/smartpack/kernelmanager/utils/kernel/io/IOAdvanced.java new file mode 100644 index 000000000..460163d9b --- /dev/null +++ b/app/src/main/java/com/smartpack/kernelmanager/utils/kernel/io/IOAdvanced.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2021-2022 sunilpaulmathew + * + * This file is part of SmartPack Kernel Manager, which is a heavily modified version of Kernel Adiutor, + * originally developed by Willi Ye + * + * Both SmartPack Kernel Manager & Kernel Adiutor are free softwares: you can redistribute it + * and/or modify it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * SmartPack Kernel Manager is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with SmartPack Kernel Manager. If not, see . + * + */ + +package com.smartpack.kernelmanager.utils.kernel.io; + +import android.content.Context; + +import com.smartpack.kernelmanager.fragments.ApplyOnBootFragment; +import com.smartpack.kernelmanager.utils.Prefs; +import com.smartpack.kernelmanager.utils.Utils; +import com.smartpack.kernelmanager.utils.root.Control; +import com.smartpack.kernelmanager.utils.root.RootFile; + +import java.util.ArrayList; +import java.util.List; + +/* + * Created by sunilpaulmathew on April 14, 2021 + */ +public class IOAdvanced { + + private static IOAdvanced sInstance; + + public static IOAdvanced getInstance() { + if (sInstance == null) { + sInstance = new IOAdvanced(); + } + return sInstance; + } + + private static final String IO_PARENT = "/sys/block"; + private static final String SCHEDULER = "scheduler"; + private static final String IOSCHED = "iosched"; + private static final String READ_AHEAD = "read_ahead_kb"; + private static final String ROTATIONAL = "rotational"; + private static final String IOSTATS = "iostats"; + private static final String ADD_RANDOM = "add_random"; + private static final String RQ_AFFINITY = "rq_affinity"; + private static final String NOMERGES = "nomerges"; + private static final String NR_REQUESTS = "nr_requests"; + + public static List getIOBlockList() { + List mTQLList = new ArrayList<>(); + for (String string : new RootFile(IO_PARENT).list()) { + if (Utils.existFile(IO_PARENT + "/" + string + "/queue")) { + mTQLList.add(string); + } + } + return mTQLList; + } + + public static String getCurrentBlock(Context context) { + return Prefs.getString("mCurrentBlock", getIOBlockList().get(0), context); + } + + public static void setCurrentBlock(int position, Context context) { + Prefs.saveString("mCurrentBlock", getIOBlockList().get(position), context); + } + + public static boolean hasScheduler(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + SCHEDULER); + } + + public static String getScheduler(Context context) { + String[] schedulers = Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + SCHEDULER).split(" "); + for (String scheduler : schedulers) { + if (scheduler.startsWith("[") && scheduler.endsWith("]")) { + return scheduler.replace("[", "").replace("]", ""); + } + } + return ""; + } + + public static List getSchedulers(Context context) { + String[] schedulers = Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + SCHEDULER).split(" "); + List list = new ArrayList<>(); + for (String scheduler : schedulers) { + list.add(scheduler.replace("[", "").replace("]", "")); + } + return list; + } + + public void setScheduler(String value, Context context) { + run(Control.write(value, IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + SCHEDULER), IO_PARENT + "/" + + getCurrentBlock(context) + "/queue/" + SCHEDULER, context); + } + + public static boolean hasReadAhead(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + READ_AHEAD); + } + + public static int getReadAhead(Context context) { + return Utils.strToInt(Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + READ_AHEAD)); + } + + public void setReadAhead(int value, Context context) { + run(Control.write(String.valueOf(value), IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + READ_AHEAD), + IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + READ_AHEAD, context); + } + + public static boolean hasRotational(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ROTATIONAL); + } + + public static boolean isRotationalEnabled(Context context) { + return Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ROTATIONAL).equals("1"); + } + + public void enableRotational(boolean enable, Context context) { + run(Control.write(enable ? "1" : "0", IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ROTATIONAL), + IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ROTATIONAL, context); + } + + public static boolean hasIOStats(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + IOSTATS); + } + + public static boolean isIOStatsEnabled(Context context) { + return Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + IOSTATS).equals("1"); + } + + public void enableIOStats(boolean enable, Context context) { + run(Control.write(enable ? "1" : "0", IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + IOSTATS), + IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + IOSTATS, context); + } + + public static boolean hasRandom(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ADD_RANDOM); + } + + public static boolean isRandomEnabled(Context context) { + return Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ADD_RANDOM).equals("1"); + } + + public void enableRandom(boolean enable, Context context) { + run(Control.write(enable ? "1" : "0", IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ADD_RANDOM), + IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + ADD_RANDOM, context); + } + + public static boolean hasAffinity(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + RQ_AFFINITY); + } + + public static int getAffinity(Context context) { + return Utils.strToInt(Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + RQ_AFFINITY)); + } + + public void setAffinity(int value, Context context) { + run(Control.write(String.valueOf(value), IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + RQ_AFFINITY), + IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + RQ_AFFINITY, context); + } + + public static boolean hasNoMerges(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NOMERGES); + } + + public static int getNoMerges(Context context) { + return Utils.strToInt(Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NOMERGES)); + } + + public void setNoMerges(int value, Context context) { + run(Control.write(String.valueOf(value), IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NOMERGES), + IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NOMERGES, context); + } + + public static boolean hasNRRequests(Context context) { + return Utils.existFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NR_REQUESTS); + } + + public static String getNRRequests(Context context) { + return Utils.readFile(IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NR_REQUESTS); + } + + public void setNRRequests(String value, Context context) { + run(Control.write(value, IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NR_REQUESTS), + IO_PARENT + "/" + getCurrentBlock(context) + "/queue/" + NR_REQUESTS, context); + } + + private void run(String command, String id, Context context) { + Control.runSetting(command, ApplyOnBootFragment.IO_ADVANCED, id, context); + } + +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2200e2eb4..8475c6cfd 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -718,6 +718,12 @@ NR Requests This controls how many requests may be allocated in the block layer for read or write requests. + + I/O Blocks (%s) + Click here to fine-tune various I/O blocks on your device! However, please be aware that some parameters are read-only and not allowed to change on some blocks. + Select I/O Block + Select the preferred I/O Block for fine-tuning. + Full scans Pages shared