Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

import java

import java

from RefType t, Variable v
where
v.getType() = t and
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
| avoid-brightness-override.java:17:9:17:31 | params.screenBrightness | Avoid setting screenBrightness to BRIGHTNESS_OVERRIDE_FULL. This disables Android's adaptive brightness feature which was introduced to improve battery life. |
| avoid-brightness-override.java:23:9:23:31 | params.screenBrightness | Avoid setting screenBrightness to BRIGHTNESS_OVERRIDE_FULL. This disables Android's adaptive brightness feature which was introduced to improve battery life. |
| avoid-brightness-override.java:29:13:29:35 | params.screenBrightness | Avoid setting screenBrightness to BRIGHTNESS_OVERRIDE_FULL. This disables Android's adaptive brightness feature which was introduced to improve battery life. |
51 changes: 51 additions & 0 deletions codeql-custom-queries-java/android/avoid-brightness-override.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// WindowManager et WindowManager.LayoutParams sont déjà déclarés dans avoid-keep-screen-on.java
// avec seulement FLAG_KEEP_SCREEN_ON — on ne peut pas les redéclarer ni les modifier.
// On utilise une classe proxy BrightnessParams qui simule WindowManager.LayoutParams
// pour les champs screenBrightness et BRIGHTNESS_OVERRIDE_FULL.

class BrightnessParams {
float screenBrightness;
static final float BRIGHTNESS_OVERRIDE_FULL = 1.0f;
static final float BRIGHTNESS_OVERRIDE_NONE = -1.0f;
}

// 🚫 Noncompliant - screenBrightness set to BRIGHTNESS_OVERRIDE_FULL
class NoncompliantBrightnessOverride {

void disableAdaptiveBrightness() {
BrightnessParams params = new BrightnessParams();
params.screenBrightness = BrightnessParams.BRIGHTNESS_OVERRIDE_FULL; // $ Alert
}

void disableAdaptiveBrightnessWithVar() {
float override = BrightnessParams.BRIGHTNESS_OVERRIDE_FULL;
BrightnessParams params = new BrightnessParams();
params.screenBrightness = override; // $ Alert
}

void disableInLoop() {
for (int i = 0; i < 3; i++) {
BrightnessParams params = new BrightnessParams();
params.screenBrightness = BrightnessParams.BRIGHTNESS_OVERRIDE_FULL; // $ Alert
}
}
}

// ✅ Compliant - screenBrightness not set to BRIGHTNESS_OVERRIDE_FULL
class CompliantBrightnessUsage {

void useAdaptiveBrightness() {
BrightnessParams params = new BrightnessParams();
params.screenBrightness = BrightnessParams.BRIGHTNESS_OVERRIDE_NONE;
}

void useCustomBrightness() {
BrightnessParams params = new BrightnessParams();
params.screenBrightness = 0.5f;
}

void noScreenBrightnessSet() {
BrightnessParams params = new BrightnessParams();
int x = 42;
}
}
24 changes: 24 additions & 0 deletions codeql-custom-queries-java/android/avoid-brightness-override.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @name Brightness Override
* @description Setting WindowManager.LayoutParams#screenBrightness to BRIGHTNESS_OVERRIDE_FULL
* disables the adaptive brightness feature introduced in Android 9.
* Adaptive brightness adjusts screen brightness based on environment light
* to improve battery life. Overriding it is a very bad idea.
* @kind problem
* @problem.severity warning
* @id java/android/avoid-brightness-override
* @tags android
* @tags java
*/

import java

