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

Aleksander Piotrowski

April 29, 2015
Tweet

More Decks by Aleksander Piotrowski

Other Decks in Technology

Transcript

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

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

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

    • motivation - hopefully lot more
  4. 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?
  5. The APIs arms race • the more, the better •

    … or just a marketing? • Android Weekly pressure ;-)
  6. android.util.Range • check if a value is in a range

    • check if ranges are equal • get lower/upper values • intersect two ranges
  7. 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; }
  8. Other projects • Svelte in KitKat running low-end on devices

    with 512MB or less • Pi ;-) Google as a telecom
  9. 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
  10. JobScheduler Job Scheduler #1 Job Info #2 Job Info #3

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

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

    mAlarm; private final PendingIntent mStableChargingTriggerIntent; [...] @Override public void onReceive(Context context, Intent intent) { onReceiveInternal(intent); } }
  13. 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); [...] }
  14. 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(); } [...] }
  15. JobScheduler Facebook Google+ Ebay Job Scheduler Service System Service Job

    Battery Time Network *** Job Info Job Info Job Info
  16. 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
  17. Idle mode system has determined that phone is not being

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

    at night, when the phone is next to your bed
  19. Many Googles • not the same Google for every one

    of us • different search results • different ads • fine-grained targeting of contents
  20. 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
  21. // 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 ;-)
  22. 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
  23. @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); } [...]
  24. @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); } [...]
  25. @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); } } }
  26. The “idle” state algorithm • time is not a factor

    at night • sensors not used lying next to the bed
  27. 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
  28. 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