Remove obsolete broadcast behavior
There is no need to broadcast when a footer is displayed/removed. The broadcasts were added specifically for gmscore to know when the footer was visible, so that GLS consent could be given. However, this was only very briefly actually used within GmsCore, and has been obsolete for several releases. Test: CTS Change-Id: I1df6c6214fe79c943cabd7b04357c8ab7d1c1c39
This commit is contained in:
@@ -28,9 +28,6 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
|
||||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
|
||||||
import com.android.settingslib.widget.FooterPreference;
|
import com.android.settingslib.widget.FooterPreference;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -41,24 +38,19 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* Preference controller for location footer preference category
|
* Preference controller for location footer preference category
|
||||||
*/
|
*/
|
||||||
public class LocationFooterPreferenceController extends LocationBasePreferenceController
|
public class LocationFooterPreferenceController extends LocationBasePreferenceController {
|
||||||
implements LifecycleObserver, OnPause {
|
|
||||||
private static final String TAG = "LocationFooter";
|
private static final String TAG = "LocationFooter";
|
||||||
private static final String KEY_LOCATION_FOOTER = "location_footer";
|
private static final String KEY_LOCATION_FOOTER = "location_footer";
|
||||||
private static final Intent INJECT_INTENT =
|
private static final Intent INJECT_INTENT =
|
||||||
new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
||||||
private final Context mContext;
|
|
||||||
private final PackageManager mPackageManager;
|
|
||||||
private Collection<ComponentName> mFooterInjectors;
|
|
||||||
|
|
||||||
public LocationFooterPreferenceController(Context context, Lifecycle lifecycle) {
|
private final PackageManager mPackageManager;
|
||||||
super(context, lifecycle);
|
|
||||||
mContext = context;
|
public LocationFooterPreferenceController(Context context) {
|
||||||
mPackageManager = mContext.getPackageManager();
|
// we don't care location mode changes, so pass in a null lifecycle to disable listening
|
||||||
mFooterInjectors = new ArrayList<>();
|
super(context, null);
|
||||||
if (lifecycle != null) {
|
mPackageManager = context.getPackageManager();
|
||||||
lifecycle.addObserver(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,37 +59,30 @@ public class LocationFooterPreferenceController extends LocationBasePreferenceCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert footer preferences. Send a {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION}
|
* Insert footer preferences.
|
||||||
* broadcast to receivers who have injected a footer
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
PreferenceCategory category = (PreferenceCategory) preference;
|
PreferenceCategory category = (PreferenceCategory) preference;
|
||||||
category.removeAll();
|
category.removeAll();
|
||||||
mFooterInjectors.clear();
|
|
||||||
Collection<FooterData> footerData = getFooterData();
|
Collection<FooterData> footerData = getFooterData();
|
||||||
for (FooterData data : footerData) {
|
for (FooterData data : footerData) {
|
||||||
// Generate a footer preference with the given text
|
|
||||||
FooterPreference footerPreference = new FooterPreference(preference.getContext());
|
|
||||||
String footerString;
|
|
||||||
try {
|
try {
|
||||||
footerString =
|
String footerString =
|
||||||
mPackageManager
|
mPackageManager
|
||||||
.getResourcesForApplication(data.applicationInfo)
|
.getResourcesForApplication(data.applicationInfo)
|
||||||
.getString(data.footerStringRes);
|
.getString(data.footerStringRes);
|
||||||
|
|
||||||
|
// Generate a footer preference with the given text
|
||||||
|
FooterPreference footerPreference = new FooterPreference(preference.getContext());
|
||||||
|
footerPreference.setTitle(footerString);
|
||||||
|
category.addPreference(footerPreference);
|
||||||
} catch (NameNotFoundException exception) {
|
} catch (NameNotFoundException exception) {
|
||||||
Log.w(
|
Log.w(
|
||||||
TAG,
|
TAG,
|
||||||
"Resources not found for application "
|
"Resources not found for application "
|
||||||
+ data.applicationInfo.packageName);
|
+ data.applicationInfo.packageName);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
footerPreference.setTitle(footerString);
|
|
||||||
// Inject the footer
|
|
||||||
category.addPreference(footerPreference);
|
|
||||||
// Send broadcast to the injector announcing a footer has been injected
|
|
||||||
sendBroadcastFooterDisplayed(data.componentName);
|
|
||||||
mFooterInjectors.add(data.componentName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,37 +101,12 @@ public class LocationFooterPreferenceController extends LocationBasePreferenceCo
|
|||||||
return !getFooterData().isEmpty();
|
return !getFooterData().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a {@link LocationManager#SETTINGS_FOOTER_REMOVED_ACTION} broadcast to footer injectors
|
|
||||||
* when LocationFragment is on pause
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
// Send broadcast to the footer injectors. Notify them the footer is not visible.
|
|
||||||
for (ComponentName componentName : mFooterInjectors) {
|
|
||||||
final Intent intent = new Intent(LocationManager.SETTINGS_FOOTER_REMOVED_ACTION);
|
|
||||||
intent.setComponent(componentName);
|
|
||||||
mContext.sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send a {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast to a footer
|
|
||||||
* injector.
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
void sendBroadcastFooterDisplayed(ComponentName componentName) {
|
|
||||||
Intent intent = new Intent(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
|
||||||
intent.setComponent(componentName);
|
|
||||||
mContext.sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of strings with text provided by ACTION_INJECT_FOOTER broadcast receivers.
|
* Return a list of strings with text provided by ACTION_INJECT_FOOTER broadcast receivers.
|
||||||
*/
|
*/
|
||||||
private Collection<FooterData> getFooterData() {
|
private List<FooterData> getFooterData() {
|
||||||
// Fetch footer text from system apps
|
// Fetch footer text from system apps
|
||||||
final List<ResolveInfo> resolveInfos =
|
List<ResolveInfo> resolveInfos =
|
||||||
mPackageManager.queryBroadcastReceivers(
|
mPackageManager.queryBroadcastReceivers(
|
||||||
INJECT_INTENT, PackageManager.GET_META_DATA);
|
INJECT_INTENT, PackageManager.GET_META_DATA);
|
||||||
if (resolveInfos == null) {
|
if (resolveInfos == null) {
|
||||||
@@ -158,10 +118,10 @@ public class LocationFooterPreferenceController extends LocationBasePreferenceCo
|
|||||||
Log.d(TAG, "Found broadcast receivers: " + resolveInfos);
|
Log.d(TAG, "Found broadcast receivers: " + resolveInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Collection<FooterData> footerDataList = new ArrayList<>(resolveInfos.size());
|
List<FooterData> footerDataList = new ArrayList<>(resolveInfos.size());
|
||||||
for (ResolveInfo resolveInfo : resolveInfos) {
|
for (ResolveInfo resolveInfo : resolveInfos) {
|
||||||
final ActivityInfo activityInfo = resolveInfo.activityInfo;
|
ActivityInfo activityInfo = resolveInfo.activityInfo;
|
||||||
final ApplicationInfo appInfo = activityInfo.applicationInfo;
|
ApplicationInfo appInfo = activityInfo.applicationInfo;
|
||||||
|
|
||||||
// If a non-system app tries to inject footer, ignore it
|
// If a non-system app tries to inject footer, ignore it
|
||||||
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
|
||||||
@@ -187,11 +147,7 @@ public class LocationFooterPreferenceController extends LocationBasePreferenceCo
|
|||||||
+ LocationManager.METADATA_SETTINGS_FOOTER_STRING);
|
+ LocationManager.METADATA_SETTINGS_FOOTER_STRING);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
footerDataList.add(
|
footerDataList.add(new FooterData(footerTextRes, appInfo));
|
||||||
new FooterData(
|
|
||||||
footerTextRes,
|
|
||||||
appInfo,
|
|
||||||
new ComponentName(activityInfo.packageName, activityInfo.name)));
|
|
||||||
}
|
}
|
||||||
return footerDataList;
|
return footerDataList;
|
||||||
}
|
}
|
||||||
@@ -207,14 +163,9 @@ public class LocationFooterPreferenceController extends LocationBasePreferenceCo
|
|||||||
// Application info of receiver injecting this footer
|
// Application info of receiver injecting this footer
|
||||||
final ApplicationInfo applicationInfo;
|
final ApplicationInfo applicationInfo;
|
||||||
|
|
||||||
// The component that injected the footer. It must be a receiver of broadcast
|
FooterData(int footerRes, ApplicationInfo appInfo) {
|
||||||
// LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION
|
|
||||||
final ComponentName componentName;
|
|
||||||
|
|
||||||
FooterData(int footerRes, ApplicationInfo appInfo, ComponentName componentName) {
|
|
||||||
this.footerStringRes = footerRes;
|
this.footerStringRes = footerRes;
|
||||||
this.applicationInfo = appInfo;
|
this.applicationInfo = appInfo;
|
||||||
this.componentName = componentName;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -121,7 +121,7 @@ public class LocationSettings extends DashboardFragment {
|
|||||||
controllers.add(new RecentLocationRequestPreferenceController(context, fragment, lifecycle));
|
controllers.add(new RecentLocationRequestPreferenceController(context, fragment, lifecycle));
|
||||||
controllers.add(new LocationScanningPreferenceController(context));
|
controllers.add(new LocationScanningPreferenceController(context));
|
||||||
controllers.add(new LocationServicePreferenceController(context, fragment, lifecycle));
|
controllers.add(new LocationServicePreferenceController(context, fragment, lifecycle));
|
||||||
controllers.add(new LocationFooterPreferenceController(context, lifecycle));
|
controllers.add(new LocationFooterPreferenceController(context));
|
||||||
return controllers;
|
return controllers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -158,10 +158,6 @@ public class LocationEnablerTest {
|
|||||||
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
|
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
|
||||||
mEnabler.setLocationEnabled(true);
|
mEnabler.setLocationEnabled(true);
|
||||||
|
|
||||||
verify(mContext).sendBroadcastAsUser(
|
|
||||||
argThat(actionMatches(LocationManager.MODE_CHANGING_ACTION)),
|
|
||||||
eq(UserHandle.of(ActivityManager.getCurrentUser())),
|
|
||||||
eq(WRITE_SECURE_SETTINGS));
|
|
||||||
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
|
assertThat(Settings.Secure.getInt(mContext.getContentResolver(),
|
||||||
Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
|
Settings.Secure.LOCATION_CHANGER, Settings.Secure.LOCATION_CHANGER_UNKNOWN))
|
||||||
.isEqualTo(Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
|
.isEqualTo(Settings.Secure.LOCATION_CHANGER_SYSTEM_SETTINGS);
|
||||||
|
@@ -22,11 +22,9 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
|||||||
import static org.mockito.Mockito.doNothing;
|
import static org.mockito.Mockito.doNothing;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
@@ -38,12 +36,9 @@ import android.content.res.Resources;
|
|||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import androidx.preference.PreferenceCategory;
|
import androidx.preference.PreferenceCategory;
|
||||||
|
|
||||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -65,22 +60,17 @@ public class LocationFooterPreferenceControllerTest {
|
|||||||
private PackageManager mPackageManager;
|
private PackageManager mPackageManager;
|
||||||
@Mock
|
@Mock
|
||||||
private Resources mResources;
|
private Resources mResources;
|
||||||
private Context mContext;
|
|
||||||
private LocationFooterPreferenceController mController;
|
private LocationFooterPreferenceController mController;
|
||||||
private LifecycleOwner mLifecycleOwner;
|
|
||||||
private Lifecycle mLifecycle;
|
|
||||||
private static final int TEST_RES_ID = 1234;
|
private static final int TEST_RES_ID = 1234;
|
||||||
private static final String TEST_TEXT = "text";
|
private static final String TEST_TEXT = "text";
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws NameNotFoundException {
|
public void setUp() throws NameNotFoundException {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
Context context = spy(RuntimeEnvironment.application);
|
||||||
when(mContext.getPackageManager()).thenReturn(mPackageManager);
|
when(context.getPackageManager()).thenReturn(mPackageManager);
|
||||||
mLifecycleOwner = () -> mLifecycle;
|
when(mPreferenceCategory.getContext()).thenReturn(context);
|
||||||
mLifecycle = new Lifecycle(mLifecycleOwner);
|
mController = spy(new LocationFooterPreferenceController(context));
|
||||||
when(mPreferenceCategory.getContext()).thenReturn(mContext);
|
|
||||||
mController = spy(new LocationFooterPreferenceController(mContext, mLifecycle));
|
|
||||||
when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class)))
|
when(mPackageManager.getResourcesForApplication(any(ApplicationInfo.class)))
|
||||||
.thenReturn(mResources);
|
.thenReturn(mResources);
|
||||||
when(mResources.getString(TEST_RES_ID)).thenReturn(TEST_TEXT);
|
when(mResources.getString(TEST_RES_ID)).thenReturn(TEST_TEXT);
|
||||||
@@ -118,32 +108,6 @@ public class LocationFooterPreferenceControllerTest {
|
|||||||
assertThat(mController.isAvailable()).isFalse();
|
assertThat(mController.isAvailable()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sendBroadcastFooterInject() {
|
|
||||||
ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
|
||||||
final ActivityInfo activityInfo =
|
|
||||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true).activityInfo;
|
|
||||||
mController.sendBroadcastFooterDisplayed(
|
|
||||||
new ComponentName(activityInfo.packageName, activityInfo.name));
|
|
||||||
verify(mContext).sendBroadcast(intent.capture());
|
|
||||||
assertThat(intent.getValue().getAction())
|
|
||||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void updateState_sendBroadcast() {
|
|
||||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
|
||||||
testResolveInfos.add(
|
|
||||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
|
|
||||||
when(mPackageManager.queryBroadcastReceivers(any(), anyInt()))
|
|
||||||
.thenReturn(testResolveInfos);
|
|
||||||
mController.updateState(mPreferenceCategory);
|
|
||||||
ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
|
||||||
verify(mContext).sendBroadcast(intent.capture());
|
|
||||||
assertThat(intent.getValue().getAction())
|
|
||||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateState_addPreferences() {
|
public void updateState_addPreferences() {
|
||||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
||||||
@@ -166,32 +130,6 @@ public class LocationFooterPreferenceControllerTest {
|
|||||||
.thenReturn(testResolveInfos);
|
.thenReturn(testResolveInfos);
|
||||||
mController.updateState(mPreferenceCategory);
|
mController.updateState(mPreferenceCategory);
|
||||||
verify(mPreferenceCategory, never()).addPreference(any(Preference.class));
|
verify(mPreferenceCategory, never()).addPreference(any(Preference.class));
|
||||||
verify(mContext, never()).sendBroadcast(any(Intent.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void updateState_thenOnPause_sendBroadcasts() {
|
|
||||||
final List<ResolveInfo> testResolveInfos = new ArrayList<>();
|
|
||||||
testResolveInfos.add(
|
|
||||||
getTestResolveInfo(/*isSystemApp*/ true, /*hasRequiredMetadata*/ true));
|
|
||||||
when(mPackageManager.queryBroadcastReceivers(any(Intent.class), anyInt()))
|
|
||||||
.thenReturn(testResolveInfos);
|
|
||||||
mController.updateState(mPreferenceCategory);
|
|
||||||
ArgumentCaptor<Intent> intent = ArgumentCaptor.forClass(Intent.class);
|
|
||||||
verify(mContext).sendBroadcast(intent.capture());
|
|
||||||
assertThat(intent.getValue().getAction())
|
|
||||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_DISPLAYED_ACTION);
|
|
||||||
|
|
||||||
mController.onPause();
|
|
||||||
verify(mContext, times(2)).sendBroadcast(intent.capture());
|
|
||||||
assertThat(intent.getValue().getAction())
|
|
||||||
.isEqualTo(LocationManager.SETTINGS_FOOTER_REMOVED_ACTION);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onPause_doNotSendBroadcast() {
|
|
||||||
mController.onPause();
|
|
||||||
verify(mContext, never()).sendBroadcast(any(Intent.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user