from FieldWrite fw
where
fw.getField().getName() = "screenBrightness" and
exists(FieldRead fr |
fr.getField().getName() = "BRIGHTNESS_OVERRIDE_FULL" and
fw.getEnclosingCallable() = fr.getEnclosingCallable()
)
select fw,
"Avoid setting screenBrightness to BRIGHTNESS_OVERRIDE_FULL. This disables Android's adaptive brightness feature which was introduced to improve battery life."
10 changes: 10 additions & 0 deletions codeql-custom-queries-java/android/avoid-day-night-mode.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
| avoid-day-night-mode.xml:5:5:5:65 | parent=Theme.AppCompat.Light | The theme 'AppTheme.Light' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-day-night-mode.xml:9:5:9:58 | parent=Theme.AppCompat | The theme 'AppTheme.Dark' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-day-night-mode.xml:13:5:13:71 | parent=Theme.MaterialComponents | The theme 'AppTheme.Material' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-day-night-mode.xml:17:5:17:83 | parent=Theme.AppCompat.Light.DarkActionBar | The theme 'AppTheme.LightDark' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-ligth-ui.xml:5:5:5:65 | parent=Theme.AppCompat.Light | The theme 'AppTheme.Light' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-ligth-ui.xml:9:5:9:82 | parent=Theme.MaterialComponents.Light | The theme 'AppTheme.MaterialLight' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-ligth-ui.xml:13:5:13:83 | parent=Theme.AppCompat.Light.DarkActionBar | The theme 'AppTheme.LightDark' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-ligth-ui.xml:17:5:17:100 | parent=Theme.MaterialComponents.Light.DarkActionBar | The theme 'AppTheme.MaterialLightDark' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-ligth-ui.xml:21:5:21:58 | parent=Theme.AppCompat | The theme 'AppTheme.Dark' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
| avoid-ligth-ui.xml:25:5:25:75 | parent=Theme.MaterialComponents | The theme 'AppTheme.MaterialDark' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens. |
26 changes: 26 additions & 0 deletions codeql-custom-queries-java/android/avoid-day-night-mode.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @name Day Night Mode
* @description Dark theme is available in Android 10 (API level 29) and higher.
* Apps should support Dark theme by inheriting from a DayNight theme
* (parent="Theme.*.DayNight"). Failing to do so prevents the app from
* adapting to the user's system dark mode preference, increasing energy
* consumption on (AM)OLED screens.
* @kind problem
* @problem.severity warning
* @id java/android/avoid-day-night-mode
* @tags android
* @tags java
*
* @note Test contains those for the darktheme detection too
*/

import semmle.code.xml.XML

from XmlAttribute attr
where
attr.getName() = "parent" and
not attr.getValue().matches("%DayNight%") and
attr.getElement().getName() = "style"
select attr,
"The theme '" + attr.getElement().getAttribute("name").getValue() +
"' does not inherit from a DayNight theme. Use 'Theme.*.DayNight' as parent to support Android dark mode and reduce energy consumption on (AM)OLED screens."
36 changes: 36 additions & 0 deletions codeql-custom-queries-java/android/avoid-day-night-mode.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<!-- 🚫 Noncompliant - explicit Light theme, no DayNight support -->
<style name="AppTheme.Light" parent="Theme.AppCompat.Light">
</style>

<!-- 🚫 Noncompliant - dark theme but not DayNight, won't adapt automatically -->
<style name="AppTheme.Dark" parent="Theme.AppCompat">
</style>

<!-- 🚫 Noncompliant - Material theme without DayNight -->
<style name="AppTheme.Material" parent="Theme.MaterialComponents">
</style>

<!-- 🚫 Noncompliant - Light with DarkActionBar but no DayNight -->
<style name="AppTheme.LightDark" parent="Theme.AppCompat.Light.DarkActionBar">
</style>

<!-- 🚫 Noncompliant - no parent attribute at all -->
<style name="AppTheme.NoParent">
</style>

<!-- ✅ Compliant - AppCompat DayNight theme -->
<style name="AppTheme.DayNight" parent="Theme.AppCompat.DayNight">
</style>

<!-- ✅ Compliant - Material DayNight theme -->
<style name="AppTheme.MaterialDayNight" parent="Theme.MaterialComponents.DayNight">
</style>

<!-- ✅ Compliant - Material DayNight with DarkActionBar -->
<style name="AppTheme.MaterialDayNightDark" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
</style>

