Merge changes from topics "A11yFeedback1P", "A11yFeedbackTopLevelPage", "AccessibilityPageIdFeatureProvider" into main

* changes:
  refactor(A11yFeedback): Rename AccessibilityMetricsFeatureProvider
  feat(A11yFeedback): Add feedback entry for downloaded Accessibility
  chore(A11yFeedback): Removing Legacy Android M Menu Behavior
  feat(A11yFeedback): Implements page ID to feedback bucket ID mapping
This commit is contained in:
Menghan Li
2025-03-05 00:06:01 -08:00
committed by Android (Google) Code Review
22 changed files with 190 additions and 91 deletions

View File

@@ -127,14 +127,13 @@ public class AccessibilityActivityPreference extends RestrictedPreference {
final String htmlDescription = mA11yShortcutInfo.loadHtmlDescription(mPm); final String htmlDescription = mA11yShortcutInfo.loadHtmlDescription(mPm);
final String settingsClassName = mA11yShortcutInfo.getSettingsActivityName(); final String settingsClassName = mA11yShortcutInfo.getSettingsActivityName();
final String tileServiceClassName = mA11yShortcutInfo.getTileServiceName(); final String tileServiceClassName = mA11yShortcutInfo.getTileServiceName();
final int metricsCategory = FeatureFactory.getFeatureFactory() final int pageIdCategory = FeatureFactory.getFeatureFactory()
.getAccessibilityMetricsFeatureProvider() .getAccessibilityPageIdFeatureProvider().getCategory(mComponentName);
.getDownloadedFeatureMetricsCategory(mComponentName);
ThreadUtils.getUiThreadHandler().post(() -> { ThreadUtils.getUiThreadHandler().post(() -> {
RestrictedPreferenceHelper.putBasicExtras( RestrictedPreferenceHelper.putBasicExtras(
this, prefKey, getTitle(), intro, description, imageRes, this, prefKey, getTitle(), intro, description, imageRes,
htmlDescription, mComponentName, metricsCategory); htmlDescription, mComponentName, pageIdCategory);
RestrictedPreferenceHelper.putSettingsExtras(this, getPackageName(), settingsClassName); RestrictedPreferenceHelper.putSettingsExtras(this, getPackageName(), settingsClassName);
RestrictedPreferenceHelper.putTileServiceExtras( RestrictedPreferenceHelper.putTileServiceExtras(
this, getPackageName(), tileServiceClassName); this, getPackageName(), tileServiceClassName);

View File

@@ -228,10 +228,10 @@ public class AccessibilityDetailsSettingsFragment extends InstrumentedFragment {
new ComponentName(packageName, tileServiceClassName).flattenToString()); new ComponentName(packageName, tileServiceClassName).flattenToString());
} }
final int metricsCategory = FeatureFactory.getFeatureFactory() final int pageIdCategory = FeatureFactory.getFeatureFactory()
.getAccessibilityMetricsFeatureProvider() .getAccessibilityPageIdFeatureProvider().getCategory(componentName);
.getDownloadedFeatureMetricsCategory(componentName); extras.putInt(AccessibilitySettings.EXTRA_METRICS_CATEGORY, pageIdCategory);
extras.putInt(AccessibilitySettings.EXTRA_METRICS_CATEGORY, metricsCategory); extras.putInt(AccessibilitySettings.EXTRA_FEEDBACK_CATEGORY, pageIdCategory);
extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, componentName); extras.putParcelable(AccessibilitySettings.EXTRA_COMPONENT_NAME, componentName);
extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, info.getAnimatedImageRes()); extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, info.getAnimatedImageRes());

View File

@@ -15,8 +15,6 @@
*/ */
package com.android.settings.accessibility; package com.android.settings.accessibility;
import android.content.ComponentName;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
/** /**
@@ -25,11 +23,11 @@ import androidx.annotation.Nullable;
public interface AccessibilityFeedbackFeatureProvider { public interface AccessibilityFeedbackFeatureProvider {
/** /**
* Returns value according to the {@code componentName}. * Returns value according to the {@code pageId}.
* *
* @param componentName the component name of the downloaded service or activity * @param pageId The unique identifier of the page.
* @return Feedback bucket ID * @return Feedback bucket ID associated with the page, or {@code null} if is not found.
*/ */
@Nullable @Nullable
String getCategory(@Nullable ComponentName componentName); String getCategory(int pageId);
} }

View File

