diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index 96096ef64d2..d9e264bf33d 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -47,6 +47,7 @@ import com.android.settings.applications.LayoutPreference; import com.android.settings.core.InstrumentedPreferenceFragment; import com.android.settings.core.instrumentation.Instrumentable; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settings.search.actionbar.SearchMenuController; import com.android.settings.support.actionbar.HelpMenuController; import com.android.settings.support.actionbar.HelpResourceProvider; import com.android.settings.widget.LoadingViewController; @@ -135,6 +136,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + SearchMenuController.init(this /* host */); HelpMenuController.init(this /* host */); if (icicle != null) { diff --git a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java index 2d2711a9bd0..f6e044eeb36 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java +++ b/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardActivity.java @@ -23,6 +23,7 @@ import android.view.Menu; import android.view.accessibility.AccessibilityEvent; import com.android.settings.SettingsActivity; +import com.android.settings.search.actionbar.SearchMenuController; import com.android.settings.support.actionbar.HelpResourceProvider; public class AccessibilitySettingsForSetupWizardActivity extends SettingsActivity { @@ -86,6 +87,7 @@ public class AccessibilitySettingsForSetupWizardActivity extends SettingsActivit // Start the new Fragment. args.putInt(HelpResourceProvider.HELP_URI_RESOURCE_KEY, 0); + args.putBoolean(SearchMenuController.NEED_SEARCH_ICON_IN_ACTION_BAR, false); startPreferenceFragment(Fragment.instantiate(this, fragmentClass, args), true); mSendExtraWindowStateChanged = true; } diff --git a/src/com/android/settings/applications/AppInfoDashboardFragment.java b/src/com/android/settings/applications/AppInfoDashboardFragment.java index 0e73ad78272..e77abde9803 100755 --- a/src/com/android/settings/applications/AppInfoDashboardFragment.java +++ b/src/com/android/settings/applications/AppInfoDashboardFragment.java @@ -48,7 +48,6 @@ import android.icu.text.ListFormatter; import android.net.INetworkStatsService; import android.net.INetworkStatsSession; import android.net.NetworkTemplate; -import android.net.TrafficStats; import android.net.Uri; import android.os.AsyncTask; import android.os.BatteryStats; @@ -563,6 +562,7 @@ public class AppInfoDashboardFragment extends SettingsPreferenceFragment @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); menu.add(0, UNINSTALL_UPDATES, 0, R.string.app_factory_reset) .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); menu.add(0, UNINSTALL_ALL_USERS_MENU, 1, R.string.uninstall_all_users_text) diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java index 91d1cb3d2fd..6f940159298 100755 --- a/src/com/android/settings/applications/InstalledAppDetails.java +++ b/src/com/android/settings/applications/InstalledAppDetails.java @@ -508,6 +508,7 @@ public class InstalledAppDetails extends AppInfoBase @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); menu.add(0, UNINSTALL_UPDATES, 0, R.string.app_factory_reset) .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); menu.add(0, UNINSTALL_ALL_USERS_MENU, 1, R.string.uninstall_all_users_text) diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java index d0c0cd971fe..437fc86a165 100644 --- a/src/com/android/settings/search/SearchFeatureProvider.java +++ b/src/com/android/settings/search/SearchFeatureProvider.java @@ -38,6 +38,8 @@ import java.util.concurrent.FutureTask; */ public interface SearchFeatureProvider { + Intent SEARCH_UI_INTENT = new Intent("com.android.settings.action.SETTINGS_SEARCH"); + /** * Ensures the caller has necessary privilege to launch search result page. * @@ -165,6 +167,10 @@ public interface SearchFeatureProvider { return null; } + default boolean isSearchV2Enabled(Context context) { + return FeatureFlagUtils.isEnabled(context, FeatureFlags.SEARCH_V2); + } + /** * Initializes the search toolbar. */ @@ -174,8 +180,8 @@ public interface SearchFeatureProvider { } toolbar.setOnClickListener(tb -> { final Intent intent; - if (FeatureFlagUtils.isEnabled(activity, FeatureFlags.SEARCH_V2)) { - intent = new Intent("com.android.settings.action.SETTINGS_SEARCH"); + if (isSearchV2Enabled(activity)) { + intent = SEARCH_UI_INTENT; } else { intent = new Intent(activity, SearchActivity.class); } diff --git a/src/com/android/settings/search/actionbar/SearchMenuController.java b/src/com/android/settings/search/actionbar/SearchMenuController.java new file mode 100644 index 00000000000..28bde33f82e --- /dev/null +++ b/src/com/android/settings/search/actionbar/SearchMenuController.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.search.actionbar; + +import android.annotation.NonNull; +import android.app.Fragment; +import android.content.Context; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import com.android.settings.R; +import com.android.settings.overlay.FeatureFactory; +import com.android.settings.search.SearchFeatureProvider; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment; +import com.android.settingslib.core.lifecycle.events.OnCreateOptionsMenu; + +public class SearchMenuController implements LifecycleObserver, OnCreateOptionsMenu { + + public static final String NEED_SEARCH_ICON_IN_ACTION_BAR = "need_search_icon_in_action_bar"; + + private final Fragment mHost; + + public static void init(@NonNull ObservablePreferenceFragment host) { + final Context context = host.getContext(); + final boolean isSearchV2Enabled = FeatureFactory.getFactory(context) + .getSearchFeatureProvider() + .isSearchV2Enabled(context); + + if (isSearchV2Enabled) { + host.getLifecycle().addObserver(new SearchMenuController(host)); + } + } + + private SearchMenuController(@NonNull Fragment host) { + mHost = host; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + if (menu == null) { + return; + } + final Bundle arguments = mHost.getArguments(); + if (arguments != null && !arguments.getBoolean(NEED_SEARCH_ICON_IN_ACTION_BAR, true)) { + return; + } + final MenuItem searchItem = menu.add(Menu.NONE, Menu.NONE, 0 /* order */, + R.string.search_menu); + searchItem.setIcon(R.drawable.ic_search_24dp); + searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + + searchItem.setOnMenuItemClickListener(target -> { + mHost.startActivityForResult( + SearchFeatureProvider.SEARCH_UI_INTENT, 0 /* requestCode */); + return true; + }); + } +} diff --git a/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java new file mode 100644 index 00000000000..52918fbd556 --- /dev/null +++ b/tests/robotests/src/com/android/settings/search/actionbar/SearchMenuControllerTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.search.actionbar; + +import static org.mockito.Matchers.nullable; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +import com.android.settings.R; +import com.android.settings.TestConfig; +import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settingslib.core.lifecycle.ObservablePreferenceFragment; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION_O) +public class SearchMenuControllerTest { + + @Mock + private Menu mMenu; + private TestFragment mHost; + private FakeFeatureFactory mFeatureFactory; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mHost = new TestFragment(); + mFeatureFactory = FakeFeatureFactory.setupForTest(); + } + + @Test + public void init_searchV2Disabled_shouldNotAddMenu() { + when(mFeatureFactory.searchFeatureProvider.isSearchV2Enabled(nullable(Context.class))) + .thenReturn(false); + + SearchMenuController.init(mHost); + mHost.getLifecycle().onCreateOptionsMenu(mMenu, null /* inflater */); + + verifyZeroInteractions(mMenu); + } + + @Test + public void init_searchV2Enabled_shouldAddMenu() { + when(mFeatureFactory.searchFeatureProvider.isSearchV2Enabled(nullable(Context.class))) + .thenReturn(true); + when(mMenu.add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu)) + .thenReturn(mock(MenuItem.class)); + + SearchMenuController.init(mHost); + mHost.getLifecycle().onCreateOptionsMenu(mMenu, null /* inflater */); + + verify(mMenu).add(Menu.NONE, Menu.NONE, 0 /* order */, R.string.search_menu); + } + + public static class TestFragment extends ObservablePreferenceFragment { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + + } + } +}