Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Le magicien Doze - Devfest Paris 2016

Le magicien Doze - Devfest Paris 2016

Durant cette session nous présenterons le fonctionnement de Doze et les mécanismes internes sur lesquels il s'appuie.

Pierre Crépieux

February 04, 2016
Tweet

More Decks by Pierre Crépieux

Other Decks in Programming

Transcript

  1. “Doze reduces battery consumption by deferring background CPU and network

    activity for apps when the devices is unused for long periods of time.”
  2. Pourquoi ? Composant Nexus 5 Nexus 6 screen.on 48.07 170

    screen.full 221 440 cpu.speeds 185.2 350 radio.active 386.2 414 $ adb pull /system/framework/framework-res.apk . $ aapt dump xmltree framework-res.apk res/xml/power_profile.xml unité: mA
  3. Le réseau Screen-Off Traffic Characterization and Optimization in 3G/4G Networks

    ”Based on analyzing real smartphone traffic collected from 20 users over five months, we find that off-screen traffic accounts for 58.5% of the total radio energy consumption although their traffic volume contribution is much smaller. Such unexpected results are attributed to the unique cellular resource management policy that is not well understood by developers, leading to cellular- unfriendly mobile apps.”
  4. La CPU • Android utilise un mécanisme “opportuniste” de mise

    en veille. • Pas de wakelock == Pas de CPU CPU Wakelock Alarm JobScheduler SyncAdapter
  5. Doze • Pas d’accès au réseau • pas de Wake

    lock • Alarm stockées pour plus tard • Pas de synchro à la demande • Une fenêtre de synchro pour tous
  6. Doze, derrière le rideau /** Device is currently active. */

    private static final int STATE_ACTIVE = 0; /** Device is inactve (screen off, no motion) and we are waiting to for idle. */ private static final int STATE_INACTIVE = 1; /** Device is past the initial inactive period, and waiting for the next idle period. */ private static final int STATE_IDLE_PENDING = 2; /** Device is currently sensing motion. */ private static final int STATE_SENSING = 3; /** Device is currently finding location (and may still be sensing). */ private static final int STATE_LOCATING = 4; /** Device is in the idle state, trying to stay asleep as much as possible. */ private static final int STATE_IDLE = 5; /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */ private static final int STATE_IDLE_MAINTENANCE = 6;
  7. Doze, derrière le rideau Start the Chron-O-John! INACTIVE_TIMEOUT = mParser.getLong(KEY_INACTIVE_TIMEOUT,

    !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L); SENSING_TIMEOUT = mParser.getLong(KEY_SENSING_TIMEOUT, !DEBUG ? 4 * 60 * 1000L : 60 * 1000L); LOCATING_TIMEOUT = mParser.getLong(KEY_LOCATING_TIMEOUT, !DEBUG ? 30 * 1000L : 15 * 1000L); MOTION_INACTIVE_TIMEOUT = mParser.getLong(KEY_MOTION_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); IDLE_AFTER_INACTIVE_TIMEOUT = mParser.getLong(KEY_IDLE_AFTER_INACTIVE_TIMEOUT, !COMPRESS_TIME ? 30 * 60 * 1000L : 3 * 60 * 1000L); IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_IDLE_PENDING_TIMEOUT, !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L); MAX_IDLE_PENDING_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_PENDING_TIMEOUT, !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L); IDLE_TIMEOUT = mParser.getLong(KEY_IDLE_TIMEOUT, !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L); MAX_IDLE_TIMEOUT = mParser.getLong(KEY_MAX_IDLE_TIMEOUT, !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L);
  8. Doze, derrière le rideau l-mac-aileen:base marcpoppleton$ adb shell dumpsys deviceidle

    Settings: inactive_to=+30m0s0ms sensing_to=+4m0s0ms locating_to=+30s0ms location_accuracy=20.0m motion_inactive_to=+10m0s0ms idle_after_inactive_to=+30m0s0ms idle_pending_to=+5m0s0ms max_idle_pending_to=+10m0s0ms idle_pending_factor=2.0 idle_to=+60m0s0ms max_idle_to=+6h0m0s0ms idle_factor=2.0 min_time_to_alarm=+60m0s0ms
  9. Doze, derrière le rideau Idle Pending, alias “on est d’accord,

    le user fait rien là hein, c’est bientôt la pause?”
  10. Doze, derrière le rideau Sensing, alias “non mais sérieux, on

    bouge pas là, on peut bien faire la pause non?”
  11. Doze, derrière le rideau Location, alias “Ah mais attend, si

    ça se trouve on est posé sur le siège passager de la voiture…”
  12. keepalives DOZ...ZZ …. ZZZ … ING ou est passé mon

    client ? * simulation de l’état RRC réalisée avec ARO
  13. keepalives DOZ...ZZ …. ZZZ … ING ou est passé mon

    client ? * simulation de l’état RRC réalisée avec ARO
  14. Le réseau a été “suspendu” 220.480972 client -> server 43450

    > 54321 [PSH, ACK] Seq=1 Ack=1 Win=416 Len=30 TSval=5654687 220.501223 server -> client 54321 > 43450 [ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902660180 Le client n’a pas pu envoyer de keepalive, le terminal est IDLE. -> Le serveur initie la fermeture de la socket TCP 520.961055 server -> client 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735141 520.961327 server -> client [TCP Out-Of-Order] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735207 521.068897 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735339 522.212984 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735604 524.333055 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902736134 528.563075 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902737192 537.602813 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902739312 554.253684 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902743552
  15. ...

  16. dumpsys deviceidle pierre ~() $adb shell dumpsys deviceidle -h Device

    idle controller (deviceidle) dump options: [-h] [CMD] -h: print this help text. Commands: step ← parfait pour tester Immediately step to next state, without waiting for alarm. force-idle Force directly into idle mode, regardless of other device state. Use "step" to get out. disable Completely disable device idle mode. enable Re-enable device idle mode after it had previously been disabled. enabled Print 1 if device idle mode is currently enabled, else 0. whitelist Print currently whitelisted apps. whitelist [package ...] Add (prefix with +) or remove (prefix with -) packages. tempwhitelist [package ..] Temporarily place packages in whitelist for 10 seconds.
  17. dumpsys deviceidle pierre ~() $ adb shell dumpsys battery unplug

    ← important pierre ~() $adb shell dumpsys deviceidle ... max_temp_app_whitelist_duration=+5m0s0ms ← hum …???... mms_temp_app_whitelist_duration=+60s0ms sms_temp_app_whitelist_duration=+20s0ms ... Whitelist system apps: com.google.android.gms com.google.android.apps.tycho com.android.omadm.service
  18. Jouons un peu avec GCM... pierre ~() $adb shell dumpsys

    deviceidle step Stepped to: IDLE pierre google-services/android/gcm(master) $./gradlew run -Pmsg=" normal-ttl-10s" ... pierre ~() $date && adb shell dumpsys deviceidle step Jeu 4 fév 2016 16:59:46 CET Stepped to: IDLE_MAINTENANCE pierre ~() $adb logcat | grep "normal-ttl" 02-04 16:59:46.805 10470 11520 D MyGcmListenerService: Message: normal-ttl-10s pierre ~() $adb shell dumpsys deviceidle step Stepped to: IDLE pierre google-services/android/gcm(master) $./gradlew run -Pmsg=" normal-ttl-40s" pierre google-services/android/gcm(master) $./gradlew run -Pmsg=" normal-ttl-20s" ... pierre ~() $date && adb shell dumpsys deviceidle step Jeu 4 fév 2016 17:11:04 CET Stepped to: IDLE_MAINTENANCE pierre ~() $adb logcat | grep "normal-ttl" 02-04 17:11:05.463 10470 11524 D MyGcmListenerService: Message: normal-ttl-40s
  19. Jouons un peu avec GCM... pierre ~() $adb shell dumpsys

    deviceidle step Stepped to: IDLE pierre google-services/android/gcm(master) $./gradlew run -Pmsg=" normal-ttl-0s" on attend quelques secondes pierre ~() $date && adb shell dumpsys deviceidle step Jeu 4 fév 2016 17:07:04 CET Stepped to: IDLE_MAINTENANCE pierre ~() $adb logcat | grep "normal-ttl-0s" ... il n’arrivera jamais
  20. Les whitelists pierre ~() $adb shell dumpsys deviceidle whitelist system-excidle,com.android.providers.downloads,10008

    ... system,com.google.android.gms,10011 system,com.google.android.apps.tycho,10102 system,com.android.omadm.service,10006 pierre ~() $adb shell dumpsys power | grep DeviceIdle mDeviceIdleMode=false mDeviceIdleWhitelist=[10006, 10011, 10102] mDeviceIdleTempWhitelist=[]
  21. Les whitelists pierre ~() $adb shell dumpsys deviceidle step Stepped

    to: IDLE pierre ~() $adb shell dumpsys power | grep DeviceIdle mDeviceIdleMode=true mDeviceIdleWhitelist=[10006, 10011, 10102] mDeviceIdleTempWhitelist=[] pierre google-services/android/gcm(master) $./gradlew run -Pmsg="high" pierre ~() $adb shell dumpsys power | grep DeviceIdle mDeviceIdleMode=true mDeviceIdleWhitelist=[10006, 10011, 10102] mDeviceIdleTempWhitelist=[ 10089] pierre ~() $adb shell dumpsys package | grep -A1 "userId=10089" | tail -n -1| awk '{print $2}' | tr -d '}' gcm.play.android.samples.com.gcmquickstart
  22. Les whitelists pierre ~() $adb shell dumpsys package perm |

    egrep -i "Permission \[.*whiteli.*\]" Permission [com.android.permission.WHITELIST_BLUETOOTH_DEVICE] (f092b57): Permission [android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST] (979bb0a): pierre ~() $adb shell dumpsys package permission android.permission. CHANGE_DEVICE_IDLE_TEMP_WHITELIST Package [com.google.android.gms] (1fb0aef): userId=10011 … requested permissions: android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST install permissions: android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST: granted=true
  23. Tout les apps sont concernées commit fd854ee58c5d56f84047007ead9f88a767ae956f Author: Dianne Hackborn

    <[email protected]> Date: Mon Jul 13 18:00:37 2015 -0700 Fix issue #21626564: MMS should be receivied while Dozing We now place whoever is receiving the MMS on the temporary whitelist while doing so, so they can get network access to download it.
  24. vraiment toutes. commit 451c3468b9186790d5381334a736a35f9b1dab36 Author: Dianne Hackborn <[email protected]> Date: Tue

    Jul 21 17:39:46 2015 -0700 Fix issue #22612630: Ensure SMS/Call delivery during Doze Add whitelist timeout for SMS.
  25. vraiment toutes. commit 451c3468b9186790d5381334a736a35f9b1dab36 Author: Dianne Hackborn <[email protected]> Date: Tue

    Jul 21 17:39:46 2015 -0700 Fix issue #22612630: Ensure SMS/Call delivery during Doze Add whitelist timeout for SMS. commit 0b6134b511e0aae7b834fd30198d464f1e13a6fa Author: Dianne Hackborn <[email protected]> Date: Tue Jul 14 18:48:07 2015 -0700 Bump mms whitelist time up to 1 minute.
  26. Que se passe t’il ? 220.480972 client -> server 43450

    > 54321 [PSH, ACK] Seq=1 Ack=1 Win=416 Len=30 TSval=5654687 220.501223 server -> client 54321 > 43450 [ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902660180 Le client n’a pas pu envoyer de keepalive, le terminal est IDLE. -> Le serveur initie la fermeture de la socket TCP 520.961055 server -> client 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735141 520.961327 server -> client [TCP Out-Of-Order] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735207 521.068897 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735339 522.212984 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902735604 524.333055 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902736134 528.563075 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902737192 537.602813 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902739312 554.253684 server -> client [TCP Retransmission] 54321 > 43450 [FIN, ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=902743552
  27. Que se passe t’il ? pierre ~() $date && adb

    shell dumpsys deviceidle step Jeu 4 fév 2016 17:30:50 CET Stepped to: IDLE pierre ~c() $date && adb shell dumpsys deviceidle step Jeu 4 fév 2016 17:31:21 CET Stepped to: IDLE_MAINTENANCE pierre ~() $adb shell dumpsys network_management NetworkManagementService NativeDaemonConnector Log: 02-04 17:30:49.940 - SND -> {670 firewall enable_chain dozable} 02-04 17:30:50.017 - RCV <- {200 670 Firewall command succeeded} 02-04 17:30:50.472 - RCV <- {613 IfaceClass active 1 115009742628503 10011} 02-04 17:31:05.520 - RCV <- {613 IfaceClass idle 1 115024789256726} 02-04 17:31:20.864 - SND -> {671 firewall disable_chain dozable} 02-04 17:31:20.930 - RCV <- {200 671 Firewall command succeeded} 02-04 17:31:21.341 - RCV <- {613 IfaceClass active 1 115040611178491 10011} Netd va mettre en place une rêgle iptables qui DROP les paquets s’ils ne sont pas destinés à une app whitelistée. (cf AOSP android/platform/system/netd/server/FirewallController.cpp)
  28. La preuve keepalive 230.312029 client -> server TCP [TCP segment

    of a reassembled PDU] 230.609162 client -> server TCP [TCP Retransmission] 44478 > 54321 [PSH, ACK] Seq=1 Ack=1 Win=427 Len=30 TSval=6134585 230.689209 server -> client TCP 54321 > 44478 [ACK] Seq=1 Ack=31 Win=91 Len=0 TSval=426601175 device IDLE (NB: apparemment un paquet est envoyé upstream sur la socket GCM…) 331.153298 client -> server2 TCP 38325 > 5228 [PSH, ACK] Seq=131 Ack=34 Win=347 Len=99 TSval=6144639 331.567524 server2 -> client TCP 5228 > 38325 [ACK] Seq=34 Ack=230 Win=350 Len=0 TSval=1275954756 device IDLE_MAINTENANCE (NB: apparemment un autre paquet est envoyé upstream sur la socket GCM…) 353.675591 client -> server2 TCP 38325 > 5228 [PSH, ACK] Seq=230 Ack=34 Win=347 Len=98 TSval=6146891 354.096836 server2 -> client TC 5228 > 38325 [ACK] Seq=34 Ack=328 Win=350 Len=0 TSval=1275977256 keepalive (le keepalive passe sans problème alors que nous avons été IDLE pendant un temps) 510.331184 client -> server TCP [TCP segment of a reassembled PDU] 510.719417 client -> server TCP [TCP Retransmission] [TCP segment of a reassembled PDU] 510.745991 server -> client TCP 54321 > 44478 [ACK] Seq=1 Ack=61 Win=91 Len=0 TSval=426671166 510.876111 server -> client TCP [TCP Dup ACK 133#1] 54321 > 44478 [ACK] Seq=1 Ack=61 Win=91 Len=0
  29. DEVICE_IDLE_MODE_CHANGED pierre ~() $date && adb shell dumpsys deviceidle step

    Jeu 4 fév 2016 18: 01:48 CET Stepped to: IDLE pierre ~() $date && adb shell dumpsys deviceidle step Jeu 4 fév 2016 18: 02:09 CET Stepped to: IDLE_MAINTENANCE pierre ~() $adb logcat ... 02-04 18:01:48.256 935 935 D JobSchedulerService: Receieved: android.os. action.DEVICE_IDLE_MODE_CHANGED ... 02-04 18:02:10.396 935 935 D JobSchedulerService: Receieved: android.os. action.DEVICE_IDLE_MODE_CHANGED
  30. Conclusion • Doze n’est pas une solution miracle aux mauvaises

    pratiques • Utilisez les ressources réseaux intelligemment pour le mode Active • Intégrez Doze dans le cycle de votre app mais aussi dans celui de votre backend! • Testez votre app!