</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| avoid-everlasting-service.java:15:9:15:38 | startService(...) | startService() is called here without a corresponding stopService() or stopSelf() in the same method. This may keep the service alive indefinitely and cause uncontrolled energy leakage. |
| avoid-everlasting-service.java:20:9:20:38 | startService(...) | startService() is called here without a corresponding stopService() or stopSelf() in the same method. This may keep the service alive indefinitely and cause uncontrolled energy leakage. |
| avoid-everlasting-service.java:21:9:21:38 | startService(...) | startService() is called here without a corresponding stopService() or stopSelf() in the same method. This may keep the service alive indefinitely and cause uncontrolled energy leakage. |
| avoid-everlasting-service.java:26:9:26:38 | startService(...) | startService() is called here without a corresponding stopService() or stopSelf() in the same method. This may keep the service alive indefinitely and cause uncontrolled energy leakage. |
61 changes: 61 additions & 0 deletions codeql-custom-queries-java/android/avoid-everlasting-service.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
class Context {
Object startService(Object service) { return null; }
boolean stopService(Object service) { return false; }
}

class Service extends Context {}

class Intent {}

// 🚫 Noncompliant - startService() without stopService() or stopSelf()
class NoncompliantEverlastingService {

void leakingLaunch() {
Context ctx = new Context();
ctx.startService(new Intent()); // $ Alert
}

void leakingLaunchMultiple() {
Context ctx = new Context();
ctx.startService(new Intent()); // $ Alert
ctx.startService(new Intent()); // $ Alert
}

void leakingNoStopInSameMethod() {
Context ctx = new Context();
ctx.startService(new Intent()); // $ Alert
}

void stopElsewhere() {
Context ctx = new Context();
ctx.stopService(new Intent());
}
}

// ✅ Compliant - startService() with stopService() in same method
class CompliantStopService {

void safeWithStopService() {
Context ctx = new Context();
ctx.startService(new Intent());
ctx.stopService(new Intent());
}

void safeMultiple() {
Context ctx = new Context();
ctx.startService(new Intent());
ctx.startService(new Intent());
ctx.stopService(new Intent());
}
}

// ✅ Compliant - startService() with stopSelf() in same method
class CompliantStopSelf extends Service {

void safeWithStopSelf() {
startService(new Intent());
stopSelf();
}

void stopSelf() {}
}
28 changes: 28 additions & 0 deletions codeql-custom-queries-java/android/avoid-everlasting-service.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @name Avoid Everlasting Service
* @description If someone calls Context#startService() then the service will continue
* running until Context#stopService() or Service#stopSelf() is called.
* Failing to call any of these methods can lead to uncontrolled energy leakage.
* @kind problem
* @problem.severity warning
* @precision medium
* @id java/android/avoid-everlasting-service
* @tags android
* @tags java
*/

import java

from MethodCall startCall
where
startCall.getMethod().getName() = "startService" and
not exists(MethodCall stopCall |
stopCall.getEnclosingCallable() = startCall.getEnclosingCallable() and
(
stopCall.getMethod().getName() = "stopService"
or
stopCall.getMethod().getName() = "stopSelf"
)
)
select startCall,
"startService() is called here without a corresponding stopService() or stopSelf() in the same method. This may keep the service alive indefinitely and cause uncontrolled energy leakage."
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
| avoid-internet-in-loop.java:18:13:18:32 | openConnection(...) | URL#openConnection() is called inside a loop. Opening HTTP connections in a loop is battery-inefficient. Consider using push notifications instead of polling. |
| avoid-internet-in-loop.java:26:13:26:32 | openConnection(...) | URL#openConnection() is called inside a loop. Opening HTTP connections in a loop is battery-inefficient. Consider using push notifications instead of polling. |
| avoid-internet-in-loop.java:34:13:34:32 | openConnection(...) | URL#openConnection() is called inside a loop. Opening HTTP connections in a loop is battery-inefficient. Consider using push notifications instead of polling. |
| avoid-internet-in-loop.java:43:13:43:32 | openConnection(...) | URL#openConnection() is called inside a loop. Opening HTTP connections in a loop is battery-inefficient. Consider using push notifications instead of polling. |
| avoid-internet-in-loop.java:51:17:51:36 | openConnection(...) | URL#openConnection() is called inside a loop. Opening HTTP connections in a loop is battery-inefficient. Consider using push notifications instead of polling. |
81 changes: 81 additions & 0 deletions codeql-custom-queries-java/android/avoid-internet-in-loop.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
class URL {
Object openConnection() { return null; }
}

class HttpURLConnection {
void connect() {}
void disconnect() {}
int getResponseCode() { return 200; }
}

