diff --git a/CHANGELOG.md b/CHANGELOG.md index 5743996..14f64d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## Version 1.1.0 *(2017-09-01)* + +* Android O support (Note: CpuUsageModule/CpuFreqModule will not work on Android O and above) +* Add a CpuFreqModule to show current/max frequencies of all the cpu cores +* Support Library 25.3.1 -> 26.0.1 + ## Version 1.0.1 *(2017-04-05)* * Use split v4 support library as dependencies for less size diff --git a/README.md b/README.md index 0d135e4..db33736 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,13 @@ so you just need to add the followings to your ***build.gradle*** file: ```groovy dependencies { - debugCompile 'com.ms-square:debugoverlay:1.0.1' - releaseCompile 'com.ms-square:debugoverlay-no-op:1.0.1' - testCompile 'com.ms-square:debugoverlay-no-op:1.0.1' + debugCompile 'com.ms-square:debugoverlay:1.1.0' + releaseCompile 'com.ms-square:debugoverlay-no-op:1.1.0' + testCompile 'com.ms-square:debugoverlay-no-op:1.1.0' } ``` -Please note that `com.ms-square:debugoverlay:1.0.1` will add `android.permission.SYSTEM_ALERT_WINDOW` to your app. +Please note that `com.ms-square:debugoverlay:1.1.0` will add `android.permission.SYSTEM_ALERT_WINDOW` to your app. Threfore, you should avoid to use that dependency for your release build. FYI, the following table describes the total number of method/field references in this library's release aar. @@ -37,11 +37,11 @@ This data is acquired by using [Dexcount Gradle Plugin](https://github.com/KeepS | library | methods | fields | |:------------- |:-------------|:-------------| -|com.ms-square:debugoverlay:1.0.1|515|227| -|com.ms-square:debugoverlay-no-op:1.0.1|127|36| +|com.ms-square:debugoverlay:1.1.0|565|249| +|com.ms-square:debugoverlay-no-op:1.1.0|142|37| Due to the extensibility of this library, no-op version unfortunately has more than a few methods. -If you want to eliminate such method count in your release build, consider having separate `Application` class only for your debug build which uses this library and just specify `debugCompile 'com.ms-square:debugoverlay:1.0.1'` in the dependencies section of build.gradle. +If you want to eliminate such method count in your release build, consider having separate `Application` class only for your debug build which uses this library and just specify `debugCompile 'com.ms-square:debugoverlay:1.1.0'` in the dependencies section of build.gradle. Usage ------ @@ -62,7 +62,7 @@ public class ExampleApplication extends Application { ``` It will show a debug overlay on system layer with the follwing three default modules just like the gif animation image displayed on this README. -- [CpuUsageModule](#cpuusagemodule) +- [CpuUsageModule](#cpuusagemodule) - will not be shown on Android O and above - [MemInfoModule](#meminfomodule) - [FpsModule](#fpsmodule) @@ -125,6 +125,8 @@ Provided Modules `default` > Collects total and app cpu usage % by reading `/proc/stat` and `/proc/[myPid]/stat` respectively. +Note: CpuUsageModule will be no-op on Android O and above. Please see this [issue](https://github.com/Manabu-GT/DebugOverlay-Android/issues/11) for why. + #### MemInfoModule `default` @@ -142,6 +144,12 @@ If low memory situation is detected by reading [lowMemory](https://developer.and `optional` > Collects logcat messages generated by your own app even on non-rooted devices. +#### CpuFreqModule +`optional` +> Collects each cpu core's current and max frequency by reading `/sys/devices/system/cpu/cpu[num]/cpufreq/scaling_cur_freq` and `/sys/devices/system/cpu/cpu[num]/cpufreq/cpuinfo_max_freq` respectively. + +Note: CpuFreqModule will be no-op on Android O and above. Please see this [issue](https://github.com/Manabu-GT/DebugOverlay-Android/issues/11) for why. + Customization ------ @@ -198,7 +206,7 @@ Example: module = new CpuUsageModule(new MyCpuViewModule()); ``` -For **CpuUsage, MemInfo, and Fps modules**, you can pass your own layout resource id as long as it contains TextView as a direct child with id set to `debugoverlay_overlay_text` which is already defined in this library. This allows you to style the TextView used within those modules very easily without fully implementing new [ViewModule][5] by yourself. +For **CpuUsage, CpuFreq, MemInfo, and Fps modules**, you can pass your own layout resource id as long as it contains TextView as a direct child with id set to `debugoverlay_overlay_text` which is already defined in this library. This allows you to style the TextView used within those modules very easily without fully implementing new [ViewModule][5] by yourself. ### Adding your own overlay module @@ -254,7 +262,8 @@ Since a new custom module called `IPAddressModule` is created, let's actually sh ```java // inside Application's onCreate() new DebugOverlay.Builder(this) - .modules(new CpuUsageModule(), + .modules(new CpuFreqModule(), + new CpuUsageModule(), new MemInfoModule(this), new FpsModule(), new IPAddressModule(this)) @@ -264,7 +273,7 @@ new DebugOverlay.Builder(this) Now, the overlay successfully shows the newly added custom module at the bottom. -DebugOverlay Screen Capture +DebugOverlay Screen Capture Thanks for reading! diff --git a/art/overlay_with_custom_module_and_cpufreq_small.png b/art/overlay_with_custom_module_and_cpufreq_small.png new file mode 100644 index 0000000..3dd0df8 Binary files /dev/null and b/art/overlay_with_custom_module_and_cpufreq_small.png differ diff --git a/build.gradle b/build.gradle index 9b9f3b2..f595f8f 100644 --- a/build.gradle +++ b/build.gradle @@ -5,17 +5,20 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.0' + classpath 'com.android.tools.build:gradle:2.3.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files - classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.6.3' + classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.7.3' } } allprojects { repositories { jcenter() + maven { + url "https://maven.google.com" + } } } diff --git a/debugoverlay-no-op/build.gradle b/debugoverlay-no-op/build.gradle index 1f32e28..b525f63 100644 --- a/debugoverlay-no-op/build.gradle +++ b/debugoverlay-no-op/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'com.android.library' apply plugin: 'com.getkeepsafe.dexcount' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 26 + buildToolsVersion "26.0.1" defaultConfig { minSdkVersion 16 - targetSdkVersion 25 + targetSdkVersion 26 } // force usage of prefix to avoid naming conflicts, diff --git a/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreq.java b/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreq.java new file mode 100644 index 0000000..6c5f489 --- /dev/null +++ b/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreq.java @@ -0,0 +1,23 @@ +package com.ms_square.debugoverlay.modules; + +public class CpuFreq { + + public CpuFreq(String cpuName, double minFreq, double curFreq, double maxFreq) { + } + + public String getCpuName() { + return null; + } + + public double getMinFreq() { + return 0f; + } + + public double getCurFreq() { + return 0f; + } + + public double getMaxFreq() { + return 0f; + } +} diff --git a/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqModule.java b/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqModule.java new file mode 100644 index 0000000..57d9b4a --- /dev/null +++ b/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqModule.java @@ -0,0 +1,31 @@ +package com.ms_square.debugoverlay.modules; + +import com.ms_square.debugoverlay.OverlayModule; +import com.ms_square.debugoverlay.ViewModule; + +import java.util.List; + +public class CpuFreqModule extends OverlayModule> { + + public static final int DEFAULT_INTERVAL = 2000; // 2000ms + + public CpuFreqModule() { + super(null, null); + } + + public CpuFreqModule(int interval) { + super(null, null); + } + + public CpuFreqModule(int interval, int layoutResId) { + super(null, null); + } + + public CpuFreqModule(ViewModule> viewModule) { + super(null, null); + } + + public CpuFreqModule(int interval, ViewModule> viewModule) { + super(null, null); + } +} diff --git a/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqViewModule.java b/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqViewModule.java new file mode 100644 index 0000000..d2c368c --- /dev/null +++ b/debugoverlay-no-op/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqViewModule.java @@ -0,0 +1,26 @@ +package com.ms_square.debugoverlay.modules; + +import android.view.View; +import android.view.ViewGroup; + +import java.util.List; + +public class CpuFreqViewModule extends BaseViewModule> { + + public CpuFreqViewModule() { + super(0); + } + + public CpuFreqViewModule(int layoutResId) { + super(layoutResId); + } + + @Override + public void onDataAvailable(List cpuFreqList) { + } + + @Override + public View createView(ViewGroup root, int textColor, float textSize, float textAlpha) { + return null; + } +} diff --git a/debugoverlay-no-op/src/test/java/com/ms_square/debugoverlay/DebugOverlayNoOpTest.java b/debugoverlay-no-op/src/test/java/com/ms_square/debugoverlay/DebugOverlayNoOpTest.java index a409dcb..ebd941e 100644 --- a/debugoverlay-no-op/src/test/java/com/ms_square/debugoverlay/DebugOverlayNoOpTest.java +++ b/debugoverlay-no-op/src/test/java/com/ms_square/debugoverlay/DebugOverlayNoOpTest.java @@ -3,6 +3,7 @@ import android.app.Application; import android.graphics.Color; +import com.ms_square.debugoverlay.modules.CpuFreqModule; import com.ms_square.debugoverlay.modules.CpuUsageModule; import com.ms_square.debugoverlay.modules.FpsModule; import com.ms_square.debugoverlay.modules.LogcatLine; @@ -38,7 +39,7 @@ public class DebugOverlayNoOpTest { OverlayModule mockOverlayModule; @Test - public void cpuModuleConstructors() { + public void cpuUsageModuleConstructors() { new CpuUsageModule(); new CpuUsageModule(0); new CpuUsageModule(0, 0); @@ -48,6 +49,17 @@ public void cpuModuleConstructors() { Mockito.verifyZeroInteractions(mockViewModule); } + @Test + public void cpuFreqModuleConstructors() { + new CpuFreqModule(); + new CpuFreqModule(0); + new CpuFreqModule(0, 0); + new CpuFreqModule(mockViewModule); + new CpuFreqModule(0, mockViewModule); + + Mockito.verifyZeroInteractions(mockViewModule); + } + @Test public void fpsModuleConstructors() { new FpsModule(); diff --git a/debugoverlay/build.gradle b/debugoverlay/build.gradle index dd533d7..c708b59 100644 --- a/debugoverlay/build.gradle +++ b/debugoverlay/build.gradle @@ -3,12 +3,12 @@ apply plugin: 'com.android.library' apply plugin: 'com.getkeepsafe.dexcount' android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 26 + buildToolsVersion "26.0.1" defaultConfig { minSdkVersion 16 - targetSdkVersion 25 + targetSdkVersion 26 } // force usage of prefix to avoid naming conflicts @@ -29,9 +29,9 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:support-compat:25.3.1' - compile 'com.android.support:support-core-utils:25.3.1' - compile 'com.android.support:support-annotations:25.3.1' + compile 'com.android.support:support-compat:26.0.1' + compile 'com.android.support:support-core-utils:26.0.1' + compile 'com.android.support:support-annotations:26.0.1' } // for maven central deployment diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlay.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlay.java index 23dd705..6154138 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlay.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlay.java @@ -9,6 +9,7 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.graphics.Color; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.Parcel; @@ -21,18 +22,20 @@ import android.support.v4.content.LocalBroadcastManager; import android.util.Log; +import com.ms_square.debugoverlay.modules.CpuFreqModule; import com.ms_square.debugoverlay.modules.CpuUsageModule; import com.ms_square.debugoverlay.modules.FpsModule; import com.ms_square.debugoverlay.modules.MemInfoModule; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.WeakHashMap; public class DebugOverlay { - private static final String TAG = DebugOverlay.class.getSimpleName(); + private static final String TAG = "DebugOverlay"; public static final Position DEFAULT_POSITION = Position.BOTTOM_START; public static final int DEFAULT_BG_COLOR = Color.parseColor("#40000000"); @@ -302,6 +305,18 @@ public DebugOverlay build() { overlayModules.add(new MemInfoModule(application)); overlayModules.add(new FpsModule()); } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // Removes any CpuUsageModule/CpuFreqModule if a device is running Android O and above + Iterator iterator = overlayModules.iterator(); + while (iterator.hasNext()) { + OverlayModule overlayModule = iterator.next(); + if (overlayModule instanceof CpuUsageModule || overlayModule instanceof CpuFreqModule) { + iterator.remove(); + } + } + } + return new DebugOverlay(application, overlayModules, new Config(position, bgColor, textColor, textSize, textAlpha, allowSystemLayer, showNotification, activityName)); diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlayService.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlayService.java index c4c3227..055d07f 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlayService.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/DebugOverlayService.java @@ -1,5 +1,6 @@ package com.ms_square.debugoverlay; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; @@ -13,6 +14,7 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Binder; +import android.os.Build; import android.os.IBinder; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -25,9 +27,10 @@ public class DebugOverlayService extends Service { - private static final String TAG = DebugOverlayService.class.getSimpleName(); + private static final String TAG = "DebugOverlayService"; - private static final int NOTIFICATION_ID = 10000; + private static final String NOTIFICATION_CHANNEL_ID = "com.ms_square.debugoverlay"; + private static final int NOTIFICATION_ID = Integer.MAX_VALUE - 100; private static final String ACTION_SHOW_SUFFIX = ".debugoverlay_ACTION_SHOW"; private static final String ACTION_HIDE_SUFFIX = ".debugoverlay_ACTION_HIDE"; @@ -65,6 +68,8 @@ public void onCreate() { } notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + createNotificationChannel(); + String packageName = getPackageName(); actionShow = packageName + ACTION_SHOW_SUFFIX; actionHide = packageName + ACTION_HIDE_SUFFIX; @@ -156,8 +161,18 @@ public void updateNotification() { showNotification(); } + private void createNotificationChannel() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (notificationManager.getNotificationChannel(NOTIFICATION_CHANNEL_ID) == null) { + NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, + getString(R.string.debugoverlay_notification_channel_name), NotificationManager.IMPORTANCE_LOW); + notificationManager.createNotificationChannel(channel); + } + } + } + private void showNotification() { - NotificationCompat.Builder builder = new NotificationCompat.Builder(this) + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) .setStyle(new NotificationCompat.BigTextStyle().bigText(getString(R.string.debugoverlay_notification_big_text))) .setSmallIcon(R.drawable.debugoverlay_ic_notification) .setLargeIcon(getAppIcon(this)) diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/OverlayViewManager.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/OverlayViewManager.java index 4e29f3e..f8900db 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/OverlayViewManager.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/OverlayViewManager.java @@ -26,12 +26,13 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; class OverlayViewManager { - private static final String TAG = OverlayViewManager.class.getSimpleName(); + private static final String TAG = "OverlayViewManager"; private final Context context; private final DebugOverlay.Config config; @@ -237,7 +238,9 @@ public static boolean isSystemLayer(int windowType) { public static int getWindowTypeForOverlay(boolean allowSystemLayer) { if (allowSystemLayer) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + return TYPE_APPLICATION_OVERLAY; + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { return TYPE_SYSTEM_ALERT; } else { return TYPE_TOAST; diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreq.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreq.java new file mode 100644 index 0000000..68207df --- /dev/null +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreq.java @@ -0,0 +1,46 @@ +package com.ms_square.debugoverlay.modules; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +public class CpuFreq { + + private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00", + DecimalFormatSymbols.getInstance(Locale.ENGLISH)); + + private final String cpuName; + private final double minFreq; + private final double curFreq; + private final double maxFreq; + + public CpuFreq(String cpuName, double minFreq, double curFreq, double maxFreq) { + this.cpuName = cpuName; + this.minFreq = minFreq; + this.curFreq = curFreq; + this.maxFreq = maxFreq; + } + + public String getCpuName() { + return cpuName; + } + + public double getMinFreq() { + return minFreq; + } + + public double getCurFreq() { + return curFreq; + } + + public double getMaxFreq() { + return maxFreq; + } + + @Override + public String toString() { + return String.format(Locale.US, "%s(GHz): %s/%s ", cpuName, + curFreq >= 0 ? DECIMAL_FORMAT.format(curFreq / 1000000f) : "NA", + maxFreq >= 0 ? DECIMAL_FORMAT.format(maxFreq / 1000000f) : "NA"); + } +} diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqDataModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqDataModule.java new file mode 100644 index 0000000..0d8b2be --- /dev/null +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqDataModule.java @@ -0,0 +1,158 @@ +package com.ms_square.debugoverlay.modules; + +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import com.ms_square.debugoverlay.DebugOverlay; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Pattern; + +import static java.lang.Double.parseDouble; + +class CpuFreqDataModule extends BaseDataModule> { + + private static final String TAG = "CpuFreqDataModule"; + + private final Handler handler = new Handler(Looper.getMainLooper()); + + private final AtomicReference> cpuFreqList = new AtomicReference<>(); + + private final Runnable notifyObserversRunnable = new Runnable() { + @Override + public void run() { + notifyObservers(); + } + }; + + /** + * The cpufreq values are given in kHz. + * https://www.kernel.org/doc/Documentation/cpu-freq/user-guide.txt + */ + private final Runnable cpuFreqReadRunnable = new Runnable() { + + Map cachedFrequencies = new LinkedHashMap<>(); + + @Override + public void run() { + if (cachedFrequencies.isEmpty()) { + File[] cpuFiles = getCpuFiles(); + if (cpuFiles != null) { + for (File cpuFile : cpuFiles) { + double minFreq = -1f; + double maxFreq = -1f; + try { + BufferedReader minFreqReader = + new BufferedReader(new FileReader(cpuFile.getAbsolutePath() + "/cpufreq/cpuinfo_min_freq")); + BufferedReader maxFreqReader = + new BufferedReader(new FileReader(cpuFile.getAbsolutePath() + "/cpufreq/cpuinfo_max_freq")); + minFreq = parseDouble(minFreqReader.readLine()); + maxFreq = parseDouble(maxFreqReader.readLine()); + + if (DebugOverlay.isDebugLoggingEnabled()) { + Log.d(TAG, cpuFile.getName() + " minFreq(kHz):" + minFreq); + Log.d(TAG, cpuFile.getName() + " maxFreq(kHz):" + maxFreq); + } + } catch (IOException ie) { + Log.w(TAG, "Error reading the min/max cpufreq", ie); + } + cachedFrequencies.put(cpuFile, new CpuFreq(cpuFile.getName(), minFreq, -1f, maxFreq)); + } + } + } + + List newCpuFreqList = new ArrayList<>(); + + for (File cpuFile : cachedFrequencies.keySet()) { + CpuFreq cached = cachedFrequencies.get(cpuFile); + double curFreq = -1f; + try { + BufferedReader curFreqReader = new BufferedReader(new FileReader(cpuFile.getAbsolutePath() + "/cpufreq/scaling_cur_freq")); + curFreq = parseDouble(curFreqReader.readLine()); + + if (DebugOverlay.isDebugLoggingEnabled()) { + Log.d(TAG, cpuFile.getName() + " curFreq(kHz):" + curFreq); + } + + } catch (IOException ie) { + Log.w(TAG, "Error reading the current cpufreq", ie); + } + + newCpuFreqList.add(new CpuFreq(cached.getCpuName(), cached.getMinFreq(), curFreq, cached.getMaxFreq())); + } + + cpuFreqList.set(Collections.unmodifiableList(newCpuFreqList)); + + handler.post(notifyObserversRunnable); + } + }; + + private ScheduledExecutorService executorService; + + public CpuFreqDataModule(int interval) { + super(interval); + } + + @Override + public void start() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Log.w(TAG, "CpuFreqDataModule is not supported on Android O and above and will be no-op."); + return; + } + if (executorService == null) { + executorService = Executors.newSingleThreadScheduledExecutor(); + executorService.scheduleWithFixedDelay(cpuFreqReadRunnable, 0, getInterval(), TimeUnit.MILLISECONDS); + } + } + + @Override + public void stop() { + handler.removeCallbacks(notifyObserversRunnable); + if (executorService != null) { + executorService.shutdown(); + try { + if (!executorService.awaitTermination(1000, TimeUnit.MILLISECONDS)) { + Log.w(TAG, "ExecutorService did not terminate"); + } + } catch (InterruptedException ie) { + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + executorService = null; + } + } + + @Override + protected List getLatestData() { + return cpuFreqList.get(); + } + + private static File[] getCpuFiles() { + File dir = new File("/sys/devices/system/cpu/"); + File[] files = dir.listFiles(new FileFilter() { + @Override + public boolean accept(File file) { + if(Pattern.matches("cpu[0-9]+", file.getName())) { + return true; + } + return false; + } + }); + return files; + } +} diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqModule.java new file mode 100644 index 0000000..3511d81 --- /dev/null +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqModule.java @@ -0,0 +1,39 @@ +package com.ms_square.debugoverlay.modules; + +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; + +import com.ms_square.debugoverlay.OverlayModule; +import com.ms_square.debugoverlay.ViewModule; + +import java.util.List; + +/** + * @deprecated will not work on Android O and above. + * @see this issue for its background. + */ +@Deprecated +public class CpuFreqModule extends OverlayModule> { + + public static final int DEFAULT_INTERVAL = 2000; // 2000ms + + public CpuFreqModule() { + super(new CpuFreqDataModule(DEFAULT_INTERVAL), new CpuFreqViewModule()); + } + + public CpuFreqModule(int interval) { + super(new CpuFreqDataModule(interval), new CpuFreqViewModule()); + } + + public CpuFreqModule(int interval, @LayoutRes int layoutResId) { + super(new CpuFreqDataModule(interval), new CpuFreqViewModule(layoutResId)); + } + + public CpuFreqModule(@NonNull ViewModule> viewModule) { + super(new CpuFreqDataModule(DEFAULT_INTERVAL), viewModule); + } + + public CpuFreqModule(int interval, @NonNull ViewModule> viewModule) { + super(new CpuFreqDataModule(interval), viewModule); + } +} diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqViewModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqViewModule.java new file mode 100644 index 0000000..7ccfc96 --- /dev/null +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuFreqViewModule.java @@ -0,0 +1,51 @@ +package com.ms_square.debugoverlay.modules; + +import android.support.annotation.ColorInt; +import android.support.annotation.LayoutRes; +import android.support.annotation.NonNull; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.ms_square.debugoverlay.R; + +import java.util.List; + +public class CpuFreqViewModule extends BaseViewModule> { + + private TextView cpuFreqTextView; + + public CpuFreqViewModule() { + super(R.layout.debugoverlay_cpu_freq); + } + + public CpuFreqViewModule(@LayoutRes int layoutResId) { + super(layoutResId); + } + + @Override + public void onDataAvailable(List cpuFreqList) { + if (cpuFreqList != null && cpuFreqTextView != null) { + StringBuilder builder = new StringBuilder(); + for (CpuFreq cpuFreq : cpuFreqList) { + if (builder.length() > 0) { + builder.append("\n"); + } + builder.append(cpuFreq.toString()); + } + cpuFreqTextView.setText(builder.toString()); + } + } + + @NonNull + @Override + public View createView(@NonNull ViewGroup root, @ColorInt int textColor, float textSize, float textAlpha) { + View view = LayoutInflater.from(root.getContext()).inflate(layoutResId, root, false); + cpuFreqTextView = view.findViewById(R.id.debugoverlay_overlay_text); + cpuFreqTextView.setTextColor(textColor); + cpuFreqTextView.setTextSize(textSize); + cpuFreqTextView.setAlpha(textAlpha); + return view; + } +} diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageDataModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageDataModule.java index 97c9495..4006a09 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageDataModule.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageDataModule.java @@ -1,5 +1,6 @@ package com.ms_square.debugoverlay.modules; +import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Process; @@ -13,7 +14,7 @@ class CpuUsageDataModule extends BaseDataModule { - private static final String TAG = CpuUsageDataModule.class.getSimpleName(); + private static final String TAG = "CpuUsageDataModule"; private final Handler handler = new Handler(Looper.getMainLooper()); @@ -27,6 +28,10 @@ public CpuUsageDataModule(int interval) { @Override public void start() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Log.w(TAG, "CpuUsageModule is not supported on Android O and above and will be no-op."); + return; + } if (cpuReaderThread == null) { cpuReaderThread = new ReaderThread(); cpuReaderThread.start(); diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageModule.java index 5f5edf5..d29f0a2 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageModule.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageModule.java @@ -6,6 +6,11 @@ import com.ms_square.debugoverlay.OverlayModule; import com.ms_square.debugoverlay.ViewModule; +/** + * @deprecated will not work on Android O and above. + * For details, @see this issue + */ +@Deprecated public class CpuUsageModule extends OverlayModule { public static final int DEFAULT_INTERVAL = 1000; // 1000ms diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageViewModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageViewModule.java index 68d6460..1869e72 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageViewModule.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/CpuUsageViewModule.java @@ -17,7 +17,7 @@ public class CpuUsageViewModule extends BaseViewModule { - private static final String TAG = CpuUsageViewModule.class.getSimpleName(); + private static final String TAG = "CpuUsageViewModule"; private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.0", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); @@ -44,7 +44,7 @@ public void onDataAvailable(CpuUsage data) { } if (cpuUsageTextView != null) { - StringBuilder builder = new StringBuilder("cpu: "); + StringBuilder builder = new StringBuilder("cpu(%): "); cpuUsageTextView.setText(builder.append(totalCpuUsage).append(" ").append(myPidCpuUsage).toString()); } } @@ -53,7 +53,7 @@ public void onDataAvailable(CpuUsage data) { @Override public View createView(ViewGroup root, @ColorInt int textColor, float textSize, float textAlpha) { View view = LayoutInflater.from(root.getContext()).inflate(layoutResId, root, false); - cpuUsageTextView = (TextView) view.findViewById(R.id.debugoverlay_overlay_text); + cpuUsageTextView = view.findViewById(R.id.debugoverlay_overlay_text); cpuUsageTextView.setTextColor(textColor); cpuUsageTextView.setTextSize(textSize); cpuUsageTextView.setAlpha(textAlpha); diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/FpsViewModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/FpsViewModule.java index e29fd69..8d795d2 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/FpsViewModule.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/FpsViewModule.java @@ -38,7 +38,7 @@ public void onDataAvailable(Double data) { @Override public View createView(ViewGroup root, @ColorInt int textColor, float textSize, float textAlpha) { View view = LayoutInflater.from(root.getContext()).inflate(layoutResId, root, false); - fpsTxtView = (TextView) view.findViewById(R.id.debugoverlay_overlay_text); + fpsTxtView = view.findViewById(R.id.debugoverlay_overlay_text); fpsTxtView.setTextColor(textColor); fpsTxtView.setTextSize(textSize); fpsTxtView.setAlpha(textAlpha); diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatDataModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatDataModule.java index 7ad7948..7e5f3f5 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatDataModule.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatDataModule.java @@ -13,7 +13,7 @@ class LogcatDataModule extends BaseDataModule { - private static final String TAG = LogcatDataModule.class.getSimpleName(); + private static final String TAG = "LogcatDataModule"; private static final int LINE_UPDATED = 10000; diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatLine.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatLine.java index 0db58b3..cf8387e 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatLine.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatLine.java @@ -11,7 +11,7 @@ */ public class LogcatLine { - private static final String TAG = LogcatLine.class.getSimpleName(); + private static final String TAG = "LogcatLine"; public enum Priority { diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatViewModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatViewModule.java index 6ea7f7e..8bf24b3 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatViewModule.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/LogcatViewModule.java @@ -20,7 +20,7 @@ public class LogcatViewModule extends BaseViewModule { - private static final String TAG = LogcatViewModule.class.getSimpleName(); + private static final String TAG = "LogcatViewModule"; private final int maxLines; @@ -126,9 +126,9 @@ public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.debugoverlay_line_logcat, parent, false); - TextView dateAndTime = (TextView) convertView.findViewById(R.id.date_and_time); - TextView priorityAndTag = (TextView) convertView.findViewById(R.id.priority_and_tag); - TextView message = (TextView) convertView.findViewById(R.id.message); + TextView dateAndTime = convertView.findViewById(R.id.date_and_time); + TextView priorityAndTag = convertView.findViewById(R.id.priority_and_tag); + TextView message = convertView.findViewById(R.id.message); dateAndTime.setTextColor(textColor); diff --git a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/MemInfoViewModule.java b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/MemInfoViewModule.java index 23264a3..e7c5105 100644 --- a/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/MemInfoViewModule.java +++ b/debugoverlay/src/main/java/com/ms_square/debugoverlay/modules/MemInfoViewModule.java @@ -22,7 +22,7 @@ public class MemInfoViewModule extends BaseViewModule { - private static final String TAG = MemInfoViewModule.class.getSimpleName(); + private static final String TAG = "MemInfoViewModule"; private static final String HEADER = "memory(mb):\n"; @@ -74,7 +74,7 @@ public void onDataAvailable(MemInfo data) { @Override public View createView(ViewGroup root, @ColorInt int textColor, float textSize, float textAlpha) { View view = LayoutInflater.from(root.getContext()).inflate(layoutResId, root, false); - memInfoTxtView = (TextView) view.findViewById(R.id.debugoverlay_overlay_text); + memInfoTxtView = view.findViewById(R.id.debugoverlay_overlay_text); memInfoTxtView.setTextColor(textColor); memInfoTxtView.setTextSize(textSize); memInfoTxtView.setAlpha(textAlpha); diff --git a/debugoverlay/src/main/res/layout/debugoverlay_cpu_freq.xml b/debugoverlay/src/main/res/layout/debugoverlay_cpu_freq.xml new file mode 100644 index 0000000..a0b31bd --- /dev/null +++ b/debugoverlay/src/main/res/layout/debugoverlay_cpu_freq.xml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/debugoverlay/src/main/res/layout/debugoverlay_cpu_usage.xml b/debugoverlay/src/main/res/layout/debugoverlay_cpu_usage.xml index 59171c9..80166a1 100644 --- a/debugoverlay/src/main/res/layout/debugoverlay_cpu_usage.xml +++ b/debugoverlay/src/main/res/layout/debugoverlay_cpu_usage.xml @@ -2,6 +2,7 @@ \ No newline at end of file diff --git a/debugoverlay/src/main/res/values/strings.xml b/debugoverlay/src/main/res/values/strings.xml index c5692b2..72b9606 100644 --- a/debugoverlay/src/main/res/values/strings.xml +++ b/debugoverlay/src/main/res/values/strings.xml @@ -1,6 +1,7 @@ + DebugOverlay %1$s:%2$s Control DebugOverlay Control DebugOverlay diff --git a/gradle.properties b/gradle.properties index 93eb6a2..9d5d97b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,8 +26,8 @@ android.enableBuildCache=true # For maven central GROUP=com.ms-square -VERSION_NAME=1.0.1 -VERSION_CODE=2 +VERSION_NAME=1.1.0 +VERSION_CODE=3 POM_PACKAGING=aar POM_DESCRIPTION=Android library to display various debugging information in an overlay window diff --git a/sample/build.gradle b/sample/build.gradle index 5327112..47f160c 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -14,12 +14,12 @@ def gitHash() { } android { - compileSdkVersion 25 - buildToolsVersion "25.0.2" + compileSdkVersion 26 + buildToolsVersion "26.0.1" defaultConfig { applicationId "com.ms_square.debugoverlay.sample" minSdkVersion 16 - targetSdkVersion 25 + targetSdkVersion 26 versionCode 1 versionName "1.0.0" @@ -65,9 +65,9 @@ dependencies { releaseCompile project(':debugoverlay-no-op') testCompile project(':debugoverlay-no-op') - compile 'com.android.support:appcompat-v7:25.3.1' - compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' - compile 'com.android.support:design:25.3.1' + compile 'com.android.support:appcompat-v7:26.0.1' + compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile 'com.android.support:design:26.0.1' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' diff --git a/sample/src/main/java/com/ms_square/debugoverlay/sample/DebugOverlaySampleApplication.java b/sample/src/main/java/com/ms_square/debugoverlay/sample/DebugOverlaySampleApplication.java index e28d478..b183c33 100644 --- a/sample/src/main/java/com/ms_square/debugoverlay/sample/DebugOverlaySampleApplication.java +++ b/sample/src/main/java/com/ms_square/debugoverlay/sample/DebugOverlaySampleApplication.java @@ -41,7 +41,8 @@ public void onCreate() { // Use custom module // new DebugOverlay.Builder(this) -// .modules(new CpuUsageModule(), +// .modules(new CpuFreqModule(), +// new CpuUsageModule(), // new MemInfoModule(this), // new FpsModule(), // new IPAddressModule(this))