視頻播放選擇懸浮窗播放,按home鍵回到Launcher封孙,此時懸浮窗視頻再切換成全屏播放迹冤,需要等待5秒原因分析
問題現(xiàn)象:
視頻播放選擇懸浮窗播放,按home鍵回到Launcher虎忌,此時懸浮窗視頻再切換成全屏播放叁巨,需要等待5秒左右。
問題分析:
//按Home進(jìn)入Launcher
03-05 15:43:58.047?? 620?? 840 I ActivityManager: ->startActivity for ActivityRecord{52345cc u0 com.android.launcher3/.Launcher t483} result:2
//從懸浮窗啟動全屏播放intent
03-05 15:43:59.782?? 620?? 982 I ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://media/external/video/media/1190 flg=0x10000001 cmp=com.android.gallery3d/com.sprd.gallery3d.app.Video (has extras)} from uid 10025, pid 1497
03-05 15:43:59.785?? 620?? 982 W ActivityManager: Activity start request from 10025 stopped
//此時AMS返回START_SWITCHES_CANCELED
03-05 15:43:59.786?? 620?? 982 I ActivityManager: ->startActivity for Intent { act=android.intent.action.VIEW dat=content://media/external/video/media/1190 flg=0x10000001 cmp=com.android.gallery3d/com.sprd.gallery3d.app.Video (has extras) }, return START_SWITCHES_CANCELED
//5秒后又一次發(fā)送全屏播放的intent
03-05 15:44:02.932?? 620?? 707 I ActivityManager: ->startActivity for ActivityRecord{136e33d u0 com.android.gallery3d/com.sprd.gallery3d.app.Video t484} result:0
AMS分析為google原生行為:
如果App想馬上啟動呐籽,不被pending 5s,需要在App的AndroidManifest.xml內(nèi)申請如下permission:
android.permission.STOP_APP_SWITCHES
并且需要在frameworks/base/data/etc/privapp-permissions-platform.xml
申明蚀瘸,不然會導(dǎo)致CTS不過:
代碼分析:
ActivityStarter.java startActivityLocked()方法中:
說到如果啟動Activity和當(dāng)前resumed的UID不相同就會檢查app?switches權(quán)限
//?If?we?are?starting?an?activity?that?is?not?from?the?same?uid?as?the?currently?resumed?one,?check?whether?app?switches?are?allowed.??
if?(voiceSession?==?null?&&?(stack.getResumedActivity()?==?null??
Launcher主界面從懸浮窗回到全屏播放狡蝶,此時resumed uid是Launcher,但是realCallingUid卻是Gallery贮勃,所以會進(jìn)入checkAppSwitchAllowedLocked流程
????????||?stack.getResumedActivity().info.applicationInfo.uid?!=?realCallingUid))?{??
????if?(!mService.checkAppSwitchAllowedLocked(callingPid,?callingUid,??
????????????realCallingPid,?realCallingUid,?"Activity?start"))?{??
????????mController.addPendingActivityLaunch(new?PendingActivityLaunch(r,??
????????????????sourceRecord,?startFlags,?stack,?callerApp));??
????????ActivityOptions.abort(checkedOptions);??
????????Slog.i(TAG,?"->startActivity?for?"?+?intent?+?",?return?START_SWITCHES_CANCELED");??
????????return?ActivityManager.START_SWITCHES_CANCELED;??
????}??
}??
看看checkAppSwitchAllowedLocked()是如何檢查權(quán)限的:
boolean?checkAppSwitchAllowedLocked(int?sourcePid,?int?sourceUid,??
????????int?callingPid,?int?callingUid,?String?name)?{??
mAppSwitchesAllowedTime?表示按HOME鍵后贪惹,在當(dāng)前系統(tǒng)的時間上加上5秒,這里判斷也就表明按home鍵5s后寂嘉,再切回全屏播放就不會出現(xiàn)遲?
???if?(mAppSwitchesAllowedTime?<?SystemClock.uptimeMillis())?{??
????????return?true;??
????}??
????if?(mRecentTasks.isCallerRecents(sourceUid))?{??
????????return?true;??
????}??
??檢查應(yīng)用是否有android.permission.STOP_APP_SWITCHES權(quán)限
????int?perm?=?checkComponentPermission(STOP_APP_SWITCHES,?sourcePid,?sourceUid,?-1,?true);??
????if?(perm?==?PackageManager.PERMISSION_GRANTED)?{??
????????return?true;??
????}??
????if?(checkAllowAppSwitchUid(sourceUid))?{??
????????return?true;??
????}??
????//?If?the?actual?IPC?caller?is?different?from?the?logical?source,?then??
????//?also?see?if?they?are?allowed?to?control?app?switches.??
????if?(callingUid?!=?-1?&&?callingUid?!=?sourceUid)?{??
????????perm?=?checkComponentPermission(STOP_APP_SWITCHES,?callingPid,?callingUid,?-1,?true);??
????????if?(perm?==?PackageManager.PERMISSION_GRANTED)?{??
????????????return?true;??
????????}??
????????if?(checkAllowAppSwitchUid(callingUid))?{??
????????????return?true;??
????????}??
????}??
????Slog.w(TAG,?name?+?"?request?from?"?+?sourceUid?+?"?stopped");??
????return?false;??
}??