From: Fan Zhang Date: Tue, 7 Mar 2017 20:12:38 +0000 (-0800) Subject: Fix a crash when opening uninstalled app detail page X-Git-Tag: android-x86-8.1-r1~710^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=1f81d10dc5119f5a6c57ceada1161c4a9f528f19;p=android-x86%2Fpackages-apps-Settings.git Fix a crash when opening uninstalled app detail page Change-Id: I417e7eb6f9c857ace4e8047b226abe03a7c8248d Fix: 36027848 Fix: 34392538 Test: make RunSettingsRoboTests --- diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index c443e73b00..0bd56d9b65 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -16,8 +16,6 @@ package com.android.settings.applications; -import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; - import android.Manifest.permission; import android.app.Activity; import android.app.ActivityManager; @@ -68,7 +66,6 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.view.View.OnClickListener; import android.view.ViewGroup; import android.webkit.IWebViewUpdateService; import android.widget.Button; @@ -115,6 +112,8 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; + /** * Activity to display application information from Settings. This activity presents * extended information associated with a package like code, data, total size, permissions @@ -325,6 +324,10 @@ public class InstalledAppDetails extends AppInfoBase super.onCreate(icicle); final Activity activity = getActivity(); + if (!ensurePackageInfoAvailable(activity)) { + return; + } + setHasOptionsMenu(true); addPreferencesFromResource(R.xml.installed_app_details_ia); addDynamicPrefs(); @@ -434,6 +437,23 @@ public class InstalledAppDetails extends AppInfoBase refreshUi(); } + /** + * Ensures the {@link PackageInfo} is available to proceed. If it's not available, the fragment + * will finish. + * + * @return true if packageInfo is available. + */ + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) + boolean ensurePackageInfoAvailable(Activity activity) { + if (mPackageInfo == null) { + mFinishing = true; + Log.w(LOG_TAG, "Package info not available. Is this package already uninstalled?"); + activity.finishAndRemoveTask(); + return false; + } + return true; + } + private void prepareUninstallAndStop() { mForceStopButton = (Button) mFooter.findViewById(R.id.right_button); mForceStopButton.setText(R.string.force_stop); diff --git a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java index 4fe6293ed8..b0cd8d5b9e 100644 --- a/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java +++ b/tests/robotests/src/com/android/settings/applications/InstalledAppDetailsTest.java @@ -16,12 +16,8 @@ package com.android.settings.applications; -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -44,6 +40,14 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public final class InstalledAppDetailsTest { @@ -51,24 +55,27 @@ public final class InstalledAppDetailsTest { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private UserManager mUserManager; @Mock + private Activity mActivity; + @Mock private DevicePolicyManager mDevicePolicyManager; + private InstalledAppDetails mAppDetail; + @Before public void setUp() { MockitoAnnotations.initMocks(this); + mAppDetail = new InstalledAppDetails(); } @Test public void getInstallationStatus_notInstalled_shouldReturnUninstalled() { - final InstalledAppDetails mAppDetail = new InstalledAppDetails(); assertThat(mAppDetail.getInstallationStatus(new ApplicationInfo())) - .isEqualTo(R.string.not_installed); + .isEqualTo(R.string.not_installed); } @Test public void getInstallationStatus_enabled_shouldReturnInstalled() { - final InstalledAppDetails mAppDetail = new InstalledAppDetails(); final ApplicationInfo info = new ApplicationInfo(); info.flags = ApplicationInfo.FLAG_INSTALLED; info.enabled = true; @@ -78,7 +85,6 @@ public final class InstalledAppDetailsTest { @Test public void getInstallationStatus_disabled_shouldReturnDisabled() { - final InstalledAppDetails mAppDetail = new InstalledAppDetails(); final ApplicationInfo info = new ApplicationInfo(); info.flags = ApplicationInfo.FLAG_INSTALLED; info.enabled = false; @@ -90,7 +96,6 @@ public final class InstalledAppDetailsTest { public void shouldShowUninstallForAll_installForOneOtherUserOnly_shouldReturnTrue() { when(mDevicePolicyManager.packageHasActiveAdmins(anyString())).thenReturn(false); when(mUserManager.getUsers().size()).thenReturn(2); - final InstalledAppDetails mAppDetail = new InstalledAppDetails(); ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager); ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager); final ApplicationInfo info = new ApplicationInfo(); @@ -107,7 +112,6 @@ public final class InstalledAppDetailsTest { public void shouldShowUninstallForAll_installForSelfOnly_shouldReturnFalse() { when(mDevicePolicyManager.packageHasActiveAdmins(anyString())).thenReturn(false); when(mUserManager.getUsers().size()).thenReturn(2); - final InstalledAppDetails mAppDetail = new InstalledAppDetails(); ReflectionHelpers.setField(mAppDetail, "mDpm", mDevicePolicyManager); ReflectionHelpers.setField(mAppDetail, "mUserManager", mUserManager); final ApplicationInfo info = new ApplicationInfo(); @@ -139,6 +143,22 @@ public final class InstalledAppDetailsTest { assertThat(InstalledAppDetails.getStorageSummary(context, stats, false)) .isEqualTo("1.00B used in Internal storage"); + } + + @Test + public void launchFragment_hasNoPackageInfo_shouldFinish() { + ReflectionHelpers.setField(mAppDetail, "mPackageInfo", null); + + assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isFalse(); + verify(mActivity).finishAndRemoveTask(); + } + + @Test + public void launchFragment_hasPackageInfo_shouldReturnTrue() { + final PackageInfo packageInfo = mock(PackageInfo.class); + ReflectionHelpers.setField(mAppDetail, "mPackageInfo", packageInfo); + assertThat(mAppDetail.ensurePackageInfoAvailable(mActivity)).isTrue(); + verify(mActivity, never()).finishAndRemoveTask(); } }