Fix Settings crash after disabling Settings Suggestion

- Settings Suggestion App is responsible for searching, we can not
prevent user disable it. Hide search feature if user disable it.

Fixes: 118805907
Fixes: 117921464
Test: manual
Change-Id: I61c47c52265a6efd79ef2fa60272bf6513e678b1
This commit is contained in:
Raff Tsai
2018-11-05 16:10:19 +08:00
parent 7d704c8798
commit 2928cd4c72
8 changed files with 69 additions and 3 deletions

View File

@@ -979,4 +979,14 @@ public final class Utils extends com.android.settingslib.Utils {
return packageManager.getDefaultActivityIcon();
}
}
/** Returns true if the current package is installed & enabled. */
public static boolean isPackageEnabled(Context context, String packageName) {
try {
return context.getPackageManager().getApplicationInfo(packageName, 0).enabled;
} catch (Exception e) {
Log.e(TAG, "Error while retrieving application info for package " + packageName, e);
}
return false;
}
}

View File

@@ -25,9 +25,11 @@ import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.search.SearchIndexableResources;
@@ -64,6 +66,13 @@ public interface SearchFeatureProvider {
if (activity == null || toolbar == null) {
return;
}
if (!Utils.isPackageEnabled(activity, getSettingsIntelligencePkgName())) {
final ViewGroup parent = (ViewGroup)toolbar.getParent();
if (parent != null) {
parent.setVisibility(View.GONE);
}
return;
}
// Please forgive me for what I am about to do.
//
// Need to make the navigation icon non-clickable so that the entire card is clickable

View File

@@ -56,9 +56,15 @@ public class SearchMenuController implements LifecycleObserver, OnCreateOptionsM
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
final Context context = mHost.getContext();
final String SettingsIntelligencePkgName = FeatureFactory.getFactory(context)
.getSearchFeatureProvider().getSettingsIntelligencePkgName();
if (!Utils.isDeviceProvisioned(mHost.getContext())) {
return;
}
if (!Utils.isPackageEnabled(mHost.getContext(), SettingsIntelligencePkgName)) {
return;
}
if (menu == null) {
return;
}
@@ -72,10 +78,8 @@ public class SearchMenuController implements LifecycleObserver, OnCreateOptionsM
searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
searchItem.setOnMenuItemClickListener(target -> {
final Context context = mHost.getContext();
final Intent intent = SearchFeatureProvider.SEARCH_UI_INTENT;
intent.setPackage(FeatureFactory.getFactory(mHost.getContext())
.getSearchFeatureProvider().getSettingsIntelligencePkgName());
intent.setPackage(SettingsIntelligencePkgName);
FeatureFactory.getFactory(context).getMetricsFeatureProvider()
.action(context, MetricsProto.MetricsEvent.ACTION_SEARCH_RESULTS);
mHost.startActivityForResult(intent, 0 /* requestCode */);

View File

@@ -38,6 +38,7 @@ import androidx.fragment.app.FragmentTransaction;
import com.android.settings.core.OnActivityResultListener;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.Before;
import org.junit.Test;
@@ -46,6 +47,7 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
@@ -69,6 +71,7 @@ public class SettingsActivityTest {
}
@Test
@Config(shadows = ShadowUtils.class)
public void onCreate_deviceNotProvisioned_shouldDisableSearch() {
Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0);
final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class)
@@ -80,6 +83,7 @@ public class SettingsActivityTest {
}
@Test
@Config(shadows = ShadowUtils.class)
public void onCreate_deviceProvisioned_shouldEnableSearch() {
Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1);
final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class)

View File

@@ -93,6 +93,7 @@ public class UtilsTest {
when(mContext.getSystemService(WifiManager.class)).thenReturn(wifiManager);
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
.thenReturn(connectivityManager);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
}
@Test
@@ -200,4 +201,27 @@ public class UtilsTest {
verify(mPackageManager).getApplicationInfoAsUser(eq(PACKAGE_NAME), anyInt(), eq(USER_ID));
verify(mIconDrawableFactory).getBadgedIcon(mApplicationInfo, USER_ID);
}
@Test
public void isPackageEnabled_appEnabled_returnTrue()
throws PackageManager.NameNotFoundException{
mApplicationInfo.enabled = true;
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isTrue();
}
@Test
public void isPackageEnabled_appDisabled_returnTrue()
throws PackageManager.NameNotFoundException{
mApplicationInfo.enabled = false;
when(mPackageManager.getApplicationInfo(PACKAGE_NAME, 0)).thenReturn(mApplicationInfo);
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
@Test
public void isPackageEnabled_noApp_returnFalse() {
assertThat(Utils.isPackageEnabled(mContext, PACKAGE_NAME)).isFalse();
}
}

View File

@@ -29,12 +29,14 @@ import android.widget.Toolbar;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
public class SearchFeatureProviderImplTest {
@@ -50,6 +52,7 @@ public class SearchFeatureProviderImplTest {
}
@Test
@Config(shadows = ShadowUtils.class)
public void initSearchToolbar_shouldInitWithOnClickListener() {
mProvider.initSearchToolbar(mActivity, null);
// Should not crash.

View File

@@ -30,6 +30,7 @@ import android.view.MenuItem;
import com.android.settings.R;
import com.android.settings.testutils.SettingsRobolectricTestRunner;
import com.android.settings.testutils.shadow.ShadowUtils;
import com.android.settingslib.core.lifecycle.ObservableFragment;
import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment;
@@ -39,8 +40,10 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@RunWith(SettingsRobolectricTestRunner.class)
@Config(shadows = ShadowUtils.class)
public class SearchMenuControllerTest {
@Mock

View File

@@ -21,9 +21,13 @@ import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
import com.android.settings.Utils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.SearchFeatureProviderImpl;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
@@ -102,6 +106,11 @@ public class ShadowUtils {
return null;
}
@Implementation
public static boolean isPackageEnabled(Context context, String packageName) {
return true;
}
public static void setApplicationLabel(String packageName, String appLabel) {
if (sAppNameMap == null) {
sAppNameMap = new HashMap<>();