@@ -15,8 +15,6 @@
*/ */
package com.android.settings.accessibility; package com.android.settings.accessibility;
import android.content.ComponentName;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
/** Default implementation of {@link AccessibilityFeedbackFeatureProvider}. */ /** Default implementation of {@link AccessibilityFeedbackFeatureProvider}. */
@@ -25,7 +23,7 @@ public class AccessibilityFeedbackFeatureProviderImpl implements
@Override @Override
@Nullable @Nullable
public String getCategory(@Nullable ComponentName componentName) { public String getCategory(int pageId) {
return ""; return null;
} }
} }

View File

@@ -21,9 +21,9 @@ import android.content.ComponentName;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
/** /**
* Provider for Accessibility metrics related features. * Provider for Accessibility page id related features.
*/ */
public interface AccessibilityMetricsFeatureProvider { public interface AccessibilityPageIdFeatureProvider {
/** /**
* Returns {@link android.app.settings.SettingsEnums} value according to the {@code * Returns {@link android.app.settings.SettingsEnums} value according to the {@code
@@ -32,5 +32,5 @@ public interface AccessibilityMetricsFeatureProvider {
* @param componentName the component name of the downloaded service or activity * @param componentName the component name of the downloaded service or activity
* @return value in {@link android.app.settings.SettingsEnums} * @return value in {@link android.app.settings.SettingsEnums}
*/ */
int getDownloadedFeatureMetricsCategory(@Nullable ComponentName componentName); int getCategory(@Nullable ComponentName componentName);
} }

View File

@@ -19,14 +19,16 @@ package com.android.settings.accessibility;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.ComponentName; import android.content.ComponentName;
import androidx.annotation.Nullable;
/** /**
* Provider implementation for Accessibility metrics related features. * Provider implementation for Accessibility page id related features.
*/ */
public class AccessibilityMetricsFeatureProviderImpl implements public class AccessibilityPageIdFeatureProviderImpl implements
AccessibilityMetricsFeatureProvider { AccessibilityPageIdFeatureProvider {
@Override @Override
public int getDownloadedFeatureMetricsCategory(ComponentName componentName) { public int getCategory(@Nullable ComponentName componentName) {
return SettingsEnums.ACCESSIBILITY_SERVICE; return SettingsEnums.ACCESSIBILITY_SERVICE;
} }
} }

View File

