Fix a crash in AppInfoBase where appEntry is invalid
Change-Id: Ifbea967405ddc1e1bd069ddeab170bc67b1835b4
Fix: 63178369
Test: robotests
diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java
index a93bfbd..4af9bc6 100644
--- a/src/com/android/settings/applications/AppInfoBase.java
+++ b/src/com/android/settings/applications/AppInfoBase.java
@@ -35,6 +35,7 @@
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
@@ -291,7 +292,8 @@
@Override
public void onReceive(Context context, Intent intent) {
String packageName = intent.getData().getSchemeSpecificPart();
- if (!mFinishing && mAppEntry.info.packageName.equals(packageName)) {
+ if (!mFinishing && (mAppEntry == null || mAppEntry.info == null
+ || TextUtils.equals(mAppEntry.info.packageName, packageName))) {
onPackageRemoved();
}
}
diff --git a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
index 735c12f..62395f3 100644
--- a/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
+++ b/tests/robotests/src/com/android/settings/applications/AppInfoWithHeaderTest.java
@@ -17,20 +17,24 @@
package com.android.settings.applications;
import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.net.Uri;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto;
-import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.applications.AppUtils;
+import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
import org.junit.After;
@@ -40,10 +44,12 @@
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -85,11 +91,41 @@
verify(mAppInfoWithHeader.mScreen).addPreference(any(LayoutPreference.class));
}
+ @Test
+ public void packageRemoved_noAppEntry_shouldFinishActivity() {
+ BroadcastReceiver packageRemovedReceiver =
+ ReflectionHelpers.getField(mAppInfoWithHeader, "mPackageRemovedReceiver");
+ ReflectionHelpers.setField(mAppInfoWithHeader, "mAppEntry", null);
+
+ final Intent packageRemovedBroadcast = new Intent();
+ packageRemovedBroadcast.setData(Uri.parse("package:com.android.settings"));
+ packageRemovedReceiver.onReceive(RuntimeEnvironment.application, packageRemovedBroadcast);
+
+ assertThat(mAppInfoWithHeader.mPackageRemovedCalled).isTrue();
+ }
+
+ @Test
+ public void packageRemoved_appEntryMatchesPackageName_shouldFinishActivity() {
+ BroadcastReceiver packageRemovedReceiver =
+ ReflectionHelpers.getField(mAppInfoWithHeader, "mPackageRemovedReceiver");
+ final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class);
+ entry.info = new ApplicationInfo();
+ entry.info.packageName = "com.android.settings";
+ ReflectionHelpers.setField(mAppInfoWithHeader, "mAppEntry", entry);
+
+ final Intent packageRemovedBroadcast = new Intent();
+ packageRemovedBroadcast.setData(Uri.parse("package:" + entry.info.packageName));
+ packageRemovedReceiver.onReceive(RuntimeEnvironment.application, packageRemovedBroadcast);
+
+ assertThat(mAppInfoWithHeader.mPackageRemovedCalled).isTrue();
+ }
+
public static class TestFragment extends AppInfoWithHeader {
PreferenceManager mManager;
PreferenceScreen mScreen;
Context mShadowContext;
+ boolean mPackageRemovedCalled;
public TestFragment() {
mPm = mock(PackageManager.class);
@@ -132,6 +168,11 @@
public Context getContext() {
return mShadowContext;
}
+
+ @Override
+ protected void onPackageRemoved() {
+ mPackageRemovedCalled = true;
+ }
}
}