Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for null results from PackageManager.getApplicationInfo #5018

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;
import androidx.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -24,18 +26,24 @@ public ManifestParser(Context context) {
this.context = context;
}

// getApplicationInfo returns null in Compose previews, see #4977 and b/263613353.
@SuppressWarnings("ConstantConditions")
@Nullable
private ApplicationInfo getOurApplicationInfo() throws NameNotFoundException {
return context
.getPackageManager()
.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
}

@SuppressWarnings("deprecation")
public List<GlideModule> parse() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Loading Glide modules");
}
List<GlideModule> modules = new ArrayList<>();
try {
ApplicationInfo appInfo =
context
.getPackageManager()
.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
if (appInfo.metaData == null) {
ApplicationInfo appInfo = getOurApplicationInfo();
if (appInfo == null || appInfo.metaData == null) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Got null app info metadata");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.bumptech.glide.module;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
Expand All @@ -16,6 +21,7 @@
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.function.ThrowingRunnable;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
Expand All @@ -27,6 +33,7 @@
@SuppressWarnings("deprecation")
public class ManifestParserTest {
private static final String MODULE_VALUE = "GlideModule";
private static final String PACKAGE_NAME = "com.bumptech.test";

@Mock private Context context;
private ManifestParser parser;
Expand All @@ -38,17 +45,27 @@ public void setUp() throws PackageManager.NameNotFoundException {
applicationInfo = new ApplicationInfo();
applicationInfo.metaData = new Bundle();

String packageName = "com.bumptech.test";
when(context.getPackageName()).thenReturn(packageName);
when(context.getPackageName()).thenReturn(PACKAGE_NAME);

PackageManager pm = mock(PackageManager.class);
when(pm.getApplicationInfo(eq(packageName), eq(PackageManager.GET_META_DATA)))
when(pm.getApplicationInfo(eq(PACKAGE_NAME), eq(PackageManager.GET_META_DATA)))
.thenReturn(applicationInfo);
when(context.getPackageManager()).thenReturn(pm);

parser = new ManifestParser(context);
}

// TODO(#4977): Remove this after the bug in Compose's previews is fixed.
@Test
public void parse_withNullApplicationInfo_doesNotThrow() throws NameNotFoundException {
PackageManager pm = mock(PackageManager.class);
when(pm.getApplicationInfo(anyString(), anyInt())).thenReturn(null);
when(context.getPackageManager()).thenReturn(pm);

parser = new ManifestParser(context);
parser.parse();
}

@Test
public void testParse_returnsEmptyListIfNoModulesListed() {
assertThat(parser.parse()).isEmpty();
Expand Down Expand Up @@ -78,7 +95,6 @@ public void testParse_withMultipleValidModuleNames_returnsListContainingModules(
@Test
public void testParse_withValidModuleName_ignoresMetadataWithoutGlideModuleValue() {
applicationInfo.metaData.putString(TestModule1.class.getName(), MODULE_VALUE + "test");

assertThat(parser.parse()).isEmpty();
}

Expand All @@ -96,13 +112,35 @@ public void testThrows_whenClassInManifestIsNotAModule() {
parser.parse();
}

@Test(expected = RuntimeException.class)
public void testThrows_whenPackageNameNotFound() {
when(context.getPackageName()).thenReturn("fakePackageName");
@Test
public void parse_withNullMetadata_doesNotThrow() throws NameNotFoundException {
PackageManager pm = mock(PackageManager.class);
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.metaData = null;
when(pm.getApplicationInfo(eq(PACKAGE_NAME), eq(PackageManager.GET_META_DATA)))
.thenReturn(applicationInfo);
when(context.getPackageManager()).thenReturn(pm);

parser.parse();
}

@Test
public void parse_withMissingName_throwsRuntimeException() throws NameNotFoundException {
PackageManager pm = mock(PackageManager.class);
doThrow(new NameNotFoundException("name")).when(pm).getApplicationInfo(anyString(), anyInt());
when(context.getPackageManager()).thenReturn(pm);

assertThrows(
"Unable to find metadata to parse GlideModules",
RuntimeException.class,
new ThrowingRunnable() {
@Override
public void run() {
parser.parse();
}
});
}

private void addModuleToManifest(Class<?> moduleClass) {
addToManifest(moduleClass.getName());
}
Expand Down