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.

Db950a4adf54b7a13cd3c70fdcd7e334?s=128

Pierre Crépieux

February 04, 2016
Tweet

Transcript

  1. Le magicien Doze Pierre Crépieux, Orange Labs Marc Poppleton, GDG

    Code d’Armor #DevFestParis & #GDG
  2. Quelque chose a changé

  3. J’ai retrouvé l’autonomie de mon 3310 :)

  4. Mais ...

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

    activity for apps when the devices is unused for long periods of time.”
  6. Pour le développeur

  7. 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
  8. 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.”
  9. Le réseau

  10. La CPU • Android utilise un mécanisme “opportuniste” de mise

    en veille. • Pas de wakelock == Pas de CPU CPU Wakelock Alarm JobScheduler SyncAdapter
  11. Doze, derrière le rideau

  12. 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
  13. Doze • Pas en charge • Ecran éteint • Pas

    de mouvement
  14. DeviceIdleController

  15. Doze, derrière le rideau AOSP services/core/java/com/android/server

  16. 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;
  17. 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);
  18. 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
  19. Doze, derrière le rideau

  20. Doze, derrière le rideau

  21. Doze, derrière le rideau

  22. Doze, derrière le rideau Idle Pending, alias “on est d’accord,

    le user fait rien là hein, c’est bientôt la pause?”
  23. Doze, derrière le rideau

  24. Doze, derrière le rideau Sensing, alias “non mais sérieux, on

    bouge pas là, on peut bien faire la pause non?”
  25. Doze, derrière le rideau

  26. 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…”
  27. Doze, derrière le rideau

  28. Doze, derrière le rideau Idle, alias “Doze”

  29. Doze, derrière le rideau

  30. Doze, derrière le rideau

  31. Doze, derrière le rideau

  32. Doze, derrière le rideau

  33. Doze, derrière le rideau

  34. Doze, derrière le rideau

  35. Doze, derrière le rideau

  36. Doze, derrière le rideau

  37. Doze, derrière le rideau source : http://developer.android.com/training/monitoring-device-state/doze-standby.html

  38. Doze, en pratique

  39. Doze, en pratique

  40. Keepalives * simulation de l’état RRC réalisée avec ARO

  41. Keepalives * simulation de l’état RRC réalisée avec ARO

  42. keepalives DOZ...ZZ …. ZZZ … ING * simulation de l’état

    RRC réalisée avec ARO
  43. keepalives DOZ...ZZ …. ZZZ … ING ou est passé mon

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

    client ? * simulation de l’état RRC réalisée avec ARO
  45. 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
  46. Alors, qu’est-ce qu’on fait?

  47. Whitelist

  48. Whitelist

  49. ...

  50. Utilisons plutôt GCM http://developer.android.com/training/monitoring-device-state/doze-standby.html

  51. High priority or not https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a- message

  52. Ah oui… au fait http://android-developers.blogspot.fr/2015/10/how-google-cloud-messaging-handles-doze.html

  53. Comment tester ?

  54. 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.
  55. 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
  56. 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
  57. 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
  58. Whitelists

  59. 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=[]
  60. 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
  61. 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
  62. Tout les apps sont concernées commit fd854ee58c5d56f84047007ead9f88a767ae956f Author: Dianne Hackborn

    <hackbod@google.com> 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.
  63. vraiment toutes. commit 451c3468b9186790d5381334a736a35f9b1dab36 Author: Dianne Hackborn <hackbod@google.com> Date: Tue

    Jul 21 17:39:46 2015 -0700 Fix issue #22612630: Ensure SMS/Call delivery during Doze Add whitelist timeout for SMS.
  64. vraiment toutes. commit 451c3468b9186790d5381334a736a35f9b1dab36 Author: Dianne Hackborn <hackbod@google.com> 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 <hackbod@google.com> Date: Tue Jul 14 18:48:07 2015 -0700 Bump mms whitelist time up to 1 minute.
  65. “The network is suspended”

  66. 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
  67. 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)
  68. 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
  69. 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
  70. Conclusion

  71. 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!
  72. Merci Pierre Crépieux, Orange Labs Marc Poppleton, GDG Code d’Armor