目录
一、system_server进程先容
二、system_server进程启动流程
2.1 startBootstrapServices
2.2 startCoreServices
2.3 startOtherServices
2.4 startApexServices
三、怎样利用体系服务
3.1 app进程调用体系服务
3.2 native进程调用体系服务
3.3 system_server进程中两个服务之间的调用
四、怎样添加一个体系服务
五、怎样裁剪体系服务
六、别的模块
6.1 NativeCrashListener
6.2 Android watchdog
一、system_server进程先容
Android system_server进程由zygote进程fork创建,是framework层的焦点进程,主要由ASM、PMS等体系服务组成,给app提供Binder调用、与native & hal进程通讯。
二、system_server进程启动流程
system_server进程启动入口:
- // frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
- public static void main(String[] argv) {
- ...
- if (startSystemServer) {
- Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
- }
- ...
- }
- private static Runnable forkSystemServer(String abiList, String socketName,
- ZygoteServer zygoteServer) {
- ...
- pid = Zygote.forkSystemServer(
- parsedArgs.mUid, parsedArgs.mGid,
- parsedArgs.mGids,
- parsedArgs.mRuntimeFlags,
- null,
- parsedArgs.mPermittedCapabilities,
- parsedArgs.mEffectiveCapabilities);
- ...
- }
- // frameworks/base/core/java/com/android/internal/os/Zygote.java
- static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
- int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
- ZygoteHooks.preFork();
- int pid = nativeForkSystemServer(
- uid, gid, gids, runtimeFlags, rlimits,
- permittedCapabilities, effectiveCapabilities);
- // Set the Java Language thread priority to the default value for new apps.
- Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
- ZygoteHooks.postForkCommon();
- return pid;
- }
- // frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
- static jint com_android_internal_os_Zygote_nativeForkSystemServer(
- JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
- jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
- jlong effective_capabilities) {
- ...
- // fork出system_server子进程
- pid_t pid = zygote::ForkCommon(env, true, fds_to_close, fds_to_ignore, true);
- // 通过JNI调用SystemServer类的main方法
- if (pid == 0) {
- SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,
- effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
- false, nullptr, nullptr, /* is_top_app= */ false,
- /* pkg_data_info_list */ nullptr,
- /* allowlisted_data_info_list */ nullptr, false, false);
- } else if (pid > 0) {
- ...
- }
- return pid;
- }
复制代码 通过JNI调用SystemServer类的main方法:
- // frameworks/base/services/java/com/android/server/SystemServer.java
- public static void main(String[] args) {
- ...
- new SystemServer().run();
- }
- private void run() {
- ...
- // Start services.
- startBootstrapServices(t);
- startCoreServices(t);
- startOtherServices(t);
- startApexServices(t);
- updateWatchdogTimeout(t);
- ...
- }
复制代码 2.1 startBootstrapServices
启动体系最重要的服务,执行startService和startBootPhase方法,如下:
- // frameworks/base/services/java/com/android/server/SystemServer.java
- private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
- // 启动watchdog线程
- final Watchdog watchdog = Watchdog.getInstance();
- watchdog.start();
- ...
- // 启动AMS
- ActivityTaskManagerService atm = mSystemServiceManager.startService(
- ActivityTaskManagerService.Lifecycle.class).getService();
- mActivityManagerService = ActivityManagerService.Lifecycle.startService(
- mSystemServiceManager, atm);
- mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
- mActivityManagerService.setInstaller(installer);
- mWindowManagerGlobalLock = atm.getGlobalLock();
- // 启动PMS
- mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
- // 启动ThermalManagerService
- mSystemServiceManager.startService(ThermalManagerService.class);
- ...
- mSystemServiceManager.startBootPhase(t, SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
- }
复制代码 startService:通过反射的方式调用服务的onStart方法,
- // frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
- public <T extends SystemService> T startService(Class<T> serviceClass) {
- final String name = serviceClass.getName();
- // Create the service.
- if (!SystemService.class.isAssignableFrom(serviceClass)) {
- throw new RuntimeException("Failed to create " + name
- + ": service must extend " + SystemService.class.getName());
- }
- final T service;
- try {
- Constructor<T> constructor = serviceClass.getConstructor(Context.class);
- service = constructor.newInstance(mContext);
- }
- ...
- startService(service);
- return service;
- }
- public void startService(@NonNull final SystemService service) {
- // Check if already started
- String className = service.getClass().getName();
- if (mServiceClassnames.contains(className)) {
- Slog.i(TAG, "Not starting an already started service " + className);
- return;
- }
- mServiceClassnames.add(className);
- // Register it.
- mServices.add(service);
- // Start it.
- long time = SystemClock.elapsedRealtime();
- try {
- service.onStart();
- }
- }
复制代码 PMS服务执行onStart和startBootPhase方法:
- public void onStart() {
- publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,
- DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);
- publishLocalService(PowerManagerInternal.class, mLocalService);
- Watchdog.getInstance().addMonitor(this);
- Watchdog.getInstance().addThread(mHandler);
- }
- @Override
- public void onBootPhase(int phase) {
- if (phase == PHASE_SYSTEM_SERVICES_READY) {
- systemReady();
- } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
- incrementBootCount();
- } else if (phase == PHASE_BOOT_COMPLETED) {
- synchronized (mLock) {
- ...
- }
- ...
- }
复制代码
| 服务名称
| 作用
| 1
| ArtModuleServiceInitializer
| 初始化 ART 模块服务管理器
| 2
| Watchdog
| 体系守护线程,监听体系服务是否发生死锁
| 3
| platformCompat
| 平台兼容性服务,为其他服务提供兼容性支持
| 4
| FileIntegrityService
| 文件完整性服务,相应应用和体系的完整性请求
| 5
| Installer
| 安装器服务,等待 Installd 启动完成
| 6
| DeviceIdentifiersPolicyService
| 设备标识符策略服务,注册在启动应用程序管理器之前
| 7
| UriGrantsManagerService
| URI 授权管理服务
| 8
| PowerStatsService
| 电源统计数据跟踪服务
| 9
| MemtrackProxyService
| 内存跟踪署理服务,早于 ActivityManagerService 启动
| 10
| AccessCheckingService
| 访问检查服务,提供新的权限和应用操纵实现
| 11
| ActivityManagerService
| 体系焦点服务,管理活动和使命
| 12
| DataLoaderManagerService
| 数据加载器管理服务
| 13
| IncrementalService
| 增量安装服务
| 14
| PowerManagerService
| 电源管理服务
| 15
| ThermalManagerService
| 热管理服务
| 16
| HintManagerService
| 提示管理服务
| 17
| RecoverySystemService
| 设备进入Recovery模式时提供各种功能和操纵
| 18
| LightsService
| LED 和显示背光管理服务
| 19
| DisplayOffloadService
| 显示卸载服务
| 20
| SidekickService
| SidekickService服务通常与其他应用程序一起工作,为用户提供额外的功能和支持
| 21
| DisplayManagerService
| 显示管理器服务
| 22
| DomainVerificationService
| selinux权限验证服务
| 23
| PackageManagerService
| 包管理器服务,管理应用程序包和应用程序
| 24
| DexUseManagerLocal
| 当地 Dex 利用管理器
| 25
| OtaDexOptService
| A/B OTA dexopt 管理服务
| 26
| UserManagerService
| 用户管理服务
| 27
| OverlayManagerService
| 用于管理和处理窗口覆盖(Overlay)相干的操纵
| 28
| ResourcesManagerService
| 资源管理器服务
| 29
| SensorPrivacyService
| 传感器隐私管理服务
| 30
| SensorService
| 传感器服务
| 2.2 startCoreServices
启动体系焦点服务,如下:
- private void startCoreServices(@NonNull TimingsTraceAndSlog t) {
- ...
- mSystemServiceManager.startService(SystemConfigService.class);
- mSystemServiceManager.startService(BatteryService.class);
- mSystemServiceManager.startService(UsageStatsService.class);
- mActivityManagerService.setUsageStatsManager(
- LocalServices.getService(UsageStatsManagerInternal.class));
- mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
- mSystemServiceManager.startService(CachedDeviceStateService.class);
- mSystemServiceManager.startService(BinderCallsStatsService.LifeCycle.class);
- mSystemServiceManager.startService(LooperStatsService.Lifecycle.class);
- mSystemServiceManager.startService(ROLLBACK_MANAGER_SERVICE_CLASS);
- mSystemServiceManager.startService(NativeTombstoneManagerService.class);
- mSystemServiceManager.startService(BugreportManagerService.class);
- mSystemServiceManager.startService(GpuService.class);
- mSystemServiceManager.startService(RemoteProvisioningService.class);
- mSystemServiceManager.startService(CpuMonitorService.class);
- }
复制代码
| 服务名称
| 作用
| 1
| SystemConfigService
| 用于管理和提供体系级别的设置信息。SystemConfigService服务为应用程序和体系组件提供了一种访问体系设置信息的方式
| 2
| BatteryService
| 用于管理和提供电池相干的信息和功能。BatteryService服务为应用程序和体系组件提供了一种访问电池状态和控制电池利用的方式
| 3
| WebViewUpdateService
| 用于管理和提供WebView组件的更新信息。WebView是Android体系中的一个内置组件,用于在应用程序中显示和处理网页内容
| 4
| CachedDeviceStateService
| 用于缓存和提供设备状态信息。这个服务会在设备启动时创建,并在整个体系运行过程中提供设备状态信息
| 5
| BinderCallsStatsService
| 为体系提供了一种网络和分析Binder通讯性能数据的服务
| 6
| LooperStatsService
| 为体系提供了一种网络和分析Looper线程性能数据的服务
| 7
| RollbackManagerService
| 为体系提供了一种管理和实现体系回滚功能的方式,以便在出现题目时快速恢复体系状态
| 8
| NativeTombstoneManagerService
| 为体系提供了一种管理和网络Native堆栈Tombstone信息,以便在进程发生native crash时快速定位题目
| 9
| BugreportManagerService
| 为体系提供了一种管理和实现Bugreport信息,以便在需要时快速网络体系和程序状态信息
| 10
| GpuService
| 为体系提供了一种访问GPU信息和控制GPU利用的服务
| 11
| RemoteProvisioningService
| 为体系提供了一种管理和实现远程设备设置功能,以便在需要时远程设置设备
| 12
| CpuMonitorService
| 用于管理和提供CPU相干的信息和功能
| 2.3 startOtherServices
启动体系别的的服务,如下:
- private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
- ...
- mSystemServiceManager.startService(DropBoxManagerService.class);
- mSystemServiceManager.startService(ALARM_MANAGER_SERVICE_CLASS);
- mSystemServiceManager.startService(CameraServiceProxy.class);
- WindowManagerService.main(context, inputManager, !mFirstBoot,
- pwm, mActivityManagerService.mActivityTaskManager);
- // 这类系统服务可以做裁剪
- if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
- t.traceBegin("StartPrintManager");
- mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
- t.traceEnd();
- }
- }
- if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP)) {
- t.traceBegin("StartCompanionDeviceManager");
- mSystemServiceManager.startService(COMPANION_DEVICE_MANAGER_SERVICE_CLASS);
- t.traceEnd();
-
- // VirtualDeviceManager depends on CDM to control the associations.
- t.traceBegin("StartVirtualDeviceManager");
- mSystemServiceManager.startService(VIRTUAL_DEVICE_MANAGER_SERVICE_CLASS);
- t.traceEnd();
- }
-
- ...
- // 这里会启动launcher进程
- mActivityManagerService.systemReady(() -> { ...}
- ...
- // 启动systemui
- startSystemUi(context, windowManagerF);
- ...
- }
复制代码
| 服务名称
| 作用
| 1
| KeyChainSystemService
| 用于管理和提供密钥链(KeyChain)相干的信息和功能。密钥链是一种在Android体系中存储和管理敏感信息(如暗码、密钥等)的机制,通常用于实现设备安全、数据加密等场景。
| 2
| DropBoxManagerService
| app进程发生ANR、native crash时,网络相干debug信息
| 3
| ContentService
| 为体系提供了一种管理和实现ContentProvider功能的方式,以便在需要时实现数据共享和访问
| 4
| AlarmManagerService
| 定时使命
| 5
| InputManagerService
| 管理和提供输入设备相干的信息和功能
| 6
| DeviceStateManagerService
| 用于管理设备的状态信息
| 7
| WindowManagerService
| 负责管理设备上的窗口和界面。它为应用程序提供了一个同一的接口,用于创建、显示、隐藏、移动、调整巨细等操纵窗口。
| 8
| BluetoothService
| 理蓝牙设备的毗连和通讯。它提供了一系列API,允许应用程序通过蓝牙进行数据互换、文件传输、音频流传输等操纵。
| 9
| StorageManagerService
| 负责管理设备的存储空间。它为应用程序提供了一个同一的接口,用于访问设备的内部存储(如闪存)和外部存储(如SD卡)。
| 10
| OemLockService
| 管理设备的OEM锁定状态
| 11
| DeviceIdleController
| 管理设备的空闲状态。当设备处于空闲状态时,DeviceIdleController可以自动执行一些节能措施,如低落屏幕亮度、关闭无线网络等,以延长设备的电池寿命。
| 12
| DevicePolicyManagerService
| 管理设备的策略和安全设置。
| 13
| StatusBarManagerService
| 管理设备的状态栏。它提供了一系列API,允许应用程序在状态栏上显示通知、图标、进度条等信息。
| 14
| NetworkManagementService
| 管理设备的网络毗连。它提供了一系列API,允许应用程序获取设备的网络状态、毗连类型、IP地址等信息,并可以控制设备的网络毗连。
| 15
| NetworkStatsService
| 统计设备的网络利用情况。它提供了一系列API,允许应用程序获取设备的网络流量统计信息,如总流量、各个应用程序的流量等。
| 16
| NetworkPolicyManagerService
| 管理设备的网络策略。它提供了一系列API,允许设备管理员对设备的网络毗连进行策略管理,如限定应用程序的网络访问、设置网络优先级等。
| 17
| SystemUpdateManagerService
| 管理设备的体系更新。它提供了一系列API,允许对设备的体系更新进行管理,如检查体系更新、下载体系更新、安装体系更新等。
| 18
| NotificationManagerService
| 管理设备的通知。它提供了一系列API,允许应用程序在通知栏上显示通知,如消息通知、提示通知等。
| 19
| DeviceStorageMonitorService
| 监控设备的存储空间。它提供了一系列API,允许应用程序获取设备的存储空间信息,如总容量、已用容量、可用容量等。
| 20
| AudioService
| 管理设备的音频。允许应用程序控制设备的音频输出,如播放音乐、播放铃声等。
| 21
| BroadcastRadioService
| 管理设备的广播电台。允许应用程序吸收广播电台的节目,如消息、音乐等。
| 22
| AdbService
| 管理设备的ADB毗连。允许开发人员通过ADB毗连设备,进行调试和测试。
| 23
| UsbService
| 管理设备的USB毗连。允许应用程序通过USB毗连设备,进行数据传输和通讯
| 24
| GestureLauncher
| 用于识别和相应用户的手势操纵。允许应用程序检测和相应用户的手势操纵,如滑动、捏合、旋转等。
| 25
| SensorNotificationService
| 管理设备的传感器通知。允许应用程序获取设备的传感器信息,如加速率计、陀螺仪等
| 26
| DiskStatsService
| 管理设备的磁盘状态。允许应用程序获取设备的磁盘状态信息,如分区巨细、利用情况等。
| 27
| RuntimeService
| 管理设备的运行时环境。允许应用程序获取设备的运行时信息,如内存利用情况、CPU利用情况等。
| 28
| GraphicsStatsService
| 管理设备的图形性能
| 29
| FaceSensorService
| 管理设备的面部识别功能
| 30
| HealthService
| 用于管理设备的康健状态。允许应用程序获取设备的康健状态信息,如电池电量、温度等。
| 31
| SdkSandboxManagerService
| 管理设备的SDK沙盒环境。允许应用程序获取设备的SDK沙盒信息,如应用程序的权限、资源等。
| 32
| PermissionPolicyService
| 管理设备的权限策略
| 33
| LockSettingsService
| 管理设备的锁定设置,如屏幕锁定方式、暗码等。
| 34
| LauncherAppsService
| 管理设备的启动器应用程序。允许应用程序获取设备的启动器应用程序信息,如启动器应用程序的名称、图标等。
| 35
| AppServiceManager
| 管理设备的应用程序服务
| 36
| GameManagerService
| 用于管理游戏的运行和状态
| 37
| LocationManagerService
| 用于管理设备的位置信息,允许应用程序获取设备的位置信息,如经纬度、海拔等
| 38
| FingerprintSensor
| 管理设备的指纹识别功能
| 39
| IoTSystemService
| 理设备的物联网功能
| 40
| SafetyCenterService
| 理设备的安全功能。允许应用程序获取设备的安全信息,如病毒扫描、防火墙等
|
| 别的体系服务:
KeyAttestationApplicationIdProviderService、BinaryTransparencyService、SchedulingPolicyService、TelecomLoaderService、TelephonyRegistry、EntropyMixer、AccountManagerService、InstallSystemProviders、
RoleManagerService、VibratorManagerService、DynamicSystemService、ConsumerIrService、ResourceEconomy、
CameraServiceProxy、VrManagerService、IpConnectivityMetrics、NetworkWatchlistService、PinnerService、
ProfcollectForwardingService、SignedConfigService、AppIntegrityService、LogcatManagerService、
InputMethodManagerService、AccessibilityManagerService、UiModeManagerService、LocaleManagerService、
GrammaticalInflectionService、AppHibernationService、LockSettingsService、PersistentDataBlockService、
MusicRecognitionManagerService、SpeechRecognitionManagerService、AppPredictionService、
ContentSuggestionsService、SearchUiService、SmartspaceService、FontManagerService、TextServicesManager、
TextClassificationManagerService、NetworkScoreService、RttService、WifiAwareService、WifiP2PService、
LowpanService、PacProxyService、ConnectivityService、MiCarNetService、VpnManagerService、VcnManagementService、UpdateLockService、TimeDetectorService、CountryDetectorService、
TimeZoneDetectorService、AltitudeService、LocationTimeZoneManagerService、GnssTimeUpdateService、
SearchManagerService、WallpaperManagerService、WallpaperEffectsGenerationService、SoundTriggerMiddlewareService、DockObserver、ThermalObserver、WiredAccessoryManagerService、
MidiManagerService、SerialService、HardwarePropertiesManagerService、TwilightService、ColorDisplayService、
SoundTriggerService、TrustManagerService、BackupManager、AppWidgetService、VoiceRecognitionManager、
ContextHubSystemService、NetworkTimeUpdateService、EmergencyAffordanceService、DreamManagerService、
CoverageService、PrintManager、AttestationVerificationService、CompanionDeviceManager、VirtualDeviceManager、RestrictionManager、MediaSessionService、HdmiControlService、TvInteractiveAppManager、TvInputManager、TunerResourceManager、MediaResourceMonitor、
TvRemoteService、MediaRouterService、IrisSensor、FingerprintSensor、BiometricService、
AuthService、DynamicCodeLoggingService、PruneInstantAppsJobService、ShortcutService、
CrossProfileAppsService、PeopleService、MediaMetricsManager、BackgroundInstallControlService、
MediaProjectionManager、WearPowerService、WearConnectivityService、WearDisplayService、
WearTimeService、WearGlobalActionsService、SliceManagerService、
StatsCompanion、StatsPullAtomService、BootstrapAtomService、IncidentCompanionService、
AdServicesManagerService、OnDevicePersonalizationSystemService、MmsService、AutoFillService、
CredentialManagerService、TranslationManagerService、SelectionToolbarManagerService、ClipboardService、
TracingServiceProxy、DeviceSpecificServices、MediaCommunicationService、
AppCompatOverridesService、HealthConnectManagerService等
| 2.4 startApexServices
启动体系apex服务,如下:
- private void startApexServices(@NonNull TimingsTraceAndSlog t) {
- List<ApexSystemServiceInfo> services = ApexManager.getInstance().getApexSystemServices();
- for (ApexSystemServiceInfo info : services) {
- String name = info.getName();
- String jarPath = info.getJarPath();
- t.traceBegin("starting " + name);
- if (TextUtils.isEmpty(jarPath)) {
- mSystemServiceManager.startService(name);
- } else {
- mSystemServiceManager.startServiceFromJar(name, jarPath);
- }
- t.traceEnd();
- }
- }
复制代码 三、怎样利用体系服务
3.1 app进程调用体系服务
以PMS服务为例,app进程通过获取PMS服务署理---PowerManager对象,调用PowerManager中的接口:
- // 获取PowerManager实例
- PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
- // 调用PowerManager类中的接口
- PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLockTag");
复制代码 3.2 native进程调用体系服务
通过binder对parcel数据通讯:
- #include <binder/IServiceManager.h>
- #include <binder/Parcel.h>
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("power"));
- if (!binder) {
- return EXIT_FAILURE;
- }
- Parcel data, result;
- data.writeInterfaceToken(String16("android.os.IPowerManager"));
- char d[] = {0x00};
- data.write(d, sizeof(d));
- // 6表示对应的方法ID
- binder->transact(6, data, &result);
复制代码 大概直接调用binder接口:
- #include <binder/IActivityManager.h>
- #include <binder/IBinder.h>
- #include <binder/IServiceManager.h>
- int openContentProviderFile(const String16& uri)
- {
- int fd = -1;
- sp<IServiceManager> sm = defaultServiceManager();
- sp<IBinder> binder = sm->getService(String16("activity"));
- sp<IActivityManager> am = interface_cast<IActivityManager>(binder);
- if (am != NULL) {
- fd = am->openContentUri(uri);
- }
- return fd;
- }
复制代码 3.3 system_server进程中两个服务之间的调用
system_server进程中的服务间调用属于进程内部通讯。如PMS服务启动时会将内部的mLocalService对象注册到当地service管理中,对外提供一个PowerManagerInternal类及接口,给别的服务调用,如下:
- // 其它服务中通过获取PowerManagerInternal对象,调用接口
- private PackageManagerInternal mPackageManagerInternal;
- mLocalPowerManager = getLocalService(PowerManagerInternal.class);
- mLocalPowerManager.getLowPowerState(
- ServiceType.QUICK_DOZE).batterySaverEnabled);
-
- // frameworks/base/core/java/android/os/PowerManagerInternal.java
- // 抽象方法,在具体实现类中实现
- public abstract PowerSaveState getLowPowerState(int serviceType);
-
- // frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
- public final class PowerManagerService extends SystemService
- implements Watchdog.Monitor {
- ...
- @Override
- public void onStart() {
- // 注册到servicemanager中,用于进程间通信
- publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,
- DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);
- // 加入到本地service中,用于进程内部调用
- publishLocalService(PowerManagerInternal.class, mLocalService);
- ...
- }
- // 内部类继承PowerManagerInternal,并实现父类抽象方法
- final class LocalService extends PowerManagerInternal {
- ...
- @Override
- public PowerSaveState getLowPowerState(@ServiceType int serviceType) {
- return mBatterySaverPolicy.getBatterySaverPolicy(serviceType);
- }
- ...
- }
- ...
- }
复制代码 四、怎样添加一个体系服务
添加步调:
1)准备体系服务代码DemoSystemService.java和Android.bp文件
- // 继承SystemService,实现Watchdog.Monitor接口
- public final class DemoManagerService extends SystemService
- implements Watchdog.Monitor {
- // 服务名称为 "demo"
- String SERVICE_NAME = "demo";
- ...
- // 重写onStart和onBootPhase方法
- @Override
- public void onStart() {
- // 发布服务
- publishBinderService(SERVICE_NAME, mBinderService, /* allowIsolated= */ false,
- DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);
- // 用于监控DemoManagerService是否发生死锁
- Watchdog.getInstance().addMonitor(this);
- Watchdog.getInstance().addThread(mHandler);
- }
-
- @Override
- public void onBootPhase(int phase) {
- ...
- }
- ...
- }
复制代码- filegroup {
- name: "demo--system-service-sources",
- srcs: ["DemoSystemService.java"],
- }
复制代码 2)将services.jar模块编译依赖新增模块
修改frameworks/base/services/Android.bp,如下:
- java_library {
- name: "services",
- ...
- srcs: [":services-main-sources",
- ":demo--system-service-sources"
- ],
- ...
- }
复制代码 3)SystemServer.java中启动Demo服务
修改frameworks/base/services/java/com/android/server/SystemServer.java, 启动DemoSystemService,如下:
- public final class SystemServer implements Dumpable {
- ...
- private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
- t.traceBegin("StartDemoSystemService");
- mSystemServiceManager.startService(DemoSystemService.class);
- t.traceEnd();
- }
- ...
- }
复制代码 4)添加selinux规则
修改system/sepolicy库,添加demo服务的标签和规则,留意添加的服务名称为demo,如下:
- // system/sepolicy/private/compat/32.0/32.0.ignore.cil
- vendor_vm_file
- virtual_device_service
- wallpaper_effects_generation_service
- demo_service
- // system/sepolicy/prebuilts/api/32.0/private/service_contexts
- demo u:object_r:demo_service:s0
- // system/sepolicy/prebuilts/api/32.0/public/service.te
- type demo_service, system_server_service, service_manager_type;
复制代码 五、怎样裁剪体系服务
所谓的体系服务裁剪,就是不让服务启动且别的获取该服务的地方有判空,避免运行时空指针报错。以printmanagerservice服务为例:
- // packagemanager
- public static final String FEATURE_PRINTING = "android.software.print";
- private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
-
- // 这类系统服务可以做裁剪,只需让hasSystemFeature方法返回false
- if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
- t.traceBegin("StartPrintManager");
- mSystemServiceManager.startService(PRINT_MANAGER_SERVICE_CLASS);
- t.traceEnd();
- }
- }
- ...
- }
复制代码 hasSystemFeature实现:
- // 通过mAvailableFeatures得到所有的feature
- public boolean hasSystemFeature(String name, int version) {
- // allow instant applications
- synchronized (mAvailableFeatures) {
- final FeatureInfo feat = mAvailableFeatures.get(name);
- if (feat == null) {
- return false;
- } else {
- return feat.version >= version;
- }
- }
- }
- // 该方法维护mAvailableFeatures列表
- private void addFeature(String name, int version) {
- FeatureInfo fi = mAvailableFeatures.get(name);
- if (fi == null) {
- fi = new FeatureInfo();
- fi.name = name;
- fi.version = version;
- mAvailableFeatures.put(name, fi);
- } else {
- fi.version = Math.max(fi.version, version);
- }
- }
- // 系统启动时会去读取handheld_core_hardware.xml配置文件,存到mAvailableFeatures列表
- SystemConfig() {
- TimingsTraceLog log = new TimingsTraceLog(TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
- log.traceBegin("readAllPermissions");
- try {
- readAllPermissions();
- readPublicNativeLibrariesList();
- } finally {
- log.traceEnd();
- }
- }
- // 读取handheld_core_hardware.xml配置文件
- private void readPermissionsFromXml(final XmlPullParser parser, File permFile,
- int permissionFlag) {
- ...
- case "feature": {
- if (allowFeatures) {
- String fname = parser.getAttributeValue(null, "name");
- int fversion = XmlUtils.readIntAttribute(parser, "version", 0);
- boolean allowed;
- if (!lowRam) {
- allowed = true;
- } else {
- String notLowRam = parser.getAttributeValue(null, "notLowRam");
- allowed = !"true".equals(notLowRam);
- }
- if (fname == null) {
- Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "
- + parser.getPositionDescription());
- } else if (allowed) {
- addFeature(fname, fversion);
- }
- } else {
- logNotAllowedInPartition(name, permFile, parser);
- }
- XmlUtils.skipCurrentTag(parser);
- } break;
- ...
- }
复制代码 只要解释掉<feature name="android.software.print" />,hasSystemFeature方法返回false,printmanagerservice服务就不会启动,如下:
- // frameworks/native/data/etc/handheld_core_hardware.xml
- <!-- basic system services -->
- <feature name="android.software.app_widgets" />
- <feature name="android.software.telecom" />
- <feature name="android.software.voice_recognizers" notLowRam="true" />
- <feature name="android.software.backup" />
- <feature name="android.software.home_screen" />
- <feature name="android.software.input_methods" />
- <feature name="android.software.picture_in_picture" notLowRam="true" />
- <feature name="android.software.activities_on_secondary_displays" notLowRam="true" />
- // <feature name="android.software.print" />
- <feature name="android.software.companion_device_setup" />
- <feature name="android.software.autofill" />
- <feature name="android.software.credentials" />
- <feature name="android.software.cant_save_state" />
- <feature name="android.software.secure_lock_screen" />
- <feature name="android.software.window_magnification" />
- ...
- </permissions>
复制代码- PRODUCT_COPY_FILES := \ frameworks/native/data/etc/handheld_core_hardware.xml:system/etc/permissions/handheld_core_hardware.xml
复制代码 app进程或体系别的服务在利用该服务前会做空判断,避免服务获取不到引入的空指针错误:
- // 服务注册
- registerService(Context.PRINT_SERVICE, PrintManager.class,
- new CachedServiceFetcher<PrintManager>() {
- @Override
- public PrintManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IPrintManager service = null;
- // If the feature not present, don't try to look up every time
- if (ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
- service = IPrintManager.Stub.asInterface(ServiceManager
- .getServiceOrThrow(Context.PRINT_SERVICE));
- }
- final int userId = ctx.getUserId();
- final int appId = UserHandle.getAppId(ctx.getApplicationInfo().uid);
- return new PrintManager(ctx.getOuterContext(), service, userId, appId);
- }});
- public PrintManager(Context context, IPrintManager service, int userId, int appId) {
- mContext = context;
- mService = service;
- ...
- }
- // app进程调用服务相关接口之前会做null判断,避免服务获取失败导致空指针错误
- public PrintJob getPrintJob(PrintJobId printJobId) {
- if (mService == null) {
- Log.w(LOG_TAG, "Feature android.software.print not available");
- return null;
- }
- try {
- PrintJobInfo printJob = mService.getPrintJobInfo(printJobId, mAppId, mUserId);
- if (printJob != null) {
- return new PrintJob(printJob, this);
- }
- } catch (RemoteException re) {
- throw re.rethrowFromSystemServer();
- }
- return null;
- }
- // 其它服务在调用该服务之前会做hasSystemFeature判断是否可用
- @Override
- public int getAvailabilityStatus() {
- return mPackageManager.hasSystemFeature(PackageManager.FEATURE_PRINTING)
- && mPrintManager != null
- ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
- }
复制代码 六、别的模块
6.1 NativeCrashListener
NativeCrashListener线程模块用于监听native crash变乱,即当某个进程发生native crash时,由crash_dump64进程通过socket(ndebugsocket)方式将crash debug信息传给NativeCrashListener模块,并传给AMS服务写入dropbox.
system_server进程启动的systemReady阶段创建NativeCrashListener线程,该线程创建"ndebugsocket" socket服务端,当有进程发生native crash时,crash_dump64客户端进程通过socket与system_server通讯,最后将数据存到"data/system/dropbox"目录。
- // frameworks/base/services/java/com/android/server/SystemServer.java
- mActivityManagerService.systemReady(() -> {
- ...
- mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
- ...
- mActivityManagerService.startObservingNativeCrashes();
- ...
- }
- // rameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
- public void startObservingNativeCrashes() {
- final NativeCrashListener ncl = new NativeCrashListener(this);
- ncl.start();
- }
复制代码- // frameworks/base/services/core/java/com/android/server/am/NativeCrashListener.java
- final class NativeCrashListener extends Thread {
- static final String DEBUGGERD_SOCKET_PATH = "/data/system/ndebugsocket";
- static final long SOCKET_TIMEOUT_MILLIS = 10000;
- final ActivityManagerService mAm;
- // 内部类线程
- class NativeCrashReporter extends Thread {
- ProcessRecord mApp;
- int mSignal;
- boolean mGwpAsanRecoverableCrash;
- String mCrashReport;
- NativeCrashReporter(ProcessRecord app, int signal, boolean gwpAsanRecoverableCrash,
- String report) {
- super("NativeCrashReport");
- mApp = app;
- mSignal = signal;
- mGwpAsanRecoverableCrash = gwpAsanRecoverableCrash;
- mCrashReport = report;
- }
- @Override
- public void run() {
- try {
- CrashInfo ci = new CrashInfo();
- ci.exceptionClassName = "Native crash";
- ci.exceptionMessage = Os.strsignal(mSignal);
- ci.throwFileName = "unknown";
- ci.throwClassName = "unknown";
- ci.throwMethodName = "unknown";
- ci.stackTrace = mCrashReport;
- // crash数据传给AMS,由AMS写入dropbox
- mAm.handleApplicationCrashInner(
- mGwpAsanRecoverableCrash ? "native_recoverable_crash" : "native_crash",
- mApp, mApp.processName, ci);
- if (DEBUG) Slog.v(TAG, "<-- handleApplicationCrash() returned");
- } catch (Exception e) {
- Slog.e(TAG, "Unable to report native crash", e);
- }
- }
- }
- // 在system_server进程启动的systemReady阶段执行,创建socke server,进入循环监听
- @Override
- public void run() {
- final byte[] ackSignal = new byte[1];
- {
- File socketFile = new File(DEBUGGERD_SOCKET_PATH);
- if (socketFile.exists()) {
- socketFile.delete();
- }
- }
- try {
- FileDescriptor serverFd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
- final UnixSocketAddress sockAddr = UnixSocketAddress.createFileSystem(
- DEBUGGERD_SOCKET_PATH);
- Os.bind(serverFd, sockAddr);
- Os.listen(serverFd, 1);
- Os.chmod(DEBUGGERD_SOCKET_PATH, 0777);
- while (true) {
- FileDescriptor peerFd = null;
- try {
- if (MORE_DEBUG) Slog.v(TAG, "Waiting for debuggerd connection");
- peerFd = Os.accept(serverFd, null /* peerAddress */);
- if (MORE_DEBUG) Slog.v(TAG, "Got debuggerd socket " + peerFd);
- if (peerFd != null) {
- // 数据客户端的信息
- consumeNativeCrashData(peerFd);
- }
- } catch (Exception e) {
- Slog.w(TAG, "Error handling connection", e);
- } finally {
- ...
- }
-
- }
- // 读取client socket数据,存到byte[] buffer
- static int readExactly(FileDescriptor fd, byte[] buffer, int offset, int numBytes)
- throws ErrnoException, InterruptedIOException {
- int totalRead = 0;
- while (numBytes > 0) {
- int n = Os.read(fd, buffer, offset + totalRead, numBytes);
- if (n <= 0) {
- if (DEBUG) {
- Slog.w(TAG, "Needed " + numBytes + " but saw " + n);
- }
- return -1; // premature EOF or timeout
- }
- numBytes -= n;
- totalRead += n;
- }
- return totalRead;
- }
- // Read a crash report from the connection
- void consumeNativeCrashData(FileDescriptor fd) {
- final byte[] buf = new byte[4096];
- final ByteArrayOutputStream os = new ByteArrayOutputStream(4096);
- try {
- StructTimeval timeout = StructTimeval.fromMillis(SOCKET_TIMEOUT_MILLIS);
- Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout);
- Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout);
- int headerBytes = readExactly(fd, buf, 0, 9);
- boolean gwpAsanRecoverableCrash = buf[8] != 0;
- ...
- // byte[]转String
- int bytes;
- do {
- // get some data
- bytes = Os.read(fd, buf, 0, buf.length);
- if (bytes > 0) {
- if (MORE_DEBUG) {
- String s = new String(buf, 0, bytes, "UTF-8");
- Slog.v(TAG, "READ=" + bytes + "> " + s);
- }
- // did we just get the EOD null byte?
- if (buf[bytes - 1] == 0) {
- os.write(buf, 0, bytes - 1); // exclude the EOD token
- break;
- }
- // no EOD, so collect it and read more
- os.write(buf, 0, bytes);
- }
- } while (bytes > 0);
- if (!gwpAsanRecoverableCrash) {
- synchronized (mAm) {
- synchronized (mAm.mProcLock) {
- pr.mErrorState.setCrashing(true);
- pr.mErrorState.setForceCrashReport(true);
- }
- }
- }
- final String reportString = new String(os.toByteArray(), "UTF-8");
- (new NativeCrashReporter(pr, signal, gwpAsanRecoverableCrash, reportString)).start();
- } catch (Exception e) {
- Slog.e(TAG, "Exception dealing with report", e);
- // ugh, fail.
- }
- }
- }
复制代码 6.2 Android watchdog
Android watchdog用于监测体系服务、UI线程、动画线程等是否出现死锁或卡死,system_server进程启动时会启动watchdog线程,进入监听,体系服务启动时会加入watchdog监听。
- private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
- ......
- // Start the watchdog as early as possible so we can crash the system server// if we deadlock during early boott.traceBegin("StartWatchdog");
- final Watchdog watchdog = Watchdog.getInstance(); // 对象创建
- watchdog.start(); // 启动watchdong线程
- mDumper.addDumpable(watchdog);
- ......
- }
复制代码
以PMS服务为例,
1)PMS服务实现Watchdog.Monitor接口,服务启动时,将PMS服务对象加入到watchdong的Monitor列表
2)system_server进程启动时,会启动watchdog线程,每隔30s会启动monitor线程调用monitor列表中的PMS对象加锁的monitor方法,如果超过30s没有返回,阐明一直在等待锁,即PMS服务卡死。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |