Slide 1

Slide 1 text

Android Internals for Developers Effie Barak (@CodingChick)

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Android is based on Linux

Slide 4

Slide 4 text

Basic Android Architecture

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Kernel

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Kernel

Slide 10

Slide 10 text

Kernel 1. OOM Killer

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Kernel 1. OOM Killer 2. Wakelocks

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Init

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Zygote

Slide 22

Slide 22 text

Zygote

Slide 23

Slide 23 text

fork() and exec()

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Processes and UIDs

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

Binder IPC

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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); ... }

Slide 31

Slide 31 text

!

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

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 {

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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; }

Slide 37

Slide 37 text

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; } ...

Slide 38

Slide 38 text

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; } }

Slide 39

Slide 39 text

NetworkInfo info = connectivityManager.getActiveNetworkInfo();

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

System server

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

Window Manager

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

Package manager

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

Activities manager

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

Processes and Activities

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

No content

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

OOM Adjustments

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

No content

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

Starting a new activity

Slide 66

Slide 66 text

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); } }

Slide 67

Slide 67 text

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); } }

Slide 68

Slide 68 text

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) { ... } }

Slide 69

Slide 69 text

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); }

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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); ...

Slide 73

Slide 73 text

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); ... }

Slide 74

Slide 74 text

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); }

Slide 75

Slide 75 text

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()); ...

Slide 76

Slide 76 text

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