Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c6634a8 authored by Fan Zhang's avatar Fan Zhang
Browse files

Fix a crash in AppInfoBase where appEntry is invalid

Change-Id: Ifbea967405ddc1e1bd069ddeab170bc67b1835b4
Fix: 63178369
Test: robotests
parent 24ba2fbd
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.os.IBinder;
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 @@ public abstract class AppInfoBase extends SettingsPreferenceFragment
        @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();
            }
        }
+42 −1
Original line number Diff line number Diff line
@@ -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.junit.runner.RunWith;
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 @@ public class AppInfoWithHeaderTest {
        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 class AppInfoWithHeaderTest {
        public Context getContext() {
            return mShadowContext;
        }

        @Override
        protected void onPackageRemoved() {
            mPackageRemovedCalled = true;
        }
    }

}