diff --git a/CHANGELOG.md b/CHANGELOG.md
index 56a05ed33..2545fc5d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
+- [ios#3](https://github.com/green-code-initiative/ecoCode-ios/issues/3) Move iOS rules into centralized rules repository
+- [android#67](https://github.com/green-code-initiative/ecoCode-android/issues/67) Move Android rules into centralized rules repository
- [#216](https://github.com/green-code-initiative/ecoCode/issues/216) Upgrade rule EC2 for Java : Multiple if-else statement improvment
- [#106](https://github.com/green-code-initiative/ecoCode/issues/106) Upgrade RULES.md : rule EC67 not relevant neither for Python nor Rust
- [#225](https://github.com/green-code-initiative/ecoCode/pull/225) Upgrade licence system and licence headers of Java files
diff --git a/ecocode-rules-specifications/pom.xml b/ecocode-rules-specifications/pom.xml
index 9d896478d..5811cddb5 100644
--- a/ecocode-rules-specifications/pom.xml
+++ b/ecocode-rules-specifications/pom.xml
@@ -147,6 +147,30 @@
+
+ assembly-swift
+ prepare-package
+
+ single
+
+
+
+ ${project.basedir}/src/main/assembly/swift.xml
+
+
+
+
+ assembly-xml
+ prepare-package
+
+ single
+
+
+
+ ${project.basedir}/src/main/assembly/xml.xml
+
+
+
true
diff --git a/ecocode-rules-specifications/src/main/assembly/swift.xml b/ecocode-rules-specifications/src/main/assembly/swift.xml
new file mode 100644
index 000000000..2ea8b63a9
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/assembly/swift.xml
@@ -0,0 +1,18 @@
+
+ swift
+
+ jar
+
+ false
+
+
+ ${project.build.outputDirectory}
+
+ io/ecocode/rules/swift/*.*
+
+
+
+
+
diff --git a/ecocode-rules-specifications/src/main/assembly/xml.xml b/ecocode-rules-specifications/src/main/assembly/xml.xml
new file mode 100644
index 000000000..bffbcd328
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/assembly/xml.xml
@@ -0,0 +1,18 @@
+
+ xml
+
+ jar
+
+ false
+
+
+ ${project.build.outputDirectory}
+
+ io/ecocode/rules/xml/*.*
+
+
+
+
+
diff --git a/ecocode-rules-specifications/src/main/rules/EC500/EC500.json b/ecocode-rules-specifications/src/main/rules/EC500/EC500.json
new file mode 100644
index 000000000..87aae031c
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC500/EC500.json
@@ -0,0 +1,18 @@
+{
+ "title": "Batch: Sensor Coalesce",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "batch",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC500/java/EC500.asciidoc b/ecocode-rules-specifications/src/main/rules/EC500/java/EC500.asciidoc
new file mode 100644
index 000000000..951822492
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC500/java/EC500.asciidoc
@@ -0,0 +1,25 @@
+With `SensorManager#registerListener(SensorEventListener, Sensor, int)` the events are delivered as soon as possible.
+
+Instead, `SensorManager#registerListener(SensorEventListener, Sensor, int, int maxReportLatencyUs)` allows events to stay temporarily in the hardware FIFO (queue) before being delivered. The events can be stored in the hardware FIFO up to `maxReportLatencyUs` microseconds.
+
+Once one of the events in the FIFO needs to be reported, all the events in the FIFO are reported sequentially. Setting `maxReportLatencyUs` to a positive value allows to reduce the number of interrupts the AP (Application Processor) receives, hence reducing power consumption, as the AP can switch to a lower power state while the sensor is capturing the data.
+
+## Noncompliant Code Example
+
+```java
+SensorEventListener sensorEventListener;
+SensorManager sensorManager;
+Sensor sensor;
+
+sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
+```
+
+## Compliant Code Example
+
+```java
+SensorEventListener sensorEventListener;
+SensorManager sensorManager;
+Sensor sensor;
+
+sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL, 200000);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC501/EC501.json b/ecocode-rules-specifications/src/main/rules/EC501/EC501.json
new file mode 100644
index 000000000..169e1f742
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC501/EC501.json
@@ -0,0 +1,18 @@
+{
+ "title": "Batch: Job Coalesce",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "3h"
+ },
+ "tags": [
+ "batch",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC501/java/EC501.asciidoc b/ecocode-rules-specifications/src/main/rules/EC501/java/EC501.asciidoc
new file mode 100644
index 000000000..84062dbab
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC501/java/EC501.asciidoc
@@ -0,0 +1,32 @@
+The Android 5.0 Lollipop (API 21) release introduces a job scheduler API via the Job Scheduler class.
+
+Compared to a custom Sync Adapter or the alarm manager, the Job Scheduler supports batch scheduling of jobs.
+
+The Android system can combine jobs so that battery consumption is reduced.
+
+## Noncompliant Code Example
+
+```java
+void setAlarm(Context context) {
+ AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
+ Intent intent = new Intent(context, Alarm.class);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
+ alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 10, pendingIntent);
+}
+
+Alarm alarm = new Alarm();
+alarm.setAlarm(this);
+```
+
+## Compliant Code Example
+
+```java
+JobInfo info = new JobInfo.Builder(123, COMPONENT_NAME)
+ .setRequiresCharging(true)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
+ .setPersisted(true)
+ .setPeriodic(10 * 60 * 1000)
+ .build();
+JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
+scheduler.schedule(info);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC502/EC502.json b/ecocode-rules-specifications/src/main/rules/EC502/EC502.json
new file mode 100644
index 000000000..786b0dc7a
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC502/EC502.json
@@ -0,0 +1,18 @@
+{
+ "title": "Bottleneck: Internet In The Loop",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "3h"
+ },
+ "tags": [
+ "optimized-api",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.2",
+ "defaultSeverity": "Critical"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC502/java/EC502.asciidoc b/ecocode-rules-specifications/src/main/rules/EC502/java/EC502.asciidoc
new file mode 100644
index 000000000..c645aaf93
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC502/java/EC502.asciidoc
@@ -0,0 +1,11 @@
+Opening and closing internet connection continuously is extremely battery-inefficient since HTTP exchange is the most consuming operation of the network. This bug typically occurs when one obtain a new `HttpURLConnection` by calling `URL#openConnection()` within a loop control structure (while, for, do-while, for-each).
+
+Also, this bad practice must be early prevented because it is the root of another evil that consists in polling data at regular intervals, instead of using push notifications to save a lot of battery power.
+
+## Noncompliant Code Example
+
+```java
+for (int val : myArray) {
+ URL.openConnection();
+}
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC503/EC503.json b/ecocode-rules-specifications/src/main/rules/EC503/EC503.json
new file mode 100644
index 000000000..27bc96daa
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC503/EC503.json
@@ -0,0 +1,18 @@
+{
+ "title": "Bottleneck: Wifi Multicast Lock",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "bottleneck",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.6",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC503/java/EC503.asciidoc b/ecocode-rules-specifications/src/main/rules/EC503/java/EC503.asciidoc
new file mode 100644
index 000000000..674011019
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC503/java/EC503.asciidoc
@@ -0,0 +1,20 @@
+Normally the Wi-Fi stack filters out packets not explicitly addressed to the device. Acquiring a Multicast Lock with `WifiManager.MulticastLock.acquire()` will cause the stack to receive packets addressed to multicast addresses.
+
+Processing these extra packets can cause a noticeable battery drain and must be disabled when not needed with to a call to `WifiManager.MulticastLock.release()`.
+
+## Noncompliant Code Example
+
+```java
+WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+WifiManager.MulticastLock lock = wifiManager.createMulticastLock("tag");
+lock.acquire();
+```
+
+## Compliant Code Example
+
+```java
+WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+WifiManager.MulticastLock lock = wifiManager.createMulticastLock("tag");
+lock.acquire();
+lock.release()
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC504/EC504.json b/ecocode-rules-specifications/src/main/rules/EC504/EC504.json
new file mode 100644
index 000000000..ee1782089
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC504/EC504.json
@@ -0,0 +1,18 @@
+{
+ "title": "Bottleneck: Uncompressed Data Transmission",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "bottleneck",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
diff --git a/ecocode-rules-specifications/src/main/rules/EC504/java/EC504.asciidoc b/ecocode-rules-specifications/src/main/rules/EC504/java/EC504.asciidoc
new file mode 100644
index 000000000..80f67b532
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC504/java/EC504.asciidoc
@@ -0,0 +1,17 @@
+Transmitting a file over a network infrastructure without compressing it consumes more energy than with compression. More precisely, energy efficiency is improved in case the data is compressed at least by 10%, transmitted and decompressed at the other network node. From the Android client side, it means making a post HTTP request using a `GZIPOutputStream` instead of the classical OutputStream, along with the `HttpURLConnection` object.
+
+## Noncompliant Code Example
+
+```java
+Url url = new Url("https://www.ecocode.io/");
+HttpsUrlConnection con = (HttpsURLConnection) url.openConnection();
+OutputStream stream = con.getOutputStream();
+```
+
+## Compliant Code Example
+
+```java
+Url url = new Url("https://www.ecocode.io/");
+HttpsUrlConnection con = (HttpsURLConnection) url.openConnection();
+OutputStream stream = new GZIPOutputStream(con.getOutputStream());
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC505/EC505.json b/ecocode-rules-specifications/src/main/rules/EC505/EC505.json
new file mode 100644
index 000000000..13922db0e
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC505/EC505.json
@@ -0,0 +1,18 @@
+{
+ "title": "Idleness: Keep Screen On (addFlags)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.6",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC505/java/EC505.asciidoc b/ecocode-rules-specifications/src/main/rules/EC505/java/EC505.asciidoc
new file mode 100644
index 000000000..8cb61fe1e
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC505/java/EC505.asciidoc
@@ -0,0 +1,9 @@
+To avoid draining the battery, an Android device that is left idle quickly falls asleep.
+
+Hence, keeping the screen on should be avoided, unless it is absolutely necessary. If so, developers typically use the `FLAG_KEEP_SCREEN_ON` in their activity. Another way to implement this is in their application's layout XML file, by using the `android:keepScreenOn` attribute.
+
+## Noncompliant Code Example
+
+```java
+getWindow().addFlags(FLAG_KEEP_SCREEN_ON);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC505/swift/EC505.asciidoc b/ecocode-rules-specifications/src/main/rules/EC505/swift/EC505.asciidoc
new file mode 100644
index 000000000..0346e3c1f
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC505/swift/EC505.asciidoc
@@ -0,0 +1,13 @@
+Score ecoCode: 2sur5
+
+To avoid draining the battery, an iOS device that is left idle quickly falls asleep.
+
+Hence, keeping the screen on should be avoided, unless it is absolutely necessary. If so, developers typically
+disable the idle timer with `UIApplication.shared.isIdleTimerDisabled = true`.
+
+## Noncompliant Code Example
+
+```swift
+UIApplication.shared.isIdleTimerDisabled = true
+```
+
diff --git a/ecocode-rules-specifications/src/main/rules/EC506/EC506.json b/ecocode-rules-specifications/src/main/rules/EC506/EC506.json
new file mode 100644
index 000000000..02149cb73
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC506/EC506.json
@@ -0,0 +1,18 @@
+{
+ "title": "Idleness: Keep Screen On (setFlags)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.6",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC506/java/EC506.asciidoc b/ecocode-rules-specifications/src/main/rules/EC506/java/EC506.asciidoc
new file mode 100644
index 000000000..b047c41cc
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC506/java/EC506.asciidoc
@@ -0,0 +1,9 @@
+To avoid draining the battery, an Android device that is left idle quickly falls asleep.
+
+Hence, keeping the screen on should be avoided, unless it is absolutely necessary. If so, developers typically use the `FLAG_KEEP_SCREEN_ON` in their activity. Another way to implement this is in their application's layout XML file, by using the `android:keepScreenOn` attribute.
+
+## Noncompliant Code Example
+
+```java
+getWindow().setFlags(FLAG_KEEP_SCREEN_ON, FLAG_KEEP_SCREEN_ON);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC506/swift/EC506.asciidoc b/ecocode-rules-specifications/src/main/rules/EC506/swift/EC506.asciidoc
new file mode 100644
index 000000000..f672a2088
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC506/swift/EC506.asciidoc
@@ -0,0 +1,16 @@
+Score ecoCode: 2sur5
+
+Setting a tolerance for timers will allow them to fire later than the scheduled fire date. The system will use this flexibility to shift the execution of timers by small amounts of time, within their tolerances, increasing the ability to optimize power savings. Your app can set the `Timer#tolerance` property to specify a tolerance for a timer. Using this approach dramatically increases the amount of time that the processor spends idling while users detect no change in system responsiveness.
+
+## Noncompliant Code Example
+
+```swift
+let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in }
+```
+
+## Compliant Code Example
+
+```swift
+let timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in }
+timer.tolerance = 0.5
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC507/EC507.json b/ecocode-rules-specifications/src/main/rules/EC507/EC507.json
new file mode 100644
index 000000000..e8c97bac2
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC507/EC507.json
@@ -0,0 +1,18 @@
+{
+ "title": "Idleness: Keep Cpu On",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "1h"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC507/java/EC507.asciidoc b/ecocode-rules-specifications/src/main/rules/EC507/java/EC507.asciidoc
new file mode 100644
index 000000000..a1a8362d5
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC507/java/EC507.asciidoc
@@ -0,0 +1,10 @@
+To avoid draining the battery, an Android device that is left idle quickly falls asleep. Hence, keeping the CPU on should be avoided, unless it is absolutely necessary.
+
+If so, developers typically use a Power Manager system service feature called wake locks by invoking `PowerManager.WakeLock#newWakeLock(int levelAndFlags, String tag)`, along with the specific permission `WAKE_LOCK` in their manifest.
+
+## Noncompliant Code Example
+
+```java
+PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+WakeLock manager = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG");
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC508/EC508.json b/ecocode-rules-specifications/src/main/rules/EC508/EC508.json
new file mode 100644
index 000000000..10d100572
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC508/EC508.json
@@ -0,0 +1,18 @@
+{
+ "title": "Idleness: Durable Wake Lock",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC508/java/EC508.asciidoc b/ecocode-rules-specifications/src/main/rules/EC508/java/EC508.asciidoc
new file mode 100644
index 000000000..98bf682f7
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC508/java/EC508.asciidoc
@@ -0,0 +1,17 @@
+A wake lock is a mechanism to indicate that your application needs to have the device stay on. The general principle is to obtain a wake lock, acquire it and finally release it.
+
+Hence, the challenge here is to release the lock as soon as possible to avoid running down the device's battery excessively. Missing call to `PowerManager#release()` is a built-in check of Android lint (_Wakelock_ check) but that does not prevent abuse of the lock over too long a period of time.
+
+This can be avoided by a call to `PowerManager#acquire(long timeout)` instead of `PowerManager#acquire()`, because the lock will be released for sure after the given timeout expires.
+
+## Noncompliant Code Example
+
+```java
+PowerManager.acquire()
+```
+
+## Compliant Code Example
+
+```java
+PowerManager.acquire(long timeout)
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC509/EC509.json b/ecocode-rules-specifications/src/main/rules/EC509/EC509.json
new file mode 100644
index 000000000..470bdd9a9
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC509/EC509.json
@@ -0,0 +1,18 @@
+{
+ "title": "Idleness: Rigid Alarm",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "1d"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC509/java/EC509.asciidoc b/ecocode-rules-specifications/src/main/rules/EC509/java/EC509.asciidoc
new file mode 100644
index 000000000..a477697e7
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC509/java/EC509.asciidoc
@@ -0,0 +1,31 @@
+Applications are strongly discouraged from using exact alarms unnecessarily as they reduce the OS's ability to minimize battery use (i.e. Doze Mode).
+
+For most apps prior to API 19, `setInexactRepeating()` is preferable over `setRepeating()`. When you use this method, Android synchronizes multiple inexact repeating alarms and fires them at the same time, thus reducing the battery drain.
+
+Similarly after API 19, `setExact()` and `setExactAndAllowWhileIdle()` can significantly impact the power use of the device when idle, so they should be used with care. High-frequency alarms are also bad for battery life but this is already checked by Android lint (ShortAlarm built-in check).
+
+## Noncompliant Code Example
+
+```java
+AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+alarmManager.setRepeating(alarmType, triggerAtMillis, intervalMillis, operation);
+``` or
+```java
+AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+alarmManager.setExact(type,triggerAtMillis,operation);
+``` or
+```java
+AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+alarmManager.setExact(type,triggerAtMillis,tag,listener,targetHandler);
+``` or
+```java
+AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+alarmManager.setExactAndAllowWhileIdle(type,triggerAtMilllis,operation);
+```
+
+## Compliant Code Example
+
+```java
+AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
+alarmManager.setInexactRepeating(alarmType, triggerAtMillis, intervalMillis, operation);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC510/EC510.json b/ecocode-rules-specifications/src/main/rules/EC510/EC510.json
new file mode 100644
index 000000000..d09f88864
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC510/EC510.json
@@ -0,0 +1,18 @@
+{
+ "title": "Idleness: Continuous Rendering",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC510/java/EC510.asciidoc b/ecocode-rules-specifications/src/main/rules/EC510/java/EC510.asciidoc
new file mode 100644
index 000000000..9d12df018
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC510/java/EC510.asciidoc
@@ -0,0 +1,15 @@
+For developers wishing to display OpenGL rendering, when choosing the rendering mode with `GLSurfaceView#setRenderMode(int renderMode)`, using `RENDERMODE_WHEN_DIRTY` instead of `RENDERMODE_CONTINUOUSLY` (by default) can improve battery life and overall system performance by allowing the GPU and CPU to idle when the view does not need to be updated.
+
+## Noncompliant Code Example
+
+```java
+GLSurfaceView surfaceView = new GLSurfaceView(this);
+surfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY)
+```
+
+## Compliant Code Example
+
+```java
+GLSurfaceView surfaceView = new GLSurfaceView(this);
+surfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY)
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC511/EC511.json b/ecocode-rules-specifications/src/main/rules/EC511/EC511.json
new file mode 100644
index 000000000..14cccf094
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC511/EC511.json
@@ -0,0 +1,18 @@
+{
+ "title": "Idleness: Keep Voice Awake",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC511/java/EC511.asciidoc b/ecocode-rules-specifications/src/main/rules/EC511/java/EC511.asciidoc
new file mode 100644
index 000000000..c911421da
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC511/java/EC511.asciidoc
@@ -0,0 +1,23 @@
+During a voice interaction session, `VoiceInteractionSession#setKeepAwake(boolean keepAwake)` allows to decide whether it will keep the device awake while it is running a voice activity.
+
+By default, the system holds a wake lock for it while in this state, so that it can work even if the screen is off. Setting this to `false` removes that wake lock, allowing the CPU to go to sleep and hence does not let this continue to drain the battery.
+
+## Noncompliant Code Example
+
+```java
+VoiceInteractionSession voiceSession = new VoiceInteractionSession(this);
+```
+
+or
+
+```java
+VoiceInteractionSession voiceSession = new VoiceInteractionSession(this);
+voiceSession.setKeepAwake(true);
+```
+
+## Compliant Code Example
+
+```java
+VoiceInteractionSession voiceSession = new VoiceInteractionSession(this);
+voiceSession.setKeepAwake(false);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC512/EC512.json b/ecocode-rules-specifications/src/main/rules/EC512/EC512.json
new file mode 100644
index 000000000..4f9481425
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC512/EC512.json
@@ -0,0 +1,18 @@
+{
+ "title": "Leakage: Camera Leak",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "leakage",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.2",
+ "defaultSeverity": "Critical"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC512/java/EC512.asciidoc b/ecocode-rules-specifications/src/main/rules/EC512/java/EC512.asciidoc
new file mode 100644
index 000000000..782c35274
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC512/java/EC512.asciidoc
@@ -0,0 +1,20 @@
+Most Android-powered devices have built-in sensors that measure motion, orientation, and various environmental conditions.
+ In addition to these are the image sensor (a.k.a. Camera) and the geo-positioning sensor (a.k.a. GPS).
+
+The common point of all these sensors is that they are expensive while in use. Their common bug is to let the sensor unnecessarily process data when the app enters an idle state, typically when paused or stopped.
+
+ Consequently, calls must be carefully pairwised: `Camera.open()/Camera.release()`.
+ Failing to do so can drain the battery in just a few hours.
+
+## Noncompliant Code Example
+
+```java
+Camera camera = Camera.open();
+```
+
+## Compliant Code Example
+
+```java
+Camera camera = Camera.open();
+camera.release();
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC513/EC513.json b/ecocode-rules-specifications/src/main/rules/EC513/EC513.json
new file mode 100644
index 000000000..62ae8ab4d
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC513/EC513.json
@@ -0,0 +1,18 @@
+{
+ "title": "Leakage: Location Leak",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "leakage",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.2",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC513/java/EC513.asciidoc b/ecocode-rules-specifications/src/main/rules/EC513/java/EC513.asciidoc
new file mode 100644
index 000000000..cdc8b59a1
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC513/java/EC513.asciidoc
@@ -0,0 +1,23 @@
+Most Android-powered devices have built-in sensors that measure motion, orientation, and various environmental conditions.
+ In addition to these are the image sensor (a.k.a. Camera) and the geo-positioning sensor (a.k.a. GPS).
+
+The common point of all these sensors is that they are expensive while in use. Their common bug is to let the sensor unnecessarily process data when the app enters an idle state, typically when paused or stopped.
+
+ Consequently, calls must be carefully pairwised: `LocationManager.requestLocationUpdates()/removeUpdates()`.
+
+ Failing to do so can drain the battery in just a few hours.
+
+## Noncompliant Code Example
+
+```java
+LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 1.0f, this);
+```
+
+## Compliant Code Example
+
+```java
+LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 1.0f, this);
+locationManager.removeUpdates(this);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC514/EC514.json b/ecocode-rules-specifications/src/main/rules/EC514/EC514.json
new file mode 100644
index 000000000..7d3fbc451
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC514/EC514.json
@@ -0,0 +1,18 @@
+{
+ "title": "Leakage: SensorManager Leak",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "leakage",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.2",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC514/java/EC514.asciidoc b/ecocode-rules-specifications/src/main/rules/EC514/java/EC514.asciidoc
new file mode 100644
index 000000000..2f06dd287
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC514/java/EC514.asciidoc
@@ -0,0 +1,24 @@
+Most Android-powered devices have built-in sensors that measure motion, orientation, and various environmental conditions.
+ In addition to these are the image sensor (a.k.a. Camera) and the geo-positioning sensor (a.k.a. GPS).
+
+The common point of all these sensors is that they are expensive while in use. Their common bug is to let the sensor unnecessarily process data when the app enters an idle state, typically when paused or stopped.
+
+ Consequently, calls must be carefully pairwised: `SensorManager#registerListener()/unregisterListener()`.
+ Failing to do so can drain the battery in just a few hours.
+
+## Noncompliant Code Example
+
+```java
+SensorManager sManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+Sensor accelerometer = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+sManager.registerListener(this,accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
+```
+
+## Compliant Code Example
+
+```java
+SensorManager sManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+Sensor accelerometer = sManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+sManager.registerListener(this,accelerometer,SensorManager.SENSOR_DELAY_NORMAL);
+sManager.unregisterListener(this);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC515/EC515.json b/ecocode-rules-specifications/src/main/rules/EC515/EC515.json
new file mode 100644
index 000000000..8fd81725b
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC515/EC515.json
@@ -0,0 +1,18 @@
+{
+ "title": "Leakage: Media Leak (MediaRecorder)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "leakage",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC515/java/EC515.asciidoc b/ecocode-rules-specifications/src/main/rules/EC515/java/EC515.asciidoc
new file mode 100644
index 000000000..2053d051b
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC515/java/EC515.asciidoc
@@ -0,0 +1,16 @@
+Creation of a Media Recorder object with `new MediaRecorder()` is used to record audio and video. Class own a `release()` method.
+
+In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a media object is no longer needed may also lead to continuous battery consumption for mobile devices.
+
+## Noncompliant Code Example
+
+```java
+MediaRecorder mr = new MediaRecorder();
+```
+
+## Compliant Solution
+
+```java
+MediaRecorder mr = new MediaRecorder();
+mr.release();
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC516/EC516.json b/ecocode-rules-specifications/src/main/rules/EC516/EC516.json
new file mode 100644
index 000000000..b6ebfa5f2
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC516/EC516.json
@@ -0,0 +1,18 @@
+{
+ "title": "Leakage: Media Leak (MediaPlayer)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "leakage",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC516/java/EC516.asciidoc b/ecocode-rules-specifications/src/main/rules/EC516/java/EC516.asciidoc
new file mode 100644
index 000000000..e59c5a2ed
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC516/java/EC516.asciidoc
@@ -0,0 +1,16 @@
+Creation of a Media Player object with `new MediaPlayer()` can be used to control playback of audio/video files and streams. Class own a`release()` method.
+
+In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a media object is no longer needed may also lead to continuous battery consumption for mobile devices.
+
+## Noncompliant Code Example
+
+```java
+MediaPlayer mp = new MediaPlayer();
+```
+
+## Compliant Solution
+
+```java
+MediaPlayer mp = new MediaPlayer();
+mp.release();
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC517/EC517.json b/ecocode-rules-specifications/src/main/rules/EC517/EC517.json
new file mode 100644
index 000000000..7c263b9f8
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC517/EC517.json
@@ -0,0 +1,18 @@
+{
+ "title": "Optimized API: Fused Location",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "optimized-api",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.6",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC517/java/EC517.asciidoc b/ecocode-rules-specifications/src/main/rules/EC517/java/EC517.asciidoc
new file mode 100644
index 000000000..03a404866
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC517/java/EC517.asciidoc
@@ -0,0 +1,15 @@
+The fused location provider is one of the location APIs in Google Play services which combines signals from GPS, Wi-Fi, and cell networks, as well as accelerometer, gyroscope, magnetometer and other sensors. It is officially recommended to maximize battery life.
+
+Thus, developer has to set up Google Play Service in her gradle file with a dependency to `com.google.android.gms:play-services-location:x.y.z`, and then to import from `com.google.android.gms.location` instead of the `android.location` package of the SDK.
+
+## Noncompliant Code Example
+
+```java
+import android.location.*;
+```
+
+## Compliant Solution
+
+```java
+import com.google.android.gms.location.*;
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC518/EC518.json b/ecocode-rules-specifications/src/main/rules/EC518/EC518.json
new file mode 100644
index 000000000..87d28f50a
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC518/EC518.json
@@ -0,0 +1,18 @@
+{
+ "title": "Optimized API: Bluetooth Low-Energy",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "optimized-api",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.6",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC518/java/EC518.asciidoc b/ecocode-rules-specifications/src/main/rules/EC518/java/EC518.asciidoc
new file mode 100644
index 000000000..805dd1e46
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC518/java/EC518.asciidoc
@@ -0,0 +1,15 @@
+In contrast to classic Bluetooth, Bluetooth Low Energy (BLE) is designed to provide significantly lower power consumption. Its purpose is to save energy on both paired devices but very few developers are aware of this alternative API.
+
+From the Android client side, it means append `android.bluetooth.le.\*` imports to `android.bluetooth.*` imports in order to benefits from low-energy features.
+
+## Noncompliant Code Example
+
+```java
+import android.bluetooth.*
+```
+
+## Compliant Solution
+
+```java
+import android.bluetooth.le.*
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC519/EC519.json b/ecocode-rules-specifications/src/main/rules/EC519/EC519.json
new file mode 100644
index 000000000..65127ad4a
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC519/EC519.json
@@ -0,0 +1,18 @@
+{
+ "title": "Power: Charge Awareness",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "0min"
+ },
+ "tags": [
+ "power",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "1.0",
+ "defaultSeverity": "Info"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC519/java/EC519.asciidoc b/ecocode-rules-specifications/src/main/rules/EC519/java/EC519.asciidoc
new file mode 100644
index 000000000..1bdc27c6e
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC519/java/EC519.asciidoc
@@ -0,0 +1,27 @@
+It's always good that an app has different behavior when device is connected/disconnected to a power station, or has different battery levels.
+
+One can monitor the changes in charging state with a broadcast receiver registered on the actions `ACTION_POWER_CONNECTED` and `ACTION_POWER_DISCONNECTED`, or monitor significant changes in battery level with a broadcast receiver registered on the actions `BATTERY_LOW` and `BATTERY_OKAY`.
+
+## Compliant Code Example
+
+```java
+new IntentFilter(Intent.ACTION_POWER_CONNECTED)
+```
+
+Or
+
+```java
+new IntentFilter(Intent.ACTION_POWER_DISCONNECTED)
+```
+
+Or
+
+```java
+new IntentFilter(Intent.ACTION_POWER_BATTERY_OKAY)
+```
+
+Or
+
+```java
+new IntentFilter(Intent.ACTION_POWER_BATTERY_LOW)
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC520/EC520.json b/ecocode-rules-specifications/src/main/rules/EC520/EC520.json
new file mode 100644
index 000000000..a5649c6ea
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC520/EC520.json
@@ -0,0 +1,18 @@
+{
+ "title": "Power: Save Mode Awareness",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "0min"
+ },
+ "tags": [
+ "power",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "1.0",
+ "defaultSeverity": "Info"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC520/java/EC520.asciidoc b/ecocode-rules-specifications/src/main/rules/EC520/java/EC520.asciidoc
new file mode 100644
index 000000000..d4e3c166c
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC520/java/EC520.asciidoc
@@ -0,0 +1,27 @@
+Taking into account when the device is entering or exiting the power save mode is higly desirable for the battery life.
+
+It implies the existence of a broadcast receiver registered on the action `ACTION_POWER_SAVE_MODE_CHANGED`, or programmaticaly with a call to `PowerManager#isPowerSaveMode().`
+
+## Compliant Code Example
+
+```java
+new IntentFilter(Intent.ACTION_POWER_SAVE_MODE_CHANGED)
+```
+
+Or
+
+```java
+intentFilter.addAction(ACTION_POWER_SAVE_MODE_CHANGED)
+```
+
+Or
+
+```java
+IntentFilter.create(ACTION_POWER_SAVE_MODE_CHANGED,"")
+```
+
+Or
+
+```java
+powerManager.isPowerSaveMode()
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC521/EC521.json b/ecocode-rules-specifications/src/main/rules/EC521/EC521.json
new file mode 100644
index 000000000..55cd4ed43
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC521/EC521.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Thrifty Motion Sensor",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC521/java/EC521.asciidoc b/ecocode-rules-specifications/src/main/rules/EC521/java/EC521.asciidoc
new file mode 100644
index 000000000..4d370f0a4
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC521/java/EC521.asciidoc
@@ -0,0 +1,15 @@
+The rotation vector sensor is the most frequently used sensor for motion detection and monitoring. When using `SensorManager#getDefaultSensor(int type)`, always prefer the constant `TYPE_GEOMAGNETIC_ROTATION_VECTOR` which is similar to `TYPE_ROTATION_VECTOR`, but using a magnetometer instead of using a gyroscope. This sensor uses lower power than the other rotation vectors, because it doesn't use the gyroscope. However, it is more noisy and will work best outdoors.
+
+## Noncompliant Code Example
+
+```java
+SensorManager sManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+sManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
+```
+
+## Compliant Code Example
+
+```java
+SensorManager sManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+sManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC521/swift/EC521.asciidoc b/ecocode-rules-specifications/src/main/rules/EC521/swift/EC521.asciidoc
new file mode 100644
index 000000000..1ee38ee48
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC521/swift/EC521.asciidoc
@@ -0,0 +1,11 @@
+Score ecoCode: 2sur5
+
+Allowing the system to pause location updates, at times when the location data is unlikely to change, can improve battery life without sacrificing location data. This is the default behavior. For example, if the user stops for food while using a navigation app, the location manager might pause updates for a period of time. It is possible to disable this behavior, by setting the `CLLocationManager#pausesLocationUpdatesAutomatically` property to `false`, but applications are strongly discouraged of doing it.
+
+## Noncompliant Code Example
+
+```swift
+let manager = CLLocationManager()
+manager.pausesLocationUpdatesAutomatically = false
+```
+
diff --git a/ecocode-rules-specifications/src/main/rules/EC522/EC522.json b/ecocode-rules-specifications/src/main/rules/EC522/EC522.json
new file mode 100644
index 000000000..8711bfb45
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC522/EC522.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Brightness Override",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC522/java/EC522.asciidoc b/ecocode-rules-specifications/src/main/rules/EC522/java/EC522.asciidoc
new file mode 100644
index 000000000..a7286af84
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC522/java/EC522.asciidoc
@@ -0,0 +1,11 @@
+Introduced in Android 9, the adaptive brightness feature raises or lower the brightness of the screen depending on the light in the current environment.
+
+For some reasons, developers may disable this feature programmatically, setting the field `WindowManager.LayoutParams#screenBrightness` with the constant `BRIGHTNESS_OVERRIDE_FULL`.
+
+This feature was introduced to improve battery life, be careful when deactivating it.
+
+## Noncompliant Code Example
+
+```java
+getWindow().getAttributes().screenBrightness = BRIGHTNESS_OVERRIDE_FULL;
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC522/swift/EC522.asciidoc b/ecocode-rules-specifications/src/main/rules/EC522/swift/EC522.asciidoc
new file mode 100644
index 000000000..010df13d8
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC522/swift/EC522.asciidoc
@@ -0,0 +1,17 @@
+Score ecoCode: 2sur5
+
+Location awareness is one of the most popular features used by apps.
+
+By default, standard location updates run with the best accuracy level, but unless your app really needs to know the user’s position within a few meters, this level of accuracy isn't needed.
+
+Requesting higher accuracy than you need causes the system to power up additional hardware and waste power for unnecessary precision. You can specify a degree of accuracy by setting the `CLLocationManager#desiredAccuracy` property.
+
+Also, setting the `CLLocationManager#activityType` property will let the system knows what type of location activity your app is performing and helps it determine the most appropriate time to perform location updates. Finally, if your app just needs a quick fix on the user’s location, it’s best to call the `CLLocationManager#requestLocation` method, that will deliver a single location update.
+
+## Compliant Code Example
+
+```swift
+let manager = CLLocationManager()
+manager.desiredAccuracy = 2
+```
+
diff --git a/ecocode-rules-specifications/src/main/rules/EC523/EC523.json b/ecocode-rules-specifications/src/main/rules/EC523/EC523.json
new file mode 100644
index 000000000..351c51238
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC523/EC523.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Thrifty Geolocation (minTime)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC523/java/EC523.asciidoc b/ecocode-rules-specifications/src/main/rules/EC523/java/EC523.asciidoc
new file mode 100644
index 000000000..2fb54ab84
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC523/java/EC523.asciidoc
@@ -0,0 +1,21 @@
+With a call to `LocationManager#requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)`, the location provider will only send your application an update when the location has changed by at least minDistance meters AND at least minTime milliseconds have passed. So `minTime` should be the primary tool to conserve battery life, and, to a lesser extent, `minDistance`.
+
+These two must imperatively be greater than 0.
+
+## Noncompliant Code Example
+
+```java
+locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+ 0,
+ 0,
+ this);
+```
+
+## Compliant Code Example
+
+```java
+locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+ 60000L, // refresh location at least each 60000ms
+ 10.0f, // refresh location at least each 10 meters
+ this);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC523/swift/EC523.asciidoc b/ecocode-rules-specifications/src/main/rules/EC523/swift/EC523.asciidoc
new file mode 100644
index 000000000..530e2ff7f
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC523/swift/EC523.asciidoc
@@ -0,0 +1,12 @@
+Score ecoCode: 2sur5
+
+To avoid draining the battery, an iOS device adapt its brightness to the environment .
+
+Hence, keeping forcing the screen brightness on should be avoided, unless it is absolutely necessary. If so, developers typically force the Brightness to 1 with `UIScreen.main.brightness = a float`.
+
+## Noncompliant Code Example
+
+```swift
+UIScreen.main.brightness = CGFloat(0.3)
+```
+
diff --git a/ecocode-rules-specifications/src/main/rules/EC524/EC524.json b/ecocode-rules-specifications/src/main/rules/EC524/EC524.json
new file mode 100644
index 000000000..215a161f0
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC524/EC524.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Thrifty Geolocation Criteria",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
diff --git a/ecocode-rules-specifications/src/main/rules/EC524/java/EC524.asciidoc b/ecocode-rules-specifications/src/main/rules/EC524/java/EC524.asciidoc
new file mode 100644
index 000000000..356629524
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC524/java/EC524.asciidoc
@@ -0,0 +1,23 @@
+Location awareness is one of the most popular features used by apps.
+
+An important point is to try to get the best possible provider (`LocationManager#getBestProvider()`) based on an energy criteria thanks to `Criteria#setPowerRequirement(int level)`, using constant `POWER_LOW` instead of `POWER_HIGH` or `POWER_MEDIUM`.
+
+## Noncompliant Code Example
+
+```java
+locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+ 1000L,
+ 1.0f,
+ this);
+```
+
+## Compliant Code Example
+
+```java
+Criteria criteria = new Criteria();
+criteria.setPowerRequirement(Criteria.POWER_LOW);
+locationManager.requestLocationUpdates(locationManager.getBestProvider(criteria,true),
+ 1000L,
+ 1.0f,
+ this);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC524/swift/EC524.asciidoc b/ecocode-rules-specifications/src/main/rules/EC524/swift/EC524.asciidoc
new file mode 100644
index 000000000..18b4651a1
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC524/swift/EC524.asciidoc
@@ -0,0 +1,21 @@
+Score ecoCode: 2sur5
+
+Turning on the torch mode programmatically must absolutely be avoided because the flashlight is one of the most energy-intensive component.
+
+## Noncompliant Code Example
+
+```swift
+AVCaptureTorchMode.on
+```
+
+or
+
+```swift
+ setTorchModeOn(level: Float)
+```
+
+or
+
+```swift
+torchMode = .on
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC525/EC525.json b/ecocode-rules-specifications/src/main/rules/EC525/EC525.json
new file mode 100644
index 000000000..820a920f9
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC525/EC525.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Thrifty Bluetooth Low Energy (setAdvertiseMode)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC525/java/EC525.asciidoc b/ecocode-rules-specifications/src/main/rules/EC525/java/EC525.asciidoc
new file mode 100644
index 000000000..a1e2af352
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC525/java/EC525.asciidoc
@@ -0,0 +1,17 @@
+With Bluetooth Low Energy technology, a Bluetooth Smart Ready device (the master) will establish a link with a Bluetooth Smart device (the slave). Most often, the slave is a GATT server and the master is a GATT client. GATT capable devices can be discovered using BLE scan process.
+
+The default and preferred advertising mode is `ADVERTISE_MODE_LOW_POWER` when calling `AdvertiseSettings.Builder#setAdvertiseMode(int advertiseMode).`
+
+## Noncompliant Code Example
+
+```java
+AdvertiseSettings.Builder builder = new AdvertiseSettings.Builder();
+builder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY);
+```
+
+## Compliant Code Example
+
+```java
+AdvertiseSettings.Builder builder = new AdvertiseSettings.Builder();
+builder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC526/EC526.json b/ecocode-rules-specifications/src/main/rules/EC526/EC526.json
new file mode 100644
index 000000000..5257b74de
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC526/EC526.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Thrifty Bluetooth Low Energy (requestConnectionPriority)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC526/java/EC526.asciidoc b/ecocode-rules-specifications/src/main/rules/EC526/java/EC526.asciidoc
new file mode 100644
index 000000000..36b25cef1
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC526/java/EC526.asciidoc
@@ -0,0 +1,19 @@
+With Bluetooth Low Energy technology (see BLE API smell), a Bluetooth Smart Ready device (the master) will establish a link with a Bluetooth Smart device (the slave).
+
+Most often, the slave is a GATT server and the master is a GATT client. GATT capable devices can be discovered using BLE scan process.
+
+Invoking `BluetoothGatt#requestConnectionPriority(int connectionPriority)` with the value `CONNECTION_PRIORITY_LOW_POWER`, is recommended to reduce power consumption.
+
+## Noncompliant Code Example
+
+```java
+BluetoothGatt gatt = new BluetoothGatt();
+gatt.requestConnectionPriority(CONNECTION_PRIORITY_HIGH);
+```
+
+## Compliant Code Example
+
+```java
+BluetoothGatt gatt = new BluetoothGatt();
+gatt.requestConnectionPriority(CONNECTION_PRIORITY_LOW_POWER);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC527/EC527.json b/ecocode-rules-specifications/src/main/rules/EC527/EC527.json
new file mode 100644
index 000000000..3a290b995
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC527/EC527.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Thrifty Geolocation (minDistance)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC527/java/EC527.asciidoc b/ecocode-rules-specifications/src/main/rules/EC527/java/EC527.asciidoc
new file mode 100644
index 000000000..2fb54ab84
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC527/java/EC527.asciidoc
@@ -0,0 +1,21 @@
+With a call to `LocationManager#requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)`, the location provider will only send your application an update when the location has changed by at least minDistance meters AND at least minTime milliseconds have passed. So `minTime` should be the primary tool to conserve battery life, and, to a lesser extent, `minDistance`.
+
+These two must imperatively be greater than 0.
+
+## Noncompliant Code Example
+
+```java
+locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+ 0,
+ 0,
+ this);
+```
+
+## Compliant Code Example
+
+```java
+locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
+ 60000L, // refresh location at least each 60000ms
+ 10.0f, // refresh location at least each 10 meters
+ this);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC528/EC528.json b/ecocode-rules-specifications/src/main/rules/EC528/EC528.json
new file mode 100644
index 000000000..15b9d9905
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC528/EC528.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Vibration Free",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC528/java/EC528.asciidoc b/ecocode-rules-specifications/src/main/rules/EC528/java/EC528.asciidoc
new file mode 100644
index 000000000..5698168e1
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC528/java/EC528.asciidoc
@@ -0,0 +1,17 @@
+Shaking of an Android device is possible in all circumstances with a call to `getSystemService(Context.VIBRATOR_SERVICE)` (API 26) or `getSystemService(Context.VIBRATOR.MANAGER.SERVICE)` (API 31).
+ Behind this effect stands a specific miniature hardware component, motor or actuator, that consumes power.
+ As a consequence, its usage must be discouraged, especially since its added value is not clear.
+
+## Noncompliant Code Example
+
+API 26:
+```java
+Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+v.vibrate(400);
+```
+
+API 31:
+```java
+VibratorManager vm = (VibratorManager) getSystemService(Context.VIBRATOR_MANAGER_SERVICE);
+vm.getDefaultVibrator().vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC529/EC529.json b/ecocode-rules-specifications/src/main/rules/EC529/EC529.json
new file mode 100644
index 000000000..53a758843
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC529/EC529.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Thrifty Notification",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
diff --git a/ecocode-rules-specifications/src/main/rules/EC529/java/EC529.asciidoc b/ecocode-rules-specifications/src/main/rules/EC529/java/EC529.asciidoc
new file mode 100644
index 000000000..9dcff316a
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC529/java/EC529.asciidoc
@@ -0,0 +1,30 @@
+Giving information to the end-user through notifications is an important aspect of a modern app.
+
+However, a notification does not necessarily need to be loud and vibrant to achieve its purpose. Default mode is enough. That is why when building a notification with `NotificationManager` there should be no extra calls to the methods `setSound()` nor `setVibrate()` (API26) nor `setVibrationPattern()` (API31) on the builder object.
+
+## Noncompliant Code Example
+
+API 26:
+
+```java
+Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext(), "42");
+notificationBuilder.setVibrate(new long[] {1000, 1000, 1000, 1000, 1000});
+notificationBuilder.setSound(
+ RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
+ Notification.AUDIO_ATTRIBUTES_DEFAULT
+);
+```
+
+API 31:
+
+```java
+NotificationChannel notification = new NotificationChannel("42",
+ "test",
+ NotificationManager.IMPORTANCE_DEFAULT
+);
+notification.setVibrationPattern(new long[]{1000, 1000, 1000, 1000, 1000});
+notification.setSound(
+ RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
+ Notification.AUDIO_ATTRIBUTES_DEFAULT
+);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC530/EC530.json b/ecocode-rules-specifications/src/main/rules/EC530/EC530.json
new file mode 100644
index 000000000..89baa698a
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC530/EC530.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: Torch Free",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
diff --git a/ecocode-rules-specifications/src/main/rules/EC530/java/EC530.asciidoc b/ecocode-rules-specifications/src/main/rules/EC530/java/EC530.asciidoc
new file mode 100644
index 000000000..9357810a6
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC530/java/EC530.asciidoc
@@ -0,0 +1,14 @@
+Turning on the torch mode programmatically with `CameraManager#setTorchMode(..., true)` must absolutely be avoided because the flashlight is one of the most energy-intensive component.
+
+## Noncompliant Code Example
+
+```java
+ CameraManager camManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
+String cameraId = null;
+try {
+ cameraId = camManager.getCameraIdList()[0];
+ camManager.setTorchMode(cameraId, true);
+} catch (CameraAccessException e) {
+ e.printStackTrace();
+}
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC531/EC531.json b/ecocode-rules-specifications/src/main/rules/EC531/EC531.json
new file mode 100644
index 000000000..7d74efb32
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC531/EC531.json
@@ -0,0 +1,18 @@
+{
+ "title": "Sobriety: High Frame Rate",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "5min"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC531/java/EC531.asciidoc b/ecocode-rules-specifications/src/main/rules/EC531/java/EC531.asciidoc
new file mode 100644
index 000000000..a12e6a75f
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC531/java/EC531.asciidoc
@@ -0,0 +1,13 @@
+In Android 11 (API level 30) or higher, a call to `Surface#setFrameRate(float frameRate, int compatibility)` results in a change to the display refresh rate. However, a regular app displays 60 frames per second (60Hz). In order to optimize content refreshes and hence saving energy, this frequency should not be raised to 90Hz or 120Hz, despite this is now supported by many devices.
+
+## Noncompliant Code Example
+
+```java
+surface.setFrameRate(120f, FRAME_RATE_COMPATIBILITY_DEFAULT);
+```
+
+## Compliant Code Example
+
+```java
+surface.setFrameRate(60f, FRAME_RATE_COMPATIBILITY_DEFAULT);
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC532/EC532.json b/ecocode-rules-specifications/src/main/rules/EC532/EC532.json
new file mode 100644
index 000000000..c73038cf1
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC532/EC532.json
@@ -0,0 +1,18 @@
+{
+ "title": "Privacy: Google Tracker",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "privacy",
+ "social",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "ecoScore": "0.4",
+ "defaultSeverity": "Minor"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC532/java/EC532.asciidoc b/ecocode-rules-specifications/src/main/rules/EC532/java/EC532.asciidoc
new file mode 100644
index 000000000..8cec4d695
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC532/java/EC532.asciidoc
@@ -0,0 +1,15 @@
+Importing the `com.google.android.gms.analytics.Tracker` or `com.google.firebase.analytics.FirebaseAnalytics` classes means that the app sends hits to Google Analytics. It is not necessarily sensitive information, but it is a first step towards Google Ads and hence this practice should be discouraged at early stage.
+
+## Noncompliant Code Example
+
+Import of Google Analytics :
+
+```java
+import com.google.android.gms.analytics.Tracker
+```
+
+Import of Firebase Analytics :
+
+```java
+import com.google.firebase.analytics
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC540/EC540.json b/ecocode-rules-specifications/src/main/rules/EC540/EC540.json
new file mode 100644
index 000000000..96150d255
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC540/EC540.json
@@ -0,0 +1,17 @@
+{
+ "title": "Batch: Service Boot Time",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "10min"
+ },
+ "tags": [
+ "batch",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC540/xml/EC540.asciidoc b/ecocode-rules-specifications/src/main/rules/EC540/xml/EC540.asciidoc
new file mode 100644
index 000000000..722d5d683
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC540/xml/EC540.asciidoc
@@ -0,0 +1,19 @@
+Score ecoCode: 2sur5
+
+Services are long-living operations, as components of the apps. However, they can be started in isolation each time the device is next started, without the user's acknowledgement.
+
+This technique should be discouraged because the accumulation of these silent services results in excessive battery depletion that remains unexplained from the end-user's point of view.
+
+In addition, end-users know how to kill applications, but more rarely how to kill services.
+
+Thus, any developer should avoid having a call to `Context#startService()` from a Broadcast Receiver component that has specified an intent-filter for the `BOOT_COMPLETED` action in the manifest.
+
+## Noncompliant Code Example
+
+```xml
+
+
+
+
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC541/EC541.json b/ecocode-rules-specifications/src/main/rules/EC541/EC541.json
new file mode 100644
index 000000000..40788f9f8
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC541/EC541.json
@@ -0,0 +1,17 @@
+{
+ "title": "Idleness: Keep Screen On",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC541/xml/EC541.asciidoc b/ecocode-rules-specifications/src/main/rules/EC541/xml/EC541.asciidoc
new file mode 100644
index 000000000..ddb1cf0c0
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC541/xml/EC541.asciidoc
@@ -0,0 +1,23 @@
+Score ecoCode: 2sur5
+
+To avoid draining the battery, an Android device that is left idle quickly falls asleep.
+
+Hence, keeping the screen on should be avoided, unless it is absolutely necessary. If so, developers typically use the `FLAG_KEEP_SCREEN_ON` in their activity. Another way to implement this is in their application's layout XML file, by using the `android:keepScreenOn` attribute.
+
+## Noncompliant Code Example
+
+```xml
+
+```
+
+## Compliant Code Example
+
+```xml
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC542/EC542.json b/ecocode-rules-specifications/src/main/rules/EC542/EC542.json
new file mode 100644
index 000000000..65f556e46
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC542/EC542.json
@@ -0,0 +1,17 @@
+{
+ "title": "Idleness: Keep CPU On",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "1h"
+ },
+ "tags": [
+ "idleness",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC542/xml/EC542.asciidoc b/ecocode-rules-specifications/src/main/rules/EC542/xml/EC542.asciidoc
new file mode 100644
index 000000000..b3b66f946
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC542/xml/EC542.asciidoc
@@ -0,0 +1,17 @@
+Score ecoCode: 2sur5
+
+To avoid draining the battery, an Android device that is left idle quickly falls asleep.
+
+Hence, keeping the screen on should be avoided, unless it is absolutely necessary.
+
+If so, developers typically use a Power Manager system service feature called wake locks
+by invoking `PowerManager.WakeLock#newWakeLock(int levelAndFlags, String tag)`,
+along with the specific permission `WAKE_LOCK` in their manifest.
+
+## Noncompliant Code Example
+
+```xml
+
+
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC543/EC543.json b/ecocode-rules-specifications/src/main/rules/EC543/EC543.json
new file mode 100644
index 000000000..5c157d61a
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC543/EC543.json
@@ -0,0 +1,17 @@
+{
+ "title": "Power: Compagnion In Background",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "20min"
+ },
+ "tags": [
+ "power",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC543/swift/EC543.asciidoc b/ecocode-rules-specifications/src/main/rules/EC543/swift/EC543.asciidoc
new file mode 100644
index 000000000..818fea1ad
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC543/swift/EC543.asciidoc
@@ -0,0 +1,25 @@
+Score ecoCode: 5sur5
+
+Use device API to check if low power mode is enabled, and adapt resources usage accordingly.
+
+For example, you can reduce frequency of data update if low power mode is enabled.
+
+Your app can query the `ProcessInfo.processInfo.isLowPowerModeEnabled` property at any time to determine whether Low Power Mode is active. Your app can also register to receive notifications when the Low Power Mode state of a device changes, using `NSProcessInfoPowerStateDidChange`.
+
+## Compliant Code Example
+
+```swift
+let isLowPowerModeEnabled = ProcessInfo.processInfo.isLowPowerModeEnabled
+```
+
+or
+
+```swift
+NotificationCenter.default.addObserver(forName: .NSProcessInfoPowerStateDidChange, object: nil, queue: nil) { _ in }
+```
+
+or
+
+```swift
+NotificationCenter.default.addObserver(forName: Notification.Name.NSProcessInfoPowerStateDidChange, object: nil, queue: nil) { _ in }
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC543/xml/EC543.asciidoc b/ecocode-rules-specifications/src/main/rules/EC543/xml/EC543.asciidoc
new file mode 100644
index 000000000..5eec80ead
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC543/xml/EC543.asciidoc
@@ -0,0 +1,11 @@
+Score ecoCode: 2sur5
+
+A negative effect on the device s battery is when an app is paired with a companion device (over Bluetooth, BLE, or Wi-Fi) and that it has been excluded from battery optimizations (run in the background) using the declaration `Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND`.
+
+## Noncompliant Code Example
+
+```xml
+
+
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC544/EC544.json b/ecocode-rules-specifications/src/main/rules/EC544/EC544.json
new file mode 100644
index 000000000..cbfbf69fb
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC544/EC544.json
@@ -0,0 +1,17 @@
+{
+ "title": "Power: Ignore Battery Optimizations",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "1h"
+ },
+ "tags": [
+ "power",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC544/xml/EC544.asciidoc b/ecocode-rules-specifications/src/main/rules/EC544/xml/EC544.asciidoc
new file mode 100644
index 000000000..3abdafaf2
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC544/xml/EC544.asciidoc
@@ -0,0 +1,13 @@
+Score ecoCode: 2sur5
+
+An app holding the permission `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` asks the user to allow it to ignore battery optimizations (that is, put them on the whitelist of apps).
+
+Most applications should not use this; there are many facilities provided by the platform for applications to operate correctly in the various power saving modes.
+
+## Noncompliant Code Example
+
+```xml
+
+
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC545/EC545.json b/ecocode-rules-specifications/src/main/rules/EC545/EC545.json
new file mode 100644
index 000000000..7c63da47f
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC545/EC545.json
@@ -0,0 +1,17 @@
+{
+ "title": "Power: Charge Awareness",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "0min"
+ },
+ "tags": [
+ "power",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Info"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC545/xml/EC545.asciidoc b/ecocode-rules-specifications/src/main/rules/EC545/xml/EC545.asciidoc
new file mode 100644
index 000000000..9d1ebf6cb
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC545/xml/EC545.asciidoc
@@ -0,0 +1,43 @@
+Score ecoCode: 5sur5
+
+It's always good that an app has different behavior when device is connected/disconnected to a power station, or has different battery levels. One can monitor the changes in charging state with a broadcast receiver registered on the actions `ACTION_POWER_CONNECTED` and `ACTION_POWER_DISCONNECTED`, or monitor significant changes in battery level with a broadcast receiver registered on the actions `BATTERY_LOW` and `BATTERY_OKAY`.
+
+## Compliant Code Example
+
+```xml
+
+
+
+
+
+```
+
+or
+
+```xml
+
+
+
+
+
+```
+
+or
+
+```xml
+
+
+
+
+
+```
+
+or
+
+```xml
+
+
+
+
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC546/EC546.json b/ecocode-rules-specifications/src/main/rules/EC546/EC546.json
new file mode 100644
index 000000000..8ec94302d
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC546/EC546.json
@@ -0,0 +1,17 @@
+{
+ "title": "Power: Save Mode Awareness",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "0min"
+ },
+ "tags": [
+ "power",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Info"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC546/xml/EC546.asciidoc b/ecocode-rules-specifications/src/main/rules/EC546/xml/EC546.asciidoc
new file mode 100644
index 000000000..a342353a4
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC546/xml/EC546.asciidoc
@@ -0,0 +1,15 @@
+Score ecoCode: 5sur5
+
+Taking into account when the device is entering or exiting the power save mode is higly desirable for the battery life.
+
+It implies the existence of a broadcast receiver registered on the action `ACTION_POWER_SAVE_MODE_CHANGED`, or programmatically with a call to `PowerManager#isPowerSaveMode().`
+
+## Compliant Code Example
+
+```xml
+
+
+
+
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC547/EC547.json b/ecocode-rules-specifications/src/main/rules/EC547/EC547.json
new file mode 100644
index 000000000..605d0c89d
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC547/EC547.json
@@ -0,0 +1,17 @@
+{
+ "title": "Sobriety: Dark UI (Bright Colors)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "1h"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC547/swift/EC547.asciidoc b/ecocode-rules-specifications/src/main/rules/EC547/swift/EC547.asciidoc
new file mode 100644
index 000000000..10fe4aaa1
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC547/swift/EC547.asciidoc
@@ -0,0 +1,12 @@
+Score ecoCode: 2sur5
+
+Using the Core Motion API, your app can receive continuous motion updates in the form of accelerometer, gyroscope, and device motion (rotation, acceleration, and more) events. Yet you don't often need these updates as soon as they are generated. Before registering to receive these recurring motion updates, you can specify an interval that meets your app’s needs, using `CMMotionManager#accelerometerUpdateInterval`, `CMMotionManager#gyroUpdateInterval`, `CMMotionManager#deviceMotionUpdateInterval` and `CMMotionManager#magnetometerUpdateInterval` properties. The larger the interval, the fewer events are delivered to your app, improving battery life.
+
+## Compliant Code
+
+```swift
+CMMotionManager.accelerometerUpdateInterval = 1000
+CMMotionManager.gyroUpdateInterval = 1000
+CMMotionManager.deviceMotionUpdateInterval = 1000
+CMMotionManager.magnetometerUpdateInterval = 1000
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC547/xml/EC547.asciidoc b/ecocode-rules-specifications/src/main/rules/EC547/xml/EC547.asciidoc
new file mode 100644
index 000000000..4b8bcc02e
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC547/xml/EC547.asciidoc
@@ -0,0 +1,16 @@
+Score ecoCode: 2sur5
+
+Displaying dark colors is particularly beneficial for mobile devices with (AM)OLED screens.
+
+Consequently, custom resources like bright colors values and bitmap images with too high luminance should be avoided.
+
+## Noncompliant Code Example
+
+```xml
+
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC548/EC548.json b/ecocode-rules-specifications/src/main/rules/EC548/EC548.json
new file mode 100644
index 000000000..329f040d9
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC548/EC548.json
@@ -0,0 +1,17 @@
+{
+ "title": "Sobriety: Dark UI (Theme)",
+ "type": "CODE_SMELL",
+ "status": "ready",
+ "remediation": {
+ "func": "Constant\/Issue",
+ "constantCost": "1h"
+ },
+ "tags": [
+ "sobriety",
+ "environment",
+ "ecocode",
+ "android",
+ "eco-design"
+ ],
+ "defaultSeverity": "Major"
+}
\ No newline at end of file
diff --git a/ecocode-rules-specifications/src/main/rules/EC548/xml/EC548.asciidoc b/ecocode-rules-specifications/src/main/rules/EC548/xml/EC548.asciidoc
new file mode 100644
index 000000000..5ea8017df
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC548/xml/EC548.asciidoc
@@ -0,0 +1,29 @@
+Score ecoCode: 2sur5
+
+Developers are allowed to apply native themes for their app, or derive new ones through inheritance. This decision has a significant impact on energy consumption since displaying dark colors is particularly beneficial for mobile devices with (AM)OLED screens.
+
+By default, Android will set Holo to the Dark theme (parent style `Theme.Holo`) and hence switching to the light theme (parent style `Theme.Holo.Light`) within the manifest or in xml themes should be avoided.
+
+## Noncompliant Code Example
+
+```xml
+
+```
+
+or
+
+```xml
+
+```
+
+## Compliant Solution
+
+```xml
+
+```
+
+or
+
+```xml
+
+```
diff --git a/ecocode-rules-specifications/src/main/rules/EC602/swift/EC602.asciidoc b/ecocode-rules-specifications/src/main/rules/EC602/swift/EC602.asciidoc
new file mode 100644
index 000000000..629d5ad5b
--- /dev/null
+++ b/ecocode-rules-specifications/src/main/rules/EC602/swift/EC602.asciidoc
@@ -0,0 +1,29 @@
+Score ecoCode: 5sur5
+
+It's always good that an app has different behavior when device is connected/disconnected to a power station, or has different battery levels. Your app can query the `UIDevice#batteryLevel` and `UIDevice#batteryState` properties at any time to determine the level of charge and the state of the battery.
+
+Your app can also register to receive notifications when the battery level or state changes, using `batteryLevelDidChangeNotification` and `batteryStateDidChangeNotification`.
+
+## Compliant Code Example
+
+```swift
+let level = UIDevice.current.batteryLevel
+```
+
+or
+
+```swift
+let state = UIDevice.current.batteryState
+```
+
+or
+
+```swift
+NotificationCenter.default.addObserver(forName: UIDevice.batteryLevelDidChangeNotification, object: nil, queue: nil) { _ in }
+```
+
+or
+
+```swift
+NotificationCenter.default.addObserver(forName: UIDevice.batteryStateDidChangeNotification, object: nil, queue: nil) { _ in }
+```