$30 off During Our Annual Pro Sale. View Details »

Android Internals for Developers

Android Internals for Developers

Effie Barak

July 14, 2017
Tweet

More Decks by Effie Barak

Other Decks in Programming

Transcript

  1. Android Internals
    for Developers
    Effie Barak
    (@CodingChick)

    View Slide

  2. View Slide

  3. Android is based on Linux

    View Slide

  4. Basic Android Architecture

    View Slide

  5. View Slide

  6. Kernel

    View Slide

  7. View Slide

  8. a process is an instance of a
    computer program that is
    being executed
    -Wikipedia

    View Slide

  9. Kernel

    View Slide

  10. Kernel
    1. OOM Killer

    View Slide

  11. View Slide

  12. View Slide

  13. Kernel
    1. OOM Killer
    2. Wakelocks

    View Slide

  14. View Slide

  15. View Slide

  16. View Slide

  17. View Slide

  18. Init

    View Slide

  19. Init
    4 First user space process
    4 The root of all other processes
    4 Spawns everything else

    View Slide

  20. View Slide

  21. Zygote

    View Slide

  22. Zygote

    View Slide

  23. fork() and exec()

    View Slide

  24. View Slide

  25. Processes and UIDs

    View Slide

  26. View Slide

  27. Binder IPC

    View Slide

  28. ConnectivityManager connectivityManager = (ConnectivityManager)
    MyApplication.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = connectivityManager.getActiveNetworkInfo();

    View Slide

  29. public class ConnectivityManager {
    private final IConnectivityManager mService;
    ...
    public NetworkInfo getActiveNetworkInfo() {
    try {
    return mService.getActiveNetworkInfo();
    } catch (RemoteException e) {
    throw e.rethrowFromSystemServer();
    }
    }
    ...
    }

    View Slide

  30. interface IConnectivityManager
    {
    Network getActiveNetwork();
    Network getActiveNetworkForUid(int uid, boolean ignoreBlocked);
    NetworkInfo getActiveNetworkInfo();
    NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked);
    NetworkInfo getNetworkInfo(int networkType);
    NetworkInfo getNetworkInfoForUid(in Network network, int uid, boolean ignoreBlocked);
    NetworkInfo[] getAllNetworkInfo();
    Network getNetworkForType(int networkType);
    Network[] getAllNetworks();
    NetworkCapabilities[] getDefaultNetworkCapabilitiesForUser(int userId);
    ...
    }

    View Slide

  31. !

    View Slide

  32. View Slide

  33. View Slide

  34. Binder
    public boolean transact(int code, Parcel data, Parcel reply, int flags)
    protected boolean onTransact(int code, Parcel data, Parcel reply,
    int flags) throws RemoteException {

    View Slide

  35. AIDL tool
    4 A bridge between the actual method and the
    transaction
    4 Generates two parts- Proxy and Stub

    View Slide

  36. IConnectivityManager.java- Proxy
    @Override public android.net.Network getActiveNetwork() throws android.os.RemoteException
    {
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    android.net.Network _result;
    try {
    _data.writeInterfaceToken(DESCRIPTOR);
    mRemote.transact(Stub.TRANSACTION_getActiveNetwork, _data, _reply, 0);
    _reply.readException();
    if ((0!=_reply.readInt())) {
    _result = android.net.Network.CREATOR.createFromParcel(_reply);
    }
    else {
    _result = null;
    }
    }
    finally {
    _reply.recycle();
    _data.recycle();
    }
    return _result;
    }

    View Slide

  37. IConnectivityManager.java- Stub
    public static abstract class Stub extends android.os.Binder implements android.net.IConnectivityManager
    {
    ...
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
    switch (code)
    {
    ...
    case TRANSACTION_getActiveNetwork:
    {
    data.enforceInterface(DESCRIPTOR);
    android.net.Network _result = this.getActiveNetwork();
    reply.writeNoException();
    if ((_result!=null)) {
    reply.writeInt(1);
    _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    }
    else {
    reply.writeInt(0);
    }
    return true;
    }
    ...

    View Slide

  38. public class ConnectivityService extends IConnectivityManager.Stub
    implements PendingIntent.OnFinished {
    ...
    @Override
    public NetworkInfo getActiveNetworkInfo() {
    enforceAccessPermission();
    final int uid = Binder.getCallingUid();
    final NetworkState state = getUnfilteredActiveNetworkState(uid);
    filterNetworkStateForUid(state, uid, false);
    maybeLogBlockedNetworkInfo(state.networkInfo, uid);
    return state.networkInfo;
    }
    private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
    final int user = UserHandle.getUserId(uid);
    int vpnNetId = NETID_UNSET;
    synchronized (mVpns) {
    final Vpn vpn = mVpns.get(user);
    if (vpn != null && vpn.appliesToUid(uid)) vpnNetId = vpn.getNetId();
    }
    NetworkAgentInfo nai;
    if (vpnNetId != NETID_UNSET) {
    synchronized (mNetworkForNetId) {
    nai = mNetworkForNetId.get(vpnNetId);
    }
    if (nai != null) return nai.network;
    }
    nai = getDefaultNetwork();
    if (nai != null
    && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, ignoreBlocked)) {
    nai = null;
    }
    return nai != null ? nai.network : null;
    }
    }

    View Slide

  39. NetworkInfo info = connectivityManager.getActiveNetworkInfo();

    View Slide

  40. View Slide

  41. System server

    View Slide

  42. View Slide

  43. Managers in system server
    4 Activity Manager
    4 Window manager
    4 Package manager

    View Slide

  44. Window Manager

    View Slide

  45. Responsiblities
    4 Keep track of window activities
    4 Visibilty
    4 Transitions and animations
    4 Good UI experience
    4 System level gestures

    View Slide

  46. Package manager

    View Slide

  47. Responsiblities
    4 Installation of new applications
    4 Resolving the correct activity
    4 Creating a list of possible activites who can match a
    certain filter

    View Slide

  48. Activities manager

    View Slide

  49. Responsiblities
    4 Managing applications (activities, services, content
    providers)
    4 Managing lifecycles
    4 Managing the actual user
    4 Memory trimming, managing excessive power usage
    4 Handling configuration changes

    View Slide

  50. Managing applications
    4 Stack
    4 Task (process >= 1)
    4 Activity

    View Slide

  51. Processes and Activities

    View Slide

  52. View Slide

  53. View Slide

  54. View Slide

  55. View Slide

  56. Managing Lifecycle
    4 One Resumed app
    4 Has surface/ visible
    4 Thread priority/ cpu affinity
    4 Gain or lose certain permissions
    4 OOM adjustments

    View Slide

  57. OOM Adjustments

    View Slide

  58. View Slide

  59. View Slide

  60. View Slide

  61. View Slide

  62. View Slide

  63. View Slide

  64. oom_adj score:
    4 applyOomAdjLocked and computeOomAdjLocked
    4 AMS gets notified back and removes the Activities
    related

    View Slide

  65. Starting a new activity

    View Slide

  66. public final class ActivityManagerService ... {
    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
    Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
    int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    ...
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
    profilerInfo, null, null, bOptions, false, userId, null, null);
    }
    }

    View Slide

  67. class ActivityStarter {
    final int startActivityMayWait(IApplicationThread caller, int callingUid,
    String callingPackage, Intent intent, String resolvedType,
    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    IBinder resultTo, String resultWho, int requestCode, int startFlags,
    ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
    Bundle bOptions, boolean ignoreTargetSecurity, int userId,
    IActivityContainer iContainer, TaskRecord inTask) {
    ...
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
    }
    }

    View Slide

  68. 1. Find the correct activity
    public class PackageManagerService extends IPackageManager.Stub {
    // Explicit activity
    @Override
    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
    ...
    }
    // Implicit activity
    @Override
    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
    int flags, int userId) {
    ...
    }
    }

    View Slide

  69. 2. Create a new ActivityRecord
    final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
    String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
    String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
    ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
    ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
    TaskRecord inTask) {
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
    intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
    requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
    options, sourceRecord);
    }

    View Slide

  70. 3. Talk to Window Manager to do
    things
    mWindowManager.prepareAppTransition(newTask
    ? r.mLaunchTaskBehind
    ? TRANSIT_TASK_OPEN_BEHIND
    : TRANSIT_TASK_OPEN
    : TRANSIT_ACTIVITY_OPEN, keepCurTransition);

    View Slide

  71. 4. Resume the top activity
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    if (mStackSupervisor.inResumeTopActivity) {
    ...

    View Slide

  72. 5. Decide if we already have a process
    to use
    void startSpecificActivityLocked(ActivityRecord r,
    boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
    r.info.applicationInfo.uid, true);
    ...

    View Slide

  73. 6. Create a new process if we don't
    private final void startProcessLocked(ProcessRecord app, String hostingType,
    String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
    ...
    Process.ProcessStartResult startResult = Process.start(entryPoint,
    app.processName, uid, uid, gids, debugFlags, mountExternal,
    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
    app.info.dataDir, entryPointArgs);
    ...
    }

    View Slide

  74. 7. Start a new process with Zygote
    private static ProcessStartResult startViaZygote(final String processClass,
    final String niceName,
    final int uid, final int gid,
    final int[] gids,
    int debugFlags, int mountExternal,
    int targetSdkVersion,
    String seInfo,
    String abi,
    String instructionSet,
    String appDataDir,
    String[] extraArgs)
    throws ZygoteStartFailedEx {
    ...
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }

    View Slide

  75. 8. When Zygote "calls back"- attach
    the correct activity
    private final boolean attachApplicationLocked(IApplicationThread thread,
    int pid) {
    ...
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
    app.instrumentationUiAutomationConnection, testMode,
    mBinderTransactionTrackingEnabled, enableTrackAllocation,
    isRestrictedBackupMode || !normalMode, app.persistent,
    new Configuration(mConfiguration), app.compat,
    getCommonServicesLocked(app.isolated),
    mCoreSettingsObserver.getCoreSettingsLocked());
    ...

    View Slide

  76. Thanks and credits
    4 Dave Smith
    4 Tim Murray
    4 Dianne Hackborn
    4 Rob Carr

    View Slide