Fix NPE when loading recently opened apps on the Apps page

From Android U, Settings start to support showing work profile apps on
recently opened apps list on the Apps page. It will query the app entry
from the cache of ApplicationsState by different user id before cache
initialization. We should check mEntriesMap by user id in getEntry() and
getEntryLocked() to avoid NPE since the cache might be empty before
reading.

Bug: 284252546
Test: robotests
Change-Id: Ie4dc0821c4fe29a389f491eb4706abe352c05c5a
This commit is contained in:
Yanting Yang
2023-06-01 16:07:13 +08:00
parent 3d137a068c
commit 986857c9e6
2 changed files with 19 additions and 11 deletions

View File

@@ -484,8 +484,9 @@ public class ApplicationsState {
if (DEBUG_LOCKING) Log.v(TAG, "getEntry about to acquire lock...");
synchronized (mEntriesMap) {
AppEntry entry = null;
if (mEntriesMap.contains(userId)) {
entry = mEntriesMap.get(userId).get(packageName);
HashMap<String, AppEntry> userEntriesMap = mEntriesMap.get(userId);
if (userEntriesMap != null) {
entry = userEntriesMap.get(packageName);
}
if (entry == null) {
ApplicationInfo info = getAppInfoLocked(packageName, userId);
@@ -735,8 +736,9 @@ public class ApplicationsState {
private AppEntry getEntryLocked(ApplicationInfo info) {
int userId = UserHandle.getUserId(info.uid);
AppEntry entry = null;
if (mEntriesMap.contains(userId)) {
entry = mEntriesMap.get(userId).get(info.packageName);
HashMap<String, AppEntry> userEntriesMap = mEntriesMap.get(userId);
if (userEntriesMap != null) {
entry = userEntriesMap.get(info.packageName);
}
if (DEBUG) {
Log.i(TAG, "Looking up entry of pkg " + info.packageName + ": " + entry);
@@ -752,8 +754,11 @@ public class ApplicationsState {
Log.i(TAG, "Creating AppEntry for " + info.packageName);
}
entry = new AppEntry(mContext, info, mCurId++);
mEntriesMap.get(userId).put(info.packageName, entry);
mAppEntries.add(entry);
userEntriesMap = mEntriesMap.get(userId);
if (userEntriesMap != null) {
userEntriesMap.put(info.packageName, entry);
mAppEntries.add(entry);
}
} else if (entry.info != info) {
entry.info = info;
}

View File

@@ -804,7 +804,7 @@ public class ApplicationsStateRoboTest {
}
@Test
public void getEntry_validUserId_shouldReturnEntry() {
public void getEntry_hasCache_shouldReturnCacheEntry() {
mApplicationsState.mEntriesMap.put(/* userId= */ 0, new HashMap<>());
addApp(PKG_1, /* id= */ 1);
@@ -813,10 +813,13 @@ public class ApplicationsStateRoboTest {
}
@Test
public void getEntry_invalidUserId_shouldReturnNull() {
mApplicationsState.mEntriesMap.put(/* userId= */ 0, new HashMap<>());
addApp(PKG_1, /* id= */ 1);
public void getEntry_hasNoCache_shouldReturnEntry() {
mApplicationsState.mEntriesMap.clear();
ApplicationInfo appInfo = createApplicationInfo(PKG_1, /* uid= */ 0);
mApplicationsState.mApplications.add(appInfo);
mApplicationsState.mSystemModules.put(PKG_1, /* value= */ false);
assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ -1)).isNull();
assertThat(mApplicationsState.getEntry(PKG_1, /* userId= */ 0).info.packageName)
.isEqualTo(PKG_1);
}
}