@@ -123,13 +123,12 @@ public class AccessibilityServicePreference extends RestrictedPreference {
final String settingsClassName = mA11yServiceInfo.getSettingsActivityName(); final String settingsClassName = mA11yServiceInfo.getSettingsActivityName();
final String tileServiceClassName = mA11yServiceInfo.getTileServiceName(); final String tileServiceClassName = mA11yServiceInfo.getTileServiceName();
final ResolveInfo resolveInfo = mA11yServiceInfo.getResolveInfo(); final ResolveInfo resolveInfo = mA11yServiceInfo.getResolveInfo();
final int metricsCategory = FeatureFactory.getFeatureFactory() final int pageIdCategory = FeatureFactory.getFeatureFactory()
.getAccessibilityMetricsFeatureProvider() .getAccessibilityPageIdFeatureProvider().getCategory(mComponentName);
.getDownloadedFeatureMetricsCategory(mComponentName);
ThreadUtils.getUiThreadHandler().post(() -> { ThreadUtils.getUiThreadHandler().post(() -> {
RestrictedPreferenceHelper.putBasicExtras( RestrictedPreferenceHelper.putBasicExtras(
this, prefKey, getTitle(), intro, description, imageRes, this, prefKey, getTitle(), intro, description, imageRes,
htmlDescription, mComponentName, metricsCategory); htmlDescription, mComponentName, pageIdCategory);
RestrictedPreferenceHelper.putServiceExtras(this, resolveInfo, mServiceEnabled); RestrictedPreferenceHelper.putServiceExtras(this, resolveInfo, mServiceEnabled);
RestrictedPreferenceHelper.putSettingsExtras(this, getPackageName(), settingsClassName); RestrictedPreferenceHelper.putSettingsExtras(this, getPackageName(), settingsClassName);
RestrictedPreferenceHelper.putTileServiceExtras( RestrictedPreferenceHelper.putTileServiceExtras(

View File

@@ -97,6 +97,7 @@ public class AccessibilitySettings extends DashboardFragment implements
static final String EXTRA_HTML_DESCRIPTION = "html_description"; static final String EXTRA_HTML_DESCRIPTION = "html_description";
static final String EXTRA_TIME_FOR_LOGGING = "start_time_to_log_a11y_tool"; static final String EXTRA_TIME_FOR_LOGGING = "start_time_to_log_a11y_tool";
static final String EXTRA_METRICS_CATEGORY = "metrics_category"; static final String EXTRA_METRICS_CATEGORY = "metrics_category";
static final String EXTRA_FEEDBACK_CATEGORY = "feedback_category";
// Timeout before we update the services if packages are added/removed // Timeout before we update the services if packages are added/removed
// since the AccessibilityManagerService has to do that processing first // since the AccessibilityManagerService has to do that processing first
@@ -255,7 +256,7 @@ public class AccessibilitySettings extends DashboardFragment implements
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
if (getFeedbackManager().isAvailable()) { if (getFeedbackManager().isAvailable()) {
menu.add(Menu.NONE, MENU_ID_SEND_FEEDBACK, Menu.NONE, menu.add(Menu.NONE, MENU_ID_SEND_FEEDBACK, Menu.NONE,
getPrefContext().getText(R.string.accessibility_send_feedback_title)); R.string.accessibility_send_feedback_title);
} }
super.onCreateOptionsMenu(menu, inflater); super.onCreateOptionsMenu(menu, inflater);
} }
@@ -286,7 +287,7 @@ public class AccessibilitySettings extends DashboardFragment implements
private FeedbackManager getFeedbackManager() { private FeedbackManager getFeedbackManager() {
if (mFeedbackManager == null) { if (mFeedbackManager == null) {
mFeedbackManager = new FeedbackManager(getActivity()); mFeedbackManager = new FeedbackManager(getActivity(), SettingsEnums.ACCESSIBILITY);
} }
return mFeedbackManager; return mFeedbackManager;
} }

View File

@@ -16,7 +16,6 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.text.TextUtils; import android.text.TextUtils;
@@ -46,23 +45,14 @@ public class FeedbackManager {
* Constructs a new FeedbackManager. * Constructs a new FeedbackManager.
* *
* @param activity The activity context. A WeakReference is used to prevent memory leaks. * @param activity The activity context. A WeakReference is used to prevent memory leaks.
* @param pageId The unique identifier of the page associated with the feedback.
*/ */
public FeedbackManager(@Nullable Activity activity) { public FeedbackManager(@Nullable Activity activity, int pageId) {
this(activity, /* componentName= */ null);
}
/**
* Constructs a new FeedbackManager.
*
* @param activity The activity context. A WeakReference is used to prevent memory leaks.
* @param componentName The component name associated with the feedback.
*/
public FeedbackManager(@Nullable Activity activity, @Nullable ComponentName componentName) {
this(activity, this(activity,
DeviceInfoUtils.getFeedbackReporterPackage(activity), DeviceInfoUtils.getFeedbackReporterPackage(activity),
FeatureFactory.getFeatureFactory() FeatureFactory.getFeatureFactory()
.getAccessibilityFeedbackFeatureProvider() .getAccessibilityFeedbackFeatureProvider()
.getCategory(componentName)); .getCategory(pageId));
} }
/** /**

View File

@@ -31,8 +31,6 @@ import android.os.UserHandle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
@@ -59,6 +57,11 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature
return getArguments().getInt(AccessibilitySettings.EXTRA_METRICS_CATEGORY); return getArguments().getInt(AccessibilitySettings.EXTRA_METRICS_CATEGORY);
} }
@Override
public int getFeedbackCategory() {
return getArguments().getInt(AccessibilitySettings.EXTRA_FEEDBACK_CATEGORY);
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
@@ -115,13 +118,6 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature
return mTileComponentName; return mTileComponentName;
} }
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Do not call super. We don't want to see the "Help & feedback" option on this page so as
// not to confuse users who think they might be able to send feedback about a specific
// accessibility service from this page.
}
// IMPORTANT: Refresh the info since there are dynamically changing capabilities. // IMPORTANT: Refresh the info since there are dynamically changing capabilities.
private AccessibilityShortcutInfo getAccessibilityShortcutInfo() { private AccessibilityShortcutInfo getAccessibilityShortcutInfo() {
final List<AccessibilityShortcutInfo> infos = AccessibilityManager.getInstance( final List<AccessibilityShortcutInfo> infos = AccessibilityManager.getInstance(

View File

@@ -217,6 +217,7 @@ public class RestrictedPreferenceHelper {
extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, imageRes); extras.putInt(AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES, imageRes);
extras.putString(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, htmlDescription); extras.putString(AccessibilitySettings.EXTRA_HTML_DESCRIPTION, htmlDescription);
extras.putInt(AccessibilitySettings.EXTRA_METRICS_CATEGORY, metricsCategory); extras.putInt(AccessibilitySettings.EXTRA_METRICS_CATEGORY, metricsCategory);
extras.putInt(AccessibilitySettings.EXTRA_FEEDBACK_CATEGORY, metricsCategory);
} }
/** /**

View File

@@ -39,8 +39,6 @@ import android.os.SystemClock;
import android.text.BidiFormatter; import android.text.BidiFormatter;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.CompoundButton; import android.widget.CompoundButton;
@@ -76,10 +74,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
} }
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public int getFeedbackCategory() {
// Do not call super. We don't want to see the "Help & feedback" option on this page so as return getArguments().getInt(AccessibilitySettings.EXTRA_FEEDBACK_CATEGORY);
// not to confuse users who think they might be able to send feedback about a specific
// accessibility service from this page.
} }
@Override @Override

View File

@@ -40,6 +40,9 @@ import android.service.quicksettings.TileService;
import android.text.Html; import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
@@ -48,6 +51,7 @@ import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference; import androidx.preference.Preference;
@@ -89,6 +93,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
// <img src="R.drawable.fileName"/>, a11y settings will get the resources successfully. // <img src="R.drawable.fileName"/>, a11y settings will get the resources successfully.
private static final String IMG_PREFIX = "R.drawable."; private static final String IMG_PREFIX = "R.drawable.";
private static final String DRAWABLE_FOLDER = "drawable"; private static final String DRAWABLE_FOLDER = "drawable";
static final int MENU_ID_SEND_FEEDBACK = 0;
protected TopIntroPreference mTopIntroPreference; protected TopIntroPreference mTopIntroPreference;
protected SettingsMainSwitchPreference mToggleServiceSwitchPreference; protected SettingsMainSwitchPreference mToggleServiceSwitchPreference;
@@ -102,6 +107,7 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
protected Intent mSettingsIntent; protected Intent mSettingsIntent;
// The mComponentName maybe null, such as Magnify // The mComponentName maybe null, such as Magnify
protected ComponentName mComponentName; protected ComponentName mComponentName;
@Nullable private FeedbackManager mFeedbackManager;
protected CharSequence mFeatureName; protected CharSequence mFeatureName;
protected Uri mImageUri; protected Uri mImageUri;
protected CharSequence mHtmlDescription; protected CharSequence mHtmlDescription;
@@ -240,6 +246,24 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
removeActionBarToggleSwitch(); removeActionBarToggleSwitch();
} }
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
if (getFeedbackManager().isAvailable()) {
menu.add(Menu.NONE, MENU_ID_SEND_FEEDBACK, Menu.NONE,
R.string.accessibility_send_feedback_title);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == MENU_ID_SEND_FEEDBACK) {
getFeedbackManager().sendFeedback();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override @Override
public int getDialogMetricsCategory(int dialogId) { public int getDialogMetricsCategory(int dialogId) {
switch (dialogId) { switch (dialogId) {
@@ -739,4 +763,28 @@ public abstract class ToggleFeaturePreferenceFragment extends DashboardFragment
super.onCreateRecyclerView(inflater, parent, savedInstanceState); super.onCreateRecyclerView(inflater, parent, savedInstanceState);
return AccessibilityFragmentUtils.addCollectionInfoToAccessibilityDelegate(recyclerView); return AccessibilityFragmentUtils.addCollectionInfoToAccessibilityDelegate(recyclerView);
} }
@VisibleForTesting
void setFeedbackManager(FeedbackManager feedbackManager) {
this.mFeedbackManager = feedbackManager;
}
private FeedbackManager getFeedbackManager() {
if (mFeedbackManager == null) {
mFeedbackManager = new FeedbackManager(getActivity(), getFeedbackCategory());
}
return mFeedbackManager;
}
/**
* Returns the category of the feedback page.
*
* <p>By default, this method returns {@link SettingsEnums#PAGE_UNKNOWN}. This indicates that
* the feedback category is unknown, and the absence of a feedback menu.
*
* @return The feedback category, which is {@link SettingsEnums#PAGE_UNKNOWN} by default.
*/
protected int getFeedbackCategory() {
return SettingsEnums.PAGE_UNKNOWN;
}
} }

View File

@@ -79,6 +79,12 @@ public class ToggleScreenReaderPreferenceFragmentForSetupWizard
return SettingsEnums.SUW_ACCESSIBILITY_TOGGLE_SCREEN_READER; return SettingsEnums.SUW_ACCESSIBILITY_TOGGLE_SCREEN_READER;
} }
@Override
public int getFeedbackCategory() {
// The feedback options should not be displayed on the setup wizard page.
return SettingsEnums.PAGE_UNKNOWN;
}
@Override @Override
public void onStop() { public void onStop() {
// Log the final choice in value if it's different from the previous value. // Log the final choice in value if it's different from the previous value.

View File

@@ -79,6 +79,12 @@ public class ToggleSelectToSpeakPreferenceFragmentForSetupWizard
return SettingsEnums.SUW_ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK; return SettingsEnums.SUW_ACCESSIBILITY_TOGGLE_SELECT_TO_SPEAK;
} }
@Override
public int getFeedbackCategory() {
// The feedback options should not be displayed on the setup wizard page.
return SettingsEnums.PAGE_UNKNOWN;
}
@Override @Override
public void onStop() { public void onStop() {
// Log the final choice in value if it's different from the previous value. // Log the final choice in value if it's different from the previous value.

View File

@@ -17,7 +17,7 @@ package com.android.settings.overlay
import android.content.Context import android.content.Context
import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider
import com.android.settings.accessibility.AccessibilityMetricsFeatureProvider import com.android.settings.accessibility.AccessibilityPageIdFeatureProvider
import com.android.settings.accessibility.AccessibilitySearchFeatureProvider import com.android.settings.accessibility.AccessibilitySearchFeatureProvider
import com.android.settings.accounts.AccountFeatureProvider import com.android.settings.accounts.AccountFeatureProvider
import com.android.settings.applications.ApplicationFeatureProvider import com.android.settings.applications.ApplicationFeatureProvider
@@ -145,9 +145,9 @@ abstract class FeatureFactory {
abstract val accessibilitySearchFeatureProvider: AccessibilitySearchFeatureProvider abstract val accessibilitySearchFeatureProvider: AccessibilitySearchFeatureProvider
/** /**
* Retrieves implementation for Accessibility metrics category feature. * Retrieves implementation for Accessibility page id category feature.
*/ */
abstract val accessibilityMetricsFeatureProvider: AccessibilityMetricsFeatureProvider abstract val accessibilityPageIdFeatureProvider: AccessibilityPageIdFeatureProvider
/** /**
* Retrieves implementation for advanced vpn feature. * Retrieves implementation for advanced vpn feature.

View File

@@ -22,8 +22,8 @@ import android.net.VpnManager
import android.os.UserManager import android.os.UserManager
import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider
import com.android.settings.accessibility.AccessibilityFeedbackFeatureProviderImpl import com.android.settings.accessibility.AccessibilityFeedbackFeatureProviderImpl
import com.android.settings.accessibility.AccessibilityMetricsFeatureProvider import com.android.settings.accessibility.AccessibilityPageIdFeatureProvider
import com.android.settings.accessibility.AccessibilityMetricsFeatureProviderImpl import com.android.settings.accessibility.AccessibilityPageIdFeatureProviderImpl
import com.android.settings.accessibility.AccessibilitySearchFeatureProvider import com.android.settings.accessibility.AccessibilitySearchFeatureProvider
import com.android.settings.accessibility.AccessibilitySearchFeatureProviderImpl import com.android.settings.accessibility.AccessibilitySearchFeatureProviderImpl
import com.android.settings.accounts.AccountFeatureProvider import com.android.settings.accounts.AccountFeatureProvider
@@ -174,8 +174,8 @@ open class FeatureFactoryImpl : FeatureFactory() {
AccessibilitySearchFeatureProviderImpl() AccessibilitySearchFeatureProviderImpl()
} }
override val accessibilityMetricsFeatureProvider: AccessibilityMetricsFeatureProvider by lazy { override val accessibilityPageIdFeatureProvider: AccessibilityPageIdFeatureProvider by lazy {
AccessibilityMetricsFeatureProviderImpl() AccessibilityPageIdFeatureProviderImpl()
} }
override val advancedVpnFeatureProvider by lazy { AdvancedVpnFeatureProviderImpl() } override val advancedVpnFeatureProvider by lazy { AdvancedVpnFeatureProviderImpl() }

View File

@@ -22,7 +22,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -458,12 +457,10 @@ public class AccessibilitySettingsTest {
setupFragment(); setupFragment();
mFragment.setFeedbackManager( mFragment.setFeedbackManager(
new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY)); new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY));
when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null); mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null);
verify(mMenu).add(anyInt(), eq(AccessibilitySettings.MENU_ID_SEND_FEEDBACK), verify(mMenu).add(anyInt(), anyInt(), anyInt(), anyInt());
anyInt(), eq(mContext.getText(R.string.accessibility_send_feedback_title)));
} }
@Test @Test
@@ -472,12 +469,10 @@ public class AccessibilitySettingsTest {
setupFragment(); setupFragment();
mFragment.setFeedbackManager( mFragment.setFeedbackManager(
new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY)); new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY));
when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null); mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null);
verify(mMenu, never()).add(anyInt(), eq(AccessibilitySettings.MENU_ID_SEND_FEEDBACK), verify(mMenu, never()).add(anyInt(), anyInt(), anyInt(), anyInt());
anyInt(), eq(mContext.getText(R.string.accessibility_send_feedback_title)));
} }
@Test @Test
@@ -486,8 +481,6 @@ public class AccessibilitySettingsTest {
setupFragment(); setupFragment();
mFragment.setFeedbackManager( mFragment.setFeedbackManager(
new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY)); new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY));
when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null);
when(mMenuItem.getItemId()).thenReturn(AccessibilitySettings.MENU_ID_SEND_FEEDBACK); when(mMenuItem.getItemId()).thenReturn(AccessibilitySettings.MENU_ID_SEND_FEEDBACK);
mFragment.onOptionsItemSelected(mMenuItem); mFragment.onOptionsItemSelected(mMenuItem);
@@ -502,8 +495,6 @@ public class AccessibilitySettingsTest {
setupFragment(); setupFragment();
mFragment.setFeedbackManager( mFragment.setFeedbackManager(
new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY)); new FeedbackManager(mFragment.getActivity(), PACKAGE_NAME, DEFAULT_CATEGORY));
when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem);
mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null);
when(mMenuItem.getItemId()).thenReturn(AccessibilitySettings.MENU_ID_SEND_FEEDBACK); when(mMenuItem.getItemId()).thenReturn(AccessibilitySettings.MENU_ID_SEND_FEEDBACK);
mFragment.onOptionsItemSelected(mMenuItem); mFragment.onOptionsItemSelected(mMenuItem);

View File

@@ -23,9 +23,12 @@ import static com.android.internal.accessibility.common.ShortcutConstants.UserSh
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -37,10 +40,13 @@ import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.icu.text.CaseMap; import android.icu.text.CaseMap;
import android.os.Bundle; import android.os.Bundle;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings; import android.provider.Settings;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
@@ -66,8 +72,9 @@ import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Answers; import org.mockito.Answers;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy; import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config; import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow; import org.robolectric.shadow.api.Shadow;
@@ -83,6 +90,8 @@ import java.util.Locale;
ShadowAccessibilityManager.class ShadowAccessibilityManager.class
}) })
public class ToggleFeaturePreferenceFragmentTest { public class ToggleFeaturePreferenceFragmentTest {
@Rule
public final MockitoRule mocks = MockitoJUnit.rule();
@Rule @Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -96,6 +105,7 @@ public class ToggleFeaturePreferenceFragmentTest {
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME); PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_TILE_CLASS_NAME);
private static final String PLACEHOLDER_TILE_TOOLTIP_CONTENT = private static final String PLACEHOLDER_TILE_TOOLTIP_CONTENT =
PLACEHOLDER_PACKAGE_NAME + "tooltip_content"; PLACEHOLDER_PACKAGE_NAME + "tooltip_content";
private static final String PLACEHOLDER_CATEGORY = "category";
private static final String PLACEHOLDER_DIALOG_TITLE = "title"; private static final String PLACEHOLDER_DIALOG_TITLE = "title";
private static final String DEFAULT_SUMMARY = "default summary"; private static final String DEFAULT_SUMMARY = "default summary";
private static final String DEFAULT_DESCRIPTION = "default description"; private static final String DEFAULT_DESCRIPTION = "default description";
@@ -120,10 +130,13 @@ public class ToggleFeaturePreferenceFragmentTest {
private ContentResolver mContentResolver; private ContentResolver mContentResolver;
@Mock @Mock
private PackageManager mPackageManager; private PackageManager mPackageManager;
@Mock
private Menu mMenu;
@Mock
private MenuItem mMenuItem;
@Before @Before
public void setUpTestFragment() { public void setUpTestFragment() {
MockitoAnnotations.initMocks(this);
mShadowAccessibilityManager = Shadow.extract( mShadowAccessibilityManager = Shadow.extract(
mContext.getSystemService(AccessibilityManager.class)); mContext.getSystemService(AccessibilityManager.class));
@@ -169,6 +182,61 @@ public class ToggleFeaturePreferenceFragmentTest {
any(AccessibilitySettingsContentObserver.class)); any(AccessibilitySettingsContentObserver.class));
} }
@Test
@EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_LOW_VISION_GENERIC_FEEDBACK)
public void onCreateOptionsMenu_enableLowVisionGenericFeedback_shouldAddSendFeedbackMenu() {
mFragment.setFeedbackManager(
new FeedbackManager(mActivity, PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CATEGORY));
mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null);
verify(mMenu).add(anyInt(), eq(ToggleFeaturePreferenceFragment.MENU_ID_SEND_FEEDBACK),
anyInt(), eq(R.string.accessibility_send_feedback_title));
}
@Test
@DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_LOW_VISION_GENERIC_FEEDBACK)
public void onCreateOptionsMenu_disableLowVisionGenericFeedback_shouldNotAddSendFeedbackMenu() {
mFragment.setFeedbackManager(
new FeedbackManager(mActivity, PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CATEGORY));
mFragment.onCreateOptionsMenu(mMenu, /* inflater= */ null);
verify(mMenu, never()).add(anyInt(),
eq(ToggleFeaturePreferenceFragment.MENU_ID_SEND_FEEDBACK), anyInt(),
eq(R.string.accessibility_send_feedback_title));
}
@Test
@EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_LOW_VISION_GENERIC_FEEDBACK)
public void onOptionsItemSelected_enableLowVisionGenericFeedback_shouldStartSendFeedback() {
mFragment.setFeedbackManager(
new FeedbackManager(mActivity, PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CATEGORY));
when(mMenuItem.getItemId()).thenReturn(
ToggleFeaturePreferenceFragment.MENU_ID_SEND_FEEDBACK);
mFragment.onOptionsItemSelected(mMenuItem);
verify(mActivity).startActivityForResult(
argThat(intent -> intent != null
&& Intent.ACTION_BUG_REPORT.equals(intent.getAction())), anyInt());
}
@Test
@DisableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_LOW_VISION_GENERIC_FEEDBACK)
public void onOptionsItemSelected_disableLowVisionGenericFeedback_shouldNotStartSendFeedback() {
mFragment.setFeedbackManager(
new FeedbackManager(mActivity, PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CATEGORY));
when(mMenuItem.getItemId()).thenReturn(
ToggleFeaturePreferenceFragment.MENU_ID_SEND_FEEDBACK);
mFragment.onOptionsItemSelected(mMenuItem);
verify(mActivity, never()).startActivityForResult(
argThat(intent -> intent != null
&& Intent.ACTION_BUG_REPORT.equals(intent.getAction())), anyInt());
}
@Test @Test
public void updateShortcutPreferenceData_assignDefaultValueToVariable() { public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME; mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;

View File

@@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock;
import android.content.Context; import android.content.Context;
import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider; import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider;
import com.android.settings.accessibility.AccessibilityMetricsFeatureProvider; import com.android.settings.accessibility.AccessibilityPageIdFeatureProvider;
import com.android.settings.accessibility.AccessibilitySearchFeatureProvider; import com.android.settings.accessibility.AccessibilitySearchFeatureProvider;
import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider;
@@ -94,7 +94,7 @@ public class FakeFeatureFactory extends FeatureFactory {
public WifiTrackerLibProvider wifiTrackerLibProvider; public WifiTrackerLibProvider wifiTrackerLibProvider;
public SecuritySettingsFeatureProvider securitySettingsFeatureProvider; public SecuritySettingsFeatureProvider securitySettingsFeatureProvider;
public AccessibilitySearchFeatureProvider mAccessibilitySearchFeatureProvider; public AccessibilitySearchFeatureProvider mAccessibilitySearchFeatureProvider;
public AccessibilityMetricsFeatureProvider mAccessibilityMetricsFeatureProvider; public AccessibilityPageIdFeatureProvider mAccessibilityPageIdFeatureProvider;
public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider; public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider;
public WifiFeatureProvider mWifiFeatureProvider; public WifiFeatureProvider mWifiFeatureProvider;
public KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider; public KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider;
@@ -145,7 +145,7 @@ public class FakeFeatureFactory extends FeatureFactory {
wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class); wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class); securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
mAccessibilitySearchFeatureProvider = mock(AccessibilitySearchFeatureProvider.class); mAccessibilitySearchFeatureProvider = mock(AccessibilitySearchFeatureProvider.class);
mAccessibilityMetricsFeatureProvider = mock(AccessibilityMetricsFeatureProvider.class); mAccessibilityPageIdFeatureProvider = mock(AccessibilityPageIdFeatureProvider.class);
mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class); mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
mWifiFeatureProvider = mock(WifiFeatureProvider.class); mWifiFeatureProvider = mock(WifiFeatureProvider.class);
mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class); mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class);
@@ -294,8 +294,8 @@ public class FakeFeatureFactory extends FeatureFactory {
} }
@Override @Override
public AccessibilityMetricsFeatureProvider getAccessibilityMetricsFeatureProvider() { public AccessibilityPageIdFeatureProvider getAccessibilityPageIdFeatureProvider() {
return mAccessibilityMetricsFeatureProvider; return mAccessibilityPageIdFeatureProvider;
} }
@Override @Override

