/**
* Keep track of all those APKs everywhere.
* <p>
* Internally there are two important locks:
* <ul>
* <li>{@link #mPackages} is used to guard all in-memory parsed package details
* and other related state. It is a fine-grained lock that should only be held
* momentarily, as it's one of the most contended locks in the system.
* <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
* operations typically involve heavy lifting of application data on disk. Since
* {@code installd} is single-threaded, and it's operations can often be slow,
* this lock should never be acquired while already holding {@link #mPackages}.
* Conversely, it's safe to acquire {@link #mPackages} momentarily while already
* holding {@link #mInstallLock}.
* </ul>
* Many internal methods rely on the caller to hold the appropriate locks, and
* this contract is expressed through method name suffixes:
* <ul>
* <li>fooLI(): the caller must hold {@link #mInstallLock}
* <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
* being modified must be frozen
* <li>fooLPr(): the caller must hold {@link #mPackages} for reading
* <li>fooLPw(): the caller must hold {@link #mPackages} for writing
* </ul>
* <p>
* Because this class is very central to the platform's security; please run all
* CTS and unit tests whenever making modifications:
*
* <pre>
* $ runtest -c android.content.pm.PackageManagerTests frameworks-core
* $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
* </pre>
*/
註釋裡面說的比較清楚Pms有兩把鎖,一把叫mPackages,是fine-grained lock(細粒度的鎖)。 另一把是mInstallLock,它是一把重量級的鎖。 另外還有四個方法範例表示該方法持有什麼樣的鎖,分別是:
另外由於mPackages為細粒度的鎖, mInstallLock為重量級鎖,所以不應該在持有 mPackages鎖的情況下再去獲取mInstallLock,否則mPackages也會變成重量級。
上述都不是重點, 重點是Pms到底如何使用這兩把鎖, 現在由我來給大家說明。
PackageManagerService主要有兩項工作:
1 應用安裝解除安裝: mInstallLock 主要保證這個流程是序列執行。而這個過程會修改mPackages鎖保護的資料,mPackages保證安裝解除安裝過程中查詢資料正確。
2 應用資訊查詢:mPackages 也是保證查詢資料正確,這個過程不會修改mPackages保護的資料。