前言
本文为继RK3128 Android 7 BOX SDK 修改为MID界面 与 RK3128 Android 7 BOX SDK 修改为MID界面-近期任务 后续.
问题
三方应用无法通过接收开机完成广播(BOOT_COMPLETED)完成自启.
LOG如下
Unable to launch app com.test/10033 for broadcast Intent { act=android.intent.action.BOOT_COMPLETED flg=0x9000010 (has extras) }: process is bad
分析解决
首先, LOG输出的位置:
frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java
if ((r.curApp=mService.startProcessLocked(targetProcess, info.activityInfo.applicationInfo, true, r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, "broadcast", r.curComponent, (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false)) == null) { // Ah, this recipient is unavailable. Finish it if necessary, // and mark the broadcast record as ready for the next. Slog.w(TAG, "Unable to launch app " + info.activityInfo.applicationInfo.packageName + "/" + info.activityInfo.applicationInfo.uid + " for broadcast " + r.intent + ": process is bad");
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge) { return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, null /* crashHandler */); } final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { //...省略中间代码... if((("true".equals(SystemProperties.get("ro.config.low_ram", "false"))) ||("true".equals(SystemProperties.get("ro.mem_optimise.enable", "false")))) && (!"true".equals(SystemProperties.get("cts_gts.status", "false")))){ final ActivityRecord next = getFocusedStack().topRunningActivityLocked(); if(next!= null && (!next.packageName.equals(processName)&& !processName.contains("antutu")) && next.packageName.contains("antutu")){ if(DEBUG_LOWMEM)Slog.v("xzj", "process dont start because for antutu: " + next.packageName + "/" + info.processName); return null; } if((mProcessMap.get(processName) != null) && (("broadcast".equals(hostingType))||("content provider".equals(hostingType)))){ if(DEBUG_LOWMEM)Slog.v("xzj", "process dont start because for filter: " + info.uid + "/" + info.processName); return null; } if((mServiceMap.get(processName) != null)&&("service".equals(hostingType))&&((info.flags & ApplicationInfo.FLAG_IS_GAME) !=0)) //for service start by system { if(DEBUG_LOWMEM)Slog.v("xzj", "service dont start auto because for filter: " + info.uid + "/" + info.processName); return null; } if(((info.flags & ApplicationInfo.FLAG_SYSTEM) ==0)&&("broadcast".equals(hostingType))) { //从这里返回 if(DEBUG_LOWMEM)Slog.v("xzj", "third part process dont start for broadcast: " + info.uid + "/" + info.processName); return null; } if(mGameMap.get(processName) != null) { killAllBackgroundProcesses(); if(DEBUG_LOWMEM)Slog.v("xzj", "----clean memory for start " + info.processName); } }
基本可以定位问题点, 进一步验证:
//获取属性值: rk3128_box:/ $ getprop ro.mem_optimise.enable true
判断非系统应用则返回处理.
if(((info.flags & ApplicationInfo.FLAG_SYSTEM) ==0)&&("broadcast".equals(hostingType)))
ro.mem_optimise.enable从属性名可以推断出这是为了优化低内存平台的用户体验, 减少自启应用以降低系统的内存占用率.
解决的方案:
1.ro.mem_optimise.enable 设置为false
2.以上代码中增加白名单, 允许指定第三方应用自启
眠休不黑屏
设置休眠15秒后, 屏幕只是变暗而不关闭:
diff --git a/device/rockchip/common/tv/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml b/device/rockchip/common/tv/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml index 40021f719c..92bdfb40b9 100644 --- a/device/rockchip/common/tv/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml +++ b/device/rockchip/common/tv/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml @@ -26,7 +26,7 @@ <bool name="def_device_provisioned">true</bool> <!-- Keep screen on at all times by default --> - <bool name="def_stay_on_while_plugged_in">true</bool> + <bool name="def_stay_on_while_plugged_in">false</bool> <!-- Do not give up on DHCP --> <integer name="def_max_dhcp_retries">0</integer>
相当代码可以参考看看
进入休眠前的几个函数:
PowerManagerService |-- handleUserActivityTimeout |-- updatePowerStateLocked |-- updateWakefulnessLocked //不进黑屏是到这里后没有进入下一个函数 |-- goToSleepNoUpdateLocked //进入休眠
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC); /** * Updates the value of mStayOn. * Sets DIRTY_STAY_ON if a change occurred. */ private void updateStayOnLocked(int dirty) { if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) { final boolean wasStayOn = mStayOn; if (mStayOnWhilePluggedInSetting != 0 && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) { mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting); } else { mStayOn = false; } if (mStayOn != wasStayOn) { mDirty |= DIRTY_STAY_ON; } } }
/** * Returns true if the device should go to sleep now. * Also used when exiting a dream to determine whether we should go back * to being fully awake or else go to sleep for good. */ private boolean isItBedTimeYetLocked() { return mBootCompleted && !isBeingKeptAwakeLocked(); } /** * Returns true if the device is being kept awake by a wake lock, user activity * or the stay on while powered setting. We also keep the phone awake when * the proximity sensor returns a positive result so that the device does not * lock while in a phone call. This function only controls whether the device * will go to sleep or dream which is independent of whether it will be allowed * to suspend. */ private boolean isBeingKeptAwakeLocked() { return mStayOn || mProximityPositive || (mWakeLockSummary & WAKE_LOCK_STAY_AWAKE) != 0 || (mUserActivitySummary & (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0 || mScreenBrightnessBoostInProgress; } /** * Updates the wakefulness of the device. * * This is the function that decides whether the device should start dreaming * based on the current wake locks and user activity state. It may modify mDirty * if the wakefulness changes. * * Returns true if the wakefulness changed and we need to restart power state calculation. */ private boolean updateWakefulnessLocked(int dirty) { boolean changed = false; if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE | DIRTY_DOCK_STATE)) != 0) { if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) { if (DEBUG_SPEW) { Slog.d(TAG, "updateWakefulnessLocked: Bed time..."); } final long time = SystemClock.uptimeMillis(); if (shouldNapAtBedTimeLocked()) { changed = napNoUpdateLocked(time, Process.SYSTEM_UID); } else { changed = goToSleepNoUpdateLocked(time, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID); } } } return changed; }