/** * Copyright (C) 2016 LinkedIn Corp. * <p> * 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 * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * 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.linkedin.android.testbutler; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.ContentResolver; import android.location.LocationManager; import android.os.Build; import android.provider.Settings; import android.support.annotation.NonNull; import android.util.Log; /** * Helper class for modifying the location services mode on the emulator * <p> * NOTE: the settings for location services changed in Android 4.4 (KitKat). This class handles * both the pre and post KitKat methods for modifying location services. */ @SuppressLint("InlinedApi") class LocationServicesChanger { private static final String TAG = LocationServicesChanger.class.getSimpleName(); private int originalLocationMode; private String originalLocationProviders; /** * Should be called before starting tests, to save original location services values */ @SuppressWarnings("deprecation") void saveLocationServicesState(@NonNull ContentResolver contentResolver) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { originalLocationProviders = Settings.Secure.getString(contentResolver, Settings.Secure.LOCATION_PROVIDERS_ALLOWED); } else { try { originalLocationMode = Settings.Secure.getInt(contentResolver, Settings.Secure.LOCATION_MODE); } catch (Settings.SettingNotFoundException e) { Log.e(TAG, "Error reading location mode settings!", e); } } } /** * Should be called after testing completes, to restore original location services values */ void restoreLocationServicesState(@NonNull ContentResolver contentResolver) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { setLocationServicesStatePreKitKat(contentResolver, originalLocationProviders); } else { setLocationServicesState(contentResolver, originalLocationMode); } } /** * Set a custom location mode * * @param contentResolver the {@link ContentResolver} used to modify settings * @param locationMode the desired location mode value to be set * @return true if the new value was set, false on database errors */ boolean setLocationServicesState(@NonNull ContentResolver contentResolver, int locationMode) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { switch (locationMode) { case Settings.Secure.LOCATION_MODE_OFF: return setLocationServicesStatePreKitKat(contentResolver, ""); case Settings.Secure.LOCATION_MODE_BATTERY_SAVING: return setLocationServicesStatePreKitKat(contentResolver, LocationManager.PASSIVE_PROVIDER); case Settings.Secure.LOCATION_MODE_SENSORS_ONLY: return setLocationServicesStatePreKitKat( contentResolver, String.format("%s,%s", LocationManager.PASSIVE_PROVIDER, LocationManager.GPS_PROVIDER)); case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY: return setLocationServicesStatePreKitKat( contentResolver, String.format("%s,%s,%s", LocationManager.PASSIVE_PROVIDER, LocationManager.NETWORK_PROVIDER, LocationManager.GPS_PROVIDER)); default: throw new IllegalArgumentException("Unknown location mode: " + locationMode); } } else { return setLocationServicesStateKitKat(contentResolver, locationMode); } } @SuppressWarnings("deprecation") private boolean setLocationServicesStatePreKitKat(@NonNull ContentResolver contentResolver, @NonNull String providers) { return Settings.Secure.putString(contentResolver, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, providers); } @TargetApi(Build.VERSION_CODES.KITKAT) private boolean setLocationServicesStateKitKat(@NonNull ContentResolver contentResolver, int locationMode) { return Settings.Secure.putInt(contentResolver, Settings.Secure.LOCATION_MODE, locationMode); } }