View File

@@ -18,7 +18,7 @@ package com.android.settings.testutils
import android.content.Context import android.content.Context
import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider
import com.android.settings.accessibility.AccessibilityMetricsFeatureProvider import com.android.settings.accessibility.AccessibilityPageIdFeatureProvider
import com.android.settings.accessibility.AccessibilitySearchFeatureProvider import com.android.settings.accessibility.AccessibilitySearchFeatureProvider
import com.android.settings.accounts.AccountFeatureProvider import com.android.settings.accounts.AccountFeatureProvider
import com.android.settings.applications.ApplicationFeatureProvider import com.android.settings.applications.ApplicationFeatureProvider
@@ -130,7 +130,7 @@ class FakeFeatureFactory : FeatureFactory() {
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
override val accessibilitySearchFeatureProvider: AccessibilitySearchFeatureProvider override val accessibilitySearchFeatureProvider: AccessibilitySearchFeatureProvider
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
override val accessibilityMetricsFeatureProvider: AccessibilityMetricsFeatureProvider override val accessibilityPageIdFeatureProvider: AccessibilityPageIdFeatureProvider
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
override val advancedVpnFeatureProvider: AdvancedVpnFeatureProvider override val advancedVpnFeatureProvider: AdvancedVpnFeatureProvider
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")

View File

@@ -20,7 +20,7 @@ import static org.mockito.Mockito.mock;
import android.content.Context; import android.content.Context;
import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider; import com.android.settings.accessibility.AccessibilityFeedbackFeatureProvider;
import com.android.settings.accessibility.AccessibilityMetricsFeatureProvider; import com.android.settings.accessibility.AccessibilityPageIdFeatureProvider;
import com.android.settings.accessibility.AccessibilitySearchFeatureProvider; import com.android.settings.accessibility.AccessibilitySearchFeatureProvider;
import com.android.settings.accounts.AccountFeatureProvider; import com.android.settings.accounts.AccountFeatureProvider;
import com.android.settings.applications.ApplicationFeatureProvider; import com.android.settings.applications.ApplicationFeatureProvider;
@@ -93,7 +93,7 @@ public class FakeFeatureFactory extends FeatureFactory {
public WifiTrackerLibProvider wifiTrackerLibProvider; public WifiTrackerLibProvider wifiTrackerLibProvider;
public SecuritySettingsFeatureProvider securitySettingsFeatureProvider; public SecuritySettingsFeatureProvider securitySettingsFeatureProvider;
public AccessibilitySearchFeatureProvider mAccessibilitySearchFeatureProvider; public AccessibilitySearchFeatureProvider mAccessibilitySearchFeatureProvider;
public AccessibilityMetricsFeatureProvider mAccessibilityMetricsFeatureProvider; public AccessibilityPageIdFeatureProvider mAccessibilityPageIdFeatureProvider;
public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider; public AdvancedVpnFeatureProvider mAdvancedVpnFeatureProvider;
public WifiFeatureProvider mWifiFeatureProvider; public WifiFeatureProvider mWifiFeatureProvider;
public KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider; public KeyboardSettingsFeatureProvider mKeyboardSettingsFeatureProvider;
@@ -146,7 +146,7 @@ public class FakeFeatureFactory extends FeatureFactory {
wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class); wifiTrackerLibProvider = mock(WifiTrackerLibProvider.class);
securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class); securitySettingsFeatureProvider = mock(SecuritySettingsFeatureProvider.class);
mAccessibilitySearchFeatureProvider = mock(AccessibilitySearchFeatureProvider.class); mAccessibilitySearchFeatureProvider = mock(AccessibilitySearchFeatureProvider.class);
mAccessibilityMetricsFeatureProvider = mock(AccessibilityMetricsFeatureProvider.class); mAccessibilityPageIdFeatureProvider = mock(AccessibilityPageIdFeatureProvider.class);
mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class); mAdvancedVpnFeatureProvider = mock(AdvancedVpnFeatureProvider.class);
mWifiFeatureProvider = mock(WifiFeatureProvider.class); mWifiFeatureProvider = mock(WifiFeatureProvider.class);
mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class); mKeyboardSettingsFeatureProvider = mock(KeyboardSettingsFeatureProvider.class);
@@ -295,8 +295,8 @@ public class FakeFeatureFactory extends FeatureFactory {
} }
@Override @Override
public AccessibilityMetricsFeatureProvider getAccessibilityMetricsFeatureProvider() { public AccessibilityPageIdFeatureProvider getAccessibilityPageIdFeatureProvider() {
return mAccessibilityMetricsFeatureProvider; return mAccessibilityPageIdFeatureProvider;
} }
@Override @Override