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;
+        }
     }
 
 }