Fix crash in Storage app info when the corresponding app is uninstalled
in the background.

1. Move the handling for package removal from InstalledAppDetails to
AppInfoBase so that all app info subclass will now finish
correspondingly if the package is uninstalled.
2. In InstalledAppDetails, when handling package removal, will also
finish the app info fragment that it starts earlier.

Change-Id: Id741e7475414045040dd0797ff3bc63ac214f400
Fixes: 27774473
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 0725386..a37039f 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -515,7 +515,7 @@
         if (resultTo == null) {
             context.startActivity(intent);
         } else {
-            resultTo.startActivityForResult(intent, resultRequestCode);
+            resultTo.getActivity().startActivityForResult(intent, resultRequestCode);
         }
     }
 
diff --git a/src/com/android/settings/applications/AppInfoBase.java b/src/com/android/settings/applications/AppInfoBase.java
index 8a99e03..f7992cc 100644
--- a/src/com/android/settings/applications/AppInfoBase.java
+++ b/src/com/android/settings/applications/AppInfoBase.java
@@ -22,8 +22,10 @@
 import android.app.DialogFragment;
 import android.app.Fragment;
 import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -74,6 +76,7 @@
     protected static final int DLG_BASE = 0;
 
     protected boolean mFinishing;
+    protected boolean mListeningToPackageRemove;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -90,6 +93,7 @@
         mUsbManager = IUsbManager.Stub.asInterface(b);
 
         retrieveAppEntry();
+        startListeningToPackageRemove();
     }
 
     @Override
@@ -114,6 +118,7 @@
 
     @Override
     public void onDestroy() {
+        stopListeningToPackageRemove();
         mSession.release();
         super.onDestroy();
     }
@@ -246,4 +251,37 @@
             return dialogFragment;
         }
     }
+
+    protected void startListeningToPackageRemove() {
+        if (mListeningToPackageRemove) {
+            return;
+        }
+        mListeningToPackageRemove = true;
+        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addDataScheme("package");
+        getContext().registerReceiver(mPackageRemovedReceiver, filter);
+    }
+
+    protected void stopListeningToPackageRemove() {
+        if (!mListeningToPackageRemove) {
+            return;
+        }
+        mListeningToPackageRemove = false;
+        getContext().unregisterReceiver(mPackageRemovedReceiver);
+    }
+
+    protected void onPackageRemoved() {
+        getActivity().finishAndRemoveTask();
+    }
+
+    protected final BroadcastReceiver mPackageRemovedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String packageName = intent.getData().getSchemeSpecificPart();
+            if (!mFinishing && mAppEntry.info.packageName.equals(packageName)) {
+                onPackageRemoved();
+            }
+        }
+    };
+
 }
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 3f42293..1cf55a4 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -29,7 +29,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.Loader;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -165,8 +164,6 @@
     private Preference mMemoryPreference;
 
     private boolean mDisableAfterUninstall;
-    private boolean mListeningToPackageRemove;
-
     // Used for updating notification preference.
     private final NotificationBackend mBackend = new NotificationBackend();
 
@@ -326,7 +323,6 @@
             removePreference(KEY_DATA);
         }
         mBatteryHelper = new BatteryStatsHelper(getActivity(), true);
-        startListeningToPackageRemove();
     }
 
     @Override
@@ -362,7 +358,6 @@
     @Override
     public void onDestroy() {
         TrafficStats.closeQuietly(mStatsSession);
-        stopListeningToPackageRemove();
         super.onDestroy();
     }
 
@@ -742,7 +737,7 @@
         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppEntry.info.packageName);
         intent.putExtra(AppHeader.EXTRA_HIDE_INFO_BUTTON, true);
         try {
-            startActivity(intent);
+            getActivity().startActivityForResult(intent, SUB_INFO_FRAGMENT);
         } catch (ActivityNotFoundException e) {
             Log.w(LOG_TAG, "No app can handle android.intent.action.MANAGE_APP_PERMISSIONS");
         }
@@ -1090,6 +1085,12 @@
         return summary.toString();
     }
 
+    @Override
+    protected void onPackageRemoved() {
+        getActivity().finishActivity(SUB_INFO_FRAGMENT);
+        super.onPackageRemoved();
+    }
+
     private class MemoryUpdater extends AsyncTask<Void, Void, ProcStatsPackageEntry> {
 
         @Override
@@ -1246,33 +1247,4 @@
             mPermissionsPreference.setSummary(summary);
         }
     };
-
-    private void startListeningToPackageRemove() {
-        if (mListeningToPackageRemove) {
-            return;
-        }
-        mListeningToPackageRemove = true;
-        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_REMOVED);
-        filter.addDataScheme("package");
-        getContext().registerReceiver(mPackageRemovedReceiver, filter);
-    }
-
-    private void stopListeningToPackageRemove() {
-        if (!mListeningToPackageRemove) {
-            return;
-        }
-        mListeningToPackageRemove = false;
-        getContext().unregisterReceiver(mPackageRemovedReceiver);
-    }
-
-    private final BroadcastReceiver mPackageRemovedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String packageName = intent.getData().getSchemeSpecificPart();
-            if (!mFinishing && mAppEntry.info.packageName.equals(packageName)) {
-                getActivity().finishAndRemoveTask();
-            }
-        }
-    };
-
 }