Android Internals for Developers

Android Internals for Developers

Bcc14b45a86f42cd22d9102a96bc8a5c?s=128

Effie Barak

July 14, 2017
Tweet

Transcript

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

  2. None
  3. Android is based on Linux

  4. Basic Android Architecture

  5. None
  6. Kernel

  7. None
  8. a process is an instance of a computer program that

    is being executed -Wikipedia
  9. Kernel

  10. Kernel 1. OOM Killer

  11. None
  12. None
  13. Kernel 1. OOM Killer 2. Wakelocks

  14. None
  15. None
  16. None
  17. None
  18. Init

  19. Init 4 First user space process 4 The root of

    all other processes 4 Spawns everything else
  20. None
  21. Zygote

  22. Zygote

  23. fork() and exec()

  24. None
  25. Processes and UIDs

  26. None
  27. Binder IPC

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

  29. public class ConnectivityManager { private final IConnectivityManager mService; ... public

    NetworkInfo getActiveNetworkInfo() { try { return mService.getActiveNetworkInfo(); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } ... }
  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); ... }
  31. !

  32. None
  33. None
  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 {
  35. AIDL tool 4 A bridge between the actual method and

    the transaction 4 Generates two parts- Proxy and Stub
  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; }
  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; } ...
  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; } }
  39. NetworkInfo info = connectivityManager.getActiveNetworkInfo();

  40. None
  41. System server

  42. None
  43. Managers in system server 4 Activity Manager 4 Window manager

    4 Package manager
  44. Window Manager

  45. Responsiblities 4 Keep track of window activities 4 Visibilty 4

    Transitions and animations 4 Good UI experience 4 System level gestures
  46. Package manager

  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
  48. Activities manager

  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
  50. Managing applications 4 Stack 4 Task (process >= 1) 4

    Activity
  51. Processes and Activities

  52. None
  53. None
  54. None
  55. None
  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
  57. OOM Adjustments

  58. None
  59. None
  60. None
  61. None
  62. None
  63. None
  64. oom_adj score: 4 applyOomAdjLocked and computeOomAdjLocked 4 AMS gets notified

    back and removes the Activities related
  65. Starting a new activity

  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); } }
  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); } }
  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) { ... } }
  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); }
  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);
  71. 4. Resume the top activity boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options)

    { if (mStackSupervisor.inResumeTopActivity) { ...
  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); ...
  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); ... }
  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); }
  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()); ...
  76. Thanks and credits 4 Dave Smith 4 Tim Murray 4

    Dianne Hackborn 4 Rob Carr