AMS は SystemServiceManager を介して起動される#
public final class SystemServer implements Dumpable {
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
... 省略部分
try {
t.traceBegin("StartServices");
// AMS はブートサービスです
startBootstrapServices(t); // ブートサービスを起動
startCoreServices(t); // コアサービスを起動
startOtherServices(t); // その他のサービスを起動
startApexServices(t); // Apexサービスを起動
} /*省略 catch*/
... 省略部分
}
// AMS を起動する関数
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
... 省略部分
// アクティビティマネージャーがショーを実行します。
// ActivityTaskManagerService クラスを作成したことに相当します
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
// ActivityManagerService.Lifecycle.startService を分析
mActivityManagerService = ActivityManagerService
.Lifecycle.startService( // startService は onStart メソッドを呼び出します
mSystemServiceManager,
atm
);
... 省略部分
// その後分析
mActivityManagerService.setSystemProcess();
... 省略部分
}
}
AMS は AMS#Lifecycle 内部クラスを介して作成される#
// ActivityManagerService.java
// SystemService (抽象クラス) を継承
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
private static ActivityTaskManagerService sAtm;
public Lifecycle(Context context) {
super(context);
// AMS を作成
mService = new ActivityManagerService(context, sAtm);
}
// SystemService#startService は onStart メソッドを呼び出します
@Override
public void onStart() {
// AMS プライベート関数 start()
mService.start();
}
... 省略部分
}
SystemService#startService が onStart メソッドを呼び出す#
// ActivityManagerService.java
private void start() {
// バッテリー統計サービスを起動
mBatteryStatsService.publish();
mAppOpsService.publish();
Slog.d("AppOps", "AppOpsService published");
// ローカル LocalServices に追加
LocalServices.addService(ActivityManagerInternal.class, mInternal);
LocalManagerRegistry.addManager(ActivityManagerLocal.class,
(ActivityManagerLocal) mInternal);
mActivityTaskManager.onActivityManagerInternalAdded();
mPendingIntentController.onActivityManagerInternalAdded();
mAppProfiler.onActivityManagerInternalAdded();
}
コンストラクタ#
// /services/core/java/com/android/server/am/ActivityManagerService.java
// AMS 構築関数
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
mInjector = new Injector(systemContext);
// システムレベルの Context
mContext = systemContext;
mFactoryTest = FactoryTest.getMode();
// 現在の ActivityThread を取得
mSystemThread = ActivityThread.currentActivityThread();
// システム UiContext を取得
mUiContext = mSystemThread.getSystemUiContext();
Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
// Handler メッセージを処理するための Handler Thread を作成
mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
// UI 関連メッセージを処理する Handler
mUiHandler = mInjector.getUiHandler(this);
mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",
THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
mProcStartHandlerThread.start();
// プロセス起動の Handler
mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());
// AMS の定数を管理し、ベンダーがシステムを変更する可能性があります
mConstants = new ActivityManagerConstants(mContext, this, mHandler);
final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */);
mPlatformCompat = (PlatformCompat) ServiceManager.getService(
Context.PLATFORM_COMPAT_SERVICE);
mProcessList = mInjector.getProcessList(this);
mProcessList.init(this, activeUids, mPlatformCompat);
mAppProfiler = new AppProfiler(this, BackgroundThread.getHandler().getLooper(),
new LowMemDetector(this));
mPhantomProcessList = new PhantomProcessList(this);
mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
// ブロードキャストポリシーパラメータ
// 前台、后台、アンロードのブロードキャストキューを初期化
// システムは前台ブロードキャストの送信を優先します
final BroadcastConstants foreConstants = new BroadcastConstants(
Settings.Global.BROADCAST_FG_CONSTANTS); // 前台
foreConstants.TIMEOUT = BROADCAST_FG_TIMEOUT;
final BroadcastConstants backConstants = new BroadcastConstants(
Settings.Global.BROADCAST_BG_CONSTANTS); // 背景
backConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;
final BroadcastConstants offloadConstants = new BroadcastConstants(
Settings.Global.BROADCAST_OFFLOAD_CONSTANTS); // アンロード
offloadConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;
// デフォルトでは、このキューに「遅い」ポリシーはありません
offloadConstants.SLOW_TIME = Integer.MAX_VALUE;
mEnableOffloadQueue = SystemProperties.getBoolean(
"persist.device_config.activity_manager_native_boot.offload_queue_enabled", false);
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", foreConstants, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", backConstants, true);
mBgOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
"offload_bg", offloadConstants, true);
mFgOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
"offload_fg", foreConstants, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
mBroadcastQueues[2] = mBgOffloadBroadcastQueue;
mBroadcastQueues[3] = mFgOffloadBroadcastQueue;
// サービスを管理する ActiveServices オブジェクトを初期化
mServices = new ActiveServices(this);
// ContentProvider を初期化
mCpHelper = new ContentProviderHelper(this, true);
// パッケージ WatchDog
mPackageWatchdog = PackageWatchdog.getInstance(mUiContext);
// APP エラーログ記録コンポーネントを初期化
mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog);
mUidObserverController = new UidObserverController(mUiHandler);
// システムディレクトリを取得
final File systemDir = SystemServiceManager.ensureSystemDir();
// TODO: ActivityManagerService の外でバッテリー統計サービスを作成する。
// バッテリー統計サービスを作成
mBatteryStatsService = new BatteryStatsService(systemContext, systemDir,
BackgroundThread.get().getHandler());
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.scheduleWriteToDisk();
mOnBattery = DEBUG_POWER ? true
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
// プロセス統計分析サービスを作成し、プロセスの乱用や悪行を追跡
mBatteryStatsService.getActiveStatistics().setCallback(this);
mOomAdjProfiler.batteryPowerChanged(mOnBattery);
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);
// マルチユーザーを管理する責任を持つ
mUserController = new UserController(this);
mPendingIntentController = new PendingIntentController(
mHandlerThread.getLooper(), mUserController, mConstants);
// システムプロパティを初期化
mUseFifoUiScheduling = SystemProperties.getInt("sys.use_fifo_ui", 0) != 0;
mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
// ActivityTaskManager を付与
mActivityTaskManager = atm;
// 初期化、内部で ActivityStackSupervisor クラスを作成します
// ActivityStackSupervisor は Activity の状態情報を記録し、AMS のコアクラスです
mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,
DisplayThread.get().getLooper());
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
mSdkSandboxSettings = new SdkSandboxSettings(mContext);
// Watchdog 監視 (プロセスが正常でない場合は Kill されます)
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
// バックグラウンドスレッドを小さなコアにバインド
// これはフレームワークテスト内で失敗することが予想されます。なぜならアプリは cpusets に直接触れないからです
// まずシステムサーバーの内部ビューを調整していることを確認してください
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
try {
Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
Process.THREAD_GROUP_SYSTEM);
Process.setThreadGroupAndCpuset(
mOomAdjuster.mCachedAppOptimizer.mCachedAppOptimizerThread.getThreadId(),
Process.THREAD_GROUP_SYSTEM);
} catch (Exception e) {
Slog.w(TAG, "Setting background thread cpuset failed");
}
mInternal = new LocalService();
mPendingStartActivityUids = new PendingStartActivityUids(mContext);
mTraceErrorLogger = new TraceErrorLogger();
mComponentAliasResolver = new ComponentAliasResolver(this);
}
AMS#setSystemProcess メソッドは自分自身 (AMS) のサーバーを Binder ドライバーに登録するだけでなく、一連のプロセス関連のサービスも登録します。以下の表ではいくつかの一般的なサービス項目について言及します。
// /ActivityManagerService.java
public void setSystemProcess() {
try {
// AMS を登録
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
// ProcessStatsService を登録
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_HIGH);
// 以下、さまざまなサービスを登録
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this),
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
ServiceManager.addService("cacheinfo", new CacheBinder(this));
// PackageManagerService のインターフェースを呼び出し、パッケージ名が android のアプリ App の ApplicationInfo 情報を取得
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
// Activity#installSystemApplicationInfo 関数を分析
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
// ProcessRecord オブジェクトを作成し、AMS オブジェクト情報を保存
synchronized (this) {
ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
false,
0,
new HostingRecord("system"));
app.setPersistent(true);
app.setPid(MY_PID);
app.mState.setMaxAdj(ProcessList.SYSTEM_ADJ);
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
addPidLocked(app);
updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
... 省略部分
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
... 省略部分
}
Binder - AMS 機能#
すべての AMS 機能を知るには、IActivityManager を調べるのが最良です。そこには AMS が提供するすべての機能が含まれています。以下は、いくつかのカテゴリに分けて説明します。
コンポーネント状態 - 管理: 4 つの主要コンポーネントの管理、startActivity、startActivityAndWait、startService、stopService、removeContentProvider … など
コンポーネント状態 - クエリ: 現在のコンポーネントの実行状況を確認 getCallingAcitivty、getServices… など
タスク関連:タスク関連の関数、removeSubTask、remove Task … など
その他: getMemoryInfo、setDebugApp… など
AMS 重点クラス#
| AMS 関連クラス | 機能 |
|---|---|
| ActivityStackSupervisor | Activity Stack を管理 |
| ClientLifecycleManager | Android 28 以降に追加され、Activity のライフサイクルを制御管理 |
| ActivityStart | Activity スターターであり、Activity の起動の詳細も管理 |
| ActivityStartController | ActivityStart のインスタンスを生成し、再利用 |
| ActivityTaskManagerService (略称 ATMS) | Android のコアサービスで、4 つのコンポーネントを起動する責任を持つ |
| ActivityTaskManager | Activity と ATMS の間のプロセス間通信のインターフェースで、ATMS の補助クラス |
| ProcessRecord | 身分を記述するデータ |
| RecentTasks | 最近開いた Activity |
| App 関連クラス | 機能 |
|---|---|
| ActivityThread | App アプリケーションのエントリーポイントで、メインスレッドを起動 |
ActivityThread#ApplicationThread | ApplicationThread は ActivityThread の内部クラスで、IApplication.Sub を継承し、APP と AMS の通信のサービス側 |
| Instrumentation | Activity の起動、終了などの操作をフックし、アプリ APP と AMS の相互作用はすべて Instrumentation を介して行われる |
| ActivityStack | Stack 単位で (AndroidManifest の 4 つの起動方法に関連) 複数の Activity を管理 |
ProcessRecord プロセス管理#
ProcessRecord クラス - プロセス関連情報
| パラメータ | 説明 |
|---|---|
| info : ApplicationInfo | AndroidManifest.xml に定義された <\application> タグ関連情報 |
| isolated : Boolean | isolated プロセス |
| uid : int | ユーザー ID |
| pid : int | プロセス ID |
| gids : int[] | グループ ID |
| userId : int | Android のマルチユーザーシステム ID (Windows の複数ユーザー機能に似ています) |
| processName : String | プロセス名、デフォルトではパッケージ名を使用 |
| uidRecord : UidRecord | 使用される uid を記録 |
| thread : IApplicationThread | このオブジェクトを介して AMS が APP にメッセージを送信します。このオブジェクトが null でない場合、その APK は使用可能です |
| procStatFile:String | proc ディレクトリ内の各プロセスには pid で命名されたディレクトリファイルがあり、そのファイルにはプロセスに関連するすべての情報が記録されています。このディレクトリは Linux カーネルによって作成されます |
| compat : CompatibilityInfo | 互換性情報 |
| requiredAbi : String | abi 情報 |
| instructionSet : String | 命令セット |
| mPkgDeps : ArraySet | 現在のプロセスが実行する依存パッケージ |
ProcessRecord クラス - プロセスコンポーネントの説明
| パラメータ | 説明 |
|---|---|
| maxAdj : int | プロセスの Adj 上限 (adjustment) |
| curRawAdj : int | 現在計算中の adj。この値は maxAdj より大きくなる可能性があります |
ProcessRecord クラス - プロセスコンポーネントの説明(4 つの主要コンポーネント関連)
| パラメータ | 説明 | その他 |
|---|---|---|
| mWindowProcessController : WindowProcessController | WindowProcessController を介してすべての Activity を管理 | Activity は ActivityRecord で表されます |
| mServices : ProcessServiceRecord | このプロセス内のすべてのサービス | Service は ServiceRecord で表されます |
| mProviders : ProcessProviderRecord | このプロセス内のすべてのプロバイダー | ContentProvider は ContentProviderRecord で表されます |
| mReceivers : ProcessReceiverRecord | このプロセス内のすべてのレシーバー | ContentProvider は BroadcastRecord で表されます |
ActivityRecord - Activity#
ActivityRecord は Activity のすべての情報を記録し、履歴スタック内の Activity です。内部には ActivityInfo (AndroidManifest 設定)、タスクサービスが記録されています。
final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {
// 所属する Task サービス
final ActivityTaskManagerService mAtmService;
// AndroidManifest 設定の値
final ActivityInfo info;
// WindowsManager トークン
final ActivityRecord.Token appToken;
// プライベートコンストラクタ
// ビルダーパターンを介して ActivityRecord オブジェクトを構築
private ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage,
@Nullable String _launchedFromFeature, Intent _intent, String _resolvedType,
ActivityInfo aInfo, ... /* 省略部分*/ ) {
... 省略部分
}
}
// ActivityStarter.java
// 最後に起動しようとしたアクティビティレコード
private ActivityRecord mLastStartActivityRecord;
private int executeRequest(Request request) {
...省略 Request 分析
// ビルダーを介して AcitiviyRecord を作成
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp) // 各種パラメータを設定
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
// 現在の Activity
mLastStartActivityRecord = r;
... 省略部分
}
Activity の起動 - ActivityTaskManagerService を呼び出す#
ActivityTaskManagerService はシステムサービスでもあり(Binder ドライバーに登録されています)、アプリ側が呼び出すにはプロキシを介さなければなりません。このプロキシが ActivityTaskManager です。
// Activity.java
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
...省略部分のインターフェース {
/*package*/ ActivityThread mMainThread;
private Instrumentation mInstrumentation;
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
... 省略部分
// @ startActivityForResult メソッドを分析
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
// @ execStartActivity メソッドを分析
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this,
// ApplicationThread
mMainThread.getApplicationThread(),
mToken, this,
intent, requestCode, options);
... 省略部分
} else {
... 省略部分
}
}
}
// ---------------------------------------------------------
// ActivityThread .java
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
// アプリケーションスレッドは一つだけ
final ApplicationThread mAppThread = new ApplicationThread();
public ApplicationThread getApplicationThread()
{
return mAppThread;
}
private class ApplicationThread extends IApplicationThread.Stub {
... 省略詳細
}
}
```
- ```java
// Instrumentation.java
public class Instrumentation {
public ActivityResult execStartActivity(
Context who,
IBinder contextThread, // IApplicationThread
IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
... 省略部分
try {
...省略部分
// ActivityTaskManager#startActivity 関数を起動
// whoThread は IApplicationThread です
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getBasePackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
// AMS の結果をチェック
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
}
// ActivityTaskManagerService.java
// SystemService によって起動されたシステムプロセス
// IActivityTaskManager.Stub はサービス側の実装です
public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // IActivityTaskManager は IDE 自動生成クラス
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
}