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

Android Lollipop Internals and our inferiority complex 

Android Lollipop Internals and our inferiority complex 

Presentation from droidcon Zagreb 2015
While going through JobScheduler internals try to answer the following question: How big is the gap between us and rockstar developers from Google or Square

F3f71a3003c496bb78fac5736288373b?s=128

Aleksander Piotrowski

April 29, 2015
Tweet

Transcript

  1. Android Lollipop Internals and our inferiority complex

  2. +AleksanderPiotrowski @pelotasplus

  3. About presentation

  4. Inferiority complex • mine but maybe yours as well? •

    gets better with each PR or a talk • … or look taken at others code
  5. History • originally as “What’s new in Lollipop” • about

    new APIs • how it works under the hood • the devil is in the detail
  6. What to look for • technical information - a bit

    • motivation - hopefully lot more
  7. Disclaimer

  8. Disclaimer • nothing against the Google • actually make a

    living thanks to their technologies
  9. Disclaimer • don’t want to diminish their achievements • or

    suggest anything bad about their devs
  10. Disclaimer • have never been recruited by them

  11. The APIs arms race

  12. None
  13. The APIs arms race • each new release thousands new

    APIs • iOS 8 includes over 4,000 new APIs • thousands of new Material Designs or new Bluetooth stacks?
  14. The APIs arms race • the more, the better •

    … or just a marketing? • Android Weekly pressure ;-)
  15. Lollipop

  16. Significant changes • Material Design • WebView updated via Play

    Store • FDE
  17. Significant changes • Bluetooth stack changes • Android Work/Multi-user -

    BYOD • JobScheduler API
  18. None
  19. None
  20. One random change • new package android.util.Range • immutable range

  21. android.util.Range • check if a value is in a range

    • check if ranges are equal • get lower/upper values • intersect two ranges
  22. Range::contains(value) public boolean contains(T value) { checkNotNull(value, "value must not

    be null"); boolean gteLower = value.compareTo(mLower) >= 0; boolean lteUpper = value.compareTo(mUpper) <= 0; return gteLower && lteUpper; }
  23. The Projects

  24. Project Butter • in JellyBean • smoother UI 60fps

  25. Other projects • Svelte in KitKat running low-end on devices

    with 512MB or less • Pi ;-) Google as a telecom
  26. Project Volta • improve battery life

  27. Project Volta • at platform level • at developers level

    • at users level
  28. Project Volta • ART runtime • JobScheduler API and Battery

    Historian • Battery Saver
  29. JobScheduler API

  30. JobScheduler Our App Task

  31. JobInfo.Builder builder = new JobInfo.Builder(jobId, serviceComponent) .setMinimumLatency(4000) .setOverrideDeadline(5000) .setRequiredNetworkType( JobInfo.NETWORK_TYPE_UNMETERED)

    .setRequiresCharging(true) .setPersisted(true); JobInfo jobInfo = builder.build(); constraints our task task is now a job
  32. JobScheduler Our App Job Info JobInfo.Builder

  33. JobScheduler Our App Job Info JobInfo.Builder schedule() Job Scheduler

  34. Job Scheduler System Service

  35. Job Scheduler System Service Battery Service android.content.Intent#ACTION_BATTERY_CHANGED

  36. Job Scheduler System Service Battery Service android.content.Intent#ACTION_BATTERY_CHANGED WebView Update Service

    android.content.Intent #ACTION_PACKAGE_REPLACED
  37. JobScheduler Job Scheduler Job Info

  38. JobScheduler Job Scheduler #1 Job Info #2 Job Info #3

    Job Info /data/system/job/jobs.xml
  39. JobScheduler Job Scheduler #1 Job Info #2 Job Info #3

    Job Info /data/system/job/jobs.xml Battery Time Network ***
  40. BatteryController public class ChargingTracker extends BroadcastReceiver { private final AlarmManager

    mAlarm; private final PendingIntent mStableChargingTriggerIntent; [...] @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } }
  41. BatteryController public void startTracking() { IntentFilter filter = new IntentFilter();

    // Battery health. filter.addAction(Intent.ACTION_BATTERY_LOW); filter.addAction(Intent.ACTION_BATTERY_OKAY); // Charging/not charging. filter.addAction(Intent.ACTION_POWER_CONNECTED); filter.addAction(Intent.ACTION_POWER_DISCONNECTED); // Charging stable. filter.addAction(ACTION_CHARGING_STABLE); mContext.registerReceiver(this, filter); [...] }
  42. BatteryController public void onReceiveInternal(Intent intent) { final String action =

    intent.getAction(); if (Intent.ACTION_BATTERY_LOW.equals(action)) { [...] // If we get this action, the battery is discharging => it isn't plugged in so // there's no work to cancel. We track this variable for the case where it is // charging, but hasn't been for long enough to be healthy. mBatteryHealthy = false; } else if (Intent.ACTION_BATTERY_OKAY.equals(action)) { [...] mBatteryHealthy = true; maybeReportNewChargingState(); } [...] }
  43. JobSchedulerCompat

  44. JobScheduler Facebook Google+ Ebay Job Scheduler Service System Service Job

    Battery Time Network *** Job Info Job Info Job Info
  45. JobSchedulerCompat Facebook Google+ Ebay Battery Time Network *** Job Info

    Job Info Job Scheduler Service Job Scheduler Service Job Scheduler Service Job Info Battery Time Network *** System Service
  46. The Idle mode ***

  47. None
  48. https://www.youtube.com/watch?v=KzSKIpJepUw

  49. Idle mode system has determined that phone is not being

    used and is not likely to be used anytime soon
  50. Idle mode example Job criteria: idle state + charging When:

    at night, when the phone is next to your bed
  51. Digression #1 Many Googles

  52. Many Googles • not the same Google for every one

    of us • different search results • different ads • fine-grained targeting of contents
  53. None
  54. None
  55. None
  56. Almost there... • strong technology marketing videos, blog posts, APIs

    arms race • bold statements about possibilities idle state, at night, next to the bed • proven track record search and ads tailored to our behaviour
  57. The idle state algorithm or is it “idle”?

  58. // Policy: we decide that we're "idle" if the device

    has been unused / // screen off or dreaming for at least this long private static final long INACTIVITY_IDLE_THRESHOLD = 71 * 60 * 1000; // millis; 71 min private static final long IDLE_WINDOW_SLOP = 5 * 60 * 1000; // 5 minute window, to be nice quotes are here ;-)
  59. The “idle” state algorithm 1. display turns off 2. start

    the timer for 71 minutes +/- 5 minutes 3. alarm goes off 4. if screen still turned off we are in the idle state
  60. @Override public void onReceive(Context context, Intent intent) { final String

    action = intent.getAction(); if (action.equals(Intent.ACTION_SCREEN_ON) || action.equals(Intent.ACTION_DREAMING_STOPPED)) { // possible transition to not-idle if (mIdle) { [...] mAlarm.cancel(mIdleTriggerIntent); mIdle = false; reportNewIdleState(mIdle); } [...]
  61. @Override public void onReceive(Context context, Intent intent) { final String

    action = intent.getAction(); [...] } else if (action.equals(Intent.ACTION_SCREEN_OFF) || action.equals(Intent.ACTION_DREAMING_STARTED)) { // when the screen goes off or dreaming starts, we schedule the // alarm that will tell us when we have decided the device is // truly idle. final long nowElapsed = SystemClock.elapsedRealtime(); final long when = nowElapsed + INACTIVITY_IDLE_THRESHOLD; if (DEBUG) { Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when=" + when); } mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, IDLE_WINDOW_SLOP, mIdleTriggerIntent); } [...]
  62. @Override public void onReceive(Context context, Intent intent) { final String

    action = intent.getAction(); [...] } else if (action.equals(ACTION_TRIGGER_IDLE)) { // idle time starts now if (!mIdle) { if (DEBUG) { Slog.v(TAG, "Idle trigger fired @ " + SystemClock.elapsedRealtime()); } mIdle = true; reportNewIdleState(mIdle); } } }
  63. The “idle” state algorithm • time is not a factor

    at night • sensors not used lying next to the bed
  64. The “idle” state algorithm • display the only factor how

    long is being turned off • not tuned per user same for everyone not based on our own behaviour
  65. The “idle” state algorithm • random 71 minutes or maybe

    there is some magic here?
  66. Takeaways • don’t be afraid to look at the code

    not a rocket science there can cure from inferiority complex • write code to get better it always sucks with the first version gets better which each commit or PR
  67. Thanks • droidcon Zagreb • YOU <3 for attending my

    talk and others too ;-)