// 🚫 Noncompliant - openConnection() inside loops
class NoncompliantInternetInLoop {

void fetchInWhileLoop() throws Exception {
int i = 0;
while (i < 10) {
URL url = new URL();
url.openConnection(); // $ Alert
i++;
}
}

void fetchInForLoop() throws Exception {
for (int i = 0; i < 10; i++) {
URL url = new URL();
url.openConnection(); // $ Alert
}
}

void fetchInDoWhileLoop() throws Exception {
int i = 0;
do {
URL url = new URL();
url.openConnection(); // $ Alert
i++;
} while (i < 10);
}

void fetchInForEachLoop() throws Exception {
String[] endpoints = {"http://a.com", "http://b.com"};
for (String endpoint : endpoints) {
URL url = new URL();
url.openConnection(); // $ Alert
}
}

void fetchInNestedLoop() throws Exception {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
URL url = new URL();
url.openConnection(); // $ Alert
}
}
}
}

// ✅ Compliant - openConnection() outside loops
class CompliantInternetUsage {

void fetchOnce() throws Exception {
URL url = new URL();
url.openConnection();
}

void fetchBeforeLoop() throws Exception {
URL url = new URL();
url.openConnection();
for (int i = 0; i < 10; i++) {
// traitement sans nouvelle connexion
int x = i * 2;
}
}

void processItems() throws Exception {
String[] items = {"a", "b", "c"};
for (String item : items) {
// traitement sans ouvrir de connexion
String result = item.toUpperCase();
}
}
}
23 changes: 23 additions & 0 deletions codeql-custom-queries-java/android/avoid-internet-in-loop.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @name Internet In The Loop
* @description Opening and closing internet connections continuously is extremely battery-inefficient.
* Obtaining a new HttpURLConnection by calling URL#openConnection() within a loop
* control structure (while, for, do-while, for-each) is a bad practice that leads
* to uncontrolled energy leakage and prevents the use of push notifications.
* @kind problem
* @problem.severity warning
* @precision high
* @id java/android/internet-in-loop
* @link https://green-code-initiative.org/rules#id:GCI502
* @tags android
* @tags java
*/

import java

from MethodCall openCall, LoopStmt loop
where
openCall.getMethod().getName() = "openConnection" and
loop.getBody().getAChild*() = openCall.getEnclosingStmt()
select openCall,
"URL#openConnection() is called inside a loop. Opening HTTP connections in a loop is battery-inefficient. Consider using push notifications instead of polling."
6 changes: 6 additions & 0 deletions codeql-custom-queries-java/android/avoid-ligth-ui.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
| avoid-day-night-mode.xml:5:5:5:65 | parent=Theme.AppCompat.Light | Avoid using light themes ('Theme.AppCompat.Light'). Light themes consume more energy on (AM)OLED screens. Prefer a dark theme instead. |
| avoid-day-night-mode.xml:17:5:17:83 | parent=Theme.AppCompat.Light.DarkActionBar | Avoid using light themes ('Theme.AppCompat.Light.DarkActionBar'). Light themes consume more energy on (AM)OLED screens. Prefer a dark theme instead. |
| avoid-ligth-ui.xml:5:5:5:65 | parent=Theme.AppCompat.Light | Avoid using light themes ('Theme.AppCompat.Light'). Light themes consume more energy on (AM)OLED screens. Prefer a dark theme instead. |
| avoid-ligth-ui.xml:9:5:9:82 | parent=Theme.MaterialComponents.Light | Avoid using light themes ('Theme.MaterialComponents.Light'). Light themes consume more energy on (AM)OLED screens. Prefer a dark theme instead. |
| avoid-ligth-ui.xml:13:5:13:83 | parent=Theme.AppCompat.Light.DarkActionBar | Avoid using light themes ('Theme.AppCompat.Light.DarkActionBar'). Light themes consume more energy on (AM)OLED screens. Prefer a dark theme instead. |
| avoid-ligth-ui.xml:17:5:17:100 | parent=Theme.MaterialComponents.Light.DarkActionBar | Avoid using light themes ('Theme.MaterialComponents.Light.DarkActionBar'). Light themes consume more energy on (AM)OLED screens. Prefer a dark theme instead. |
Loading
Loading