1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.incallui.calllocation.impl; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.content.Intent; 22import android.content.pm.PackageManager; 23import android.content.pm.ResolveInfo; 24import android.database.Cursor; 25import android.net.Uri; 26import android.provider.Settings.Secure; 27import android.provider.Settings.SettingNotFoundException; 28import com.android.dialer.common.LogUtil; 29 30/** 31 * Helper class to check if Google Location Services is enabled. This class is based on 32 * https://docs.google.com/a/google.com/document/d/1sGm8pHgGY1QmxbLCwTZuWQASEDN7CFW9EPSZXAuGQfo 33 */ 34public class GoogleLocationSettingHelper { 35 36 /** User has disagreed to use location for Google services. */ 37 public static final int USE_LOCATION_FOR_SERVICES_OFF = 0; 38 /** User has agreed to use location for Google services. */ 39 public static final int USE_LOCATION_FOR_SERVICES_ON = 1; 40 /** The user has neither agreed nor disagreed to use location for Google services yet. */ 41 public static final int USE_LOCATION_FOR_SERVICES_NOT_SET = 2; 42 43 private static final String GOOGLE_SETTINGS_AUTHORITY = "com.google.settings"; 44 private static final Uri GOOGLE_SETTINGS_CONTENT_URI = 45 Uri.parse("content://" + GOOGLE_SETTINGS_AUTHORITY + "/partner"); 46 private static final String NAME = "name"; 47 private static final String VALUE = "value"; 48 private static final String USE_LOCATION_FOR_SERVICES = "use_location_for_services"; 49 50 /** Determine if Google apps need to conform to the USE_LOCATION_FOR_SERVICES setting. */ 51 public static boolean isEnforceable(Context context) { 52 final ResolveInfo ri = 53 context 54 .getPackageManager() 55 .resolveActivity( 56 new Intent("com.google.android.gsf.GOOGLE_APPS_LOCATION_SETTINGS"), 57 PackageManager.MATCH_DEFAULT_ONLY); 58 return ri != null; 59 } 60 61 /** 62 * Get the current value for the 'Use value for location' setting. 63 * 64 * @return One of {@link #USE_LOCATION_FOR_SERVICES_NOT_SET}, {@link 65 * #USE_LOCATION_FOR_SERVICES_OFF} or {@link #USE_LOCATION_FOR_SERVICES_ON}. 66 */ 67 private static int getUseLocationForServices(Context context) { 68 final ContentResolver resolver = context.getContentResolver(); 69 Cursor c = null; 70 String stringValue = null; 71 try { 72 c = 73 resolver.query( 74 GOOGLE_SETTINGS_CONTENT_URI, 75 new String[] {VALUE}, 76 NAME + "=?", 77 new String[] {USE_LOCATION_FOR_SERVICES}, 78 null); 79 if (c != null && c.moveToNext()) { 80 stringValue = c.getString(0); 81 } 82 } catch (final RuntimeException e) { 83 LogUtil.e( 84 "GoogleLocationSettingHelper.getUseLocationForServices", 85 "Failed to get 'Use My Location' setting", 86 e); 87 } finally { 88 if (c != null) { 89 c.close(); 90 } 91 } 92 if (stringValue == null) { 93 return USE_LOCATION_FOR_SERVICES_NOT_SET; 94 } 95 int value; 96 try { 97 value = Integer.parseInt(stringValue); 98 } catch (final NumberFormatException nfe) { 99 value = USE_LOCATION_FOR_SERVICES_NOT_SET; 100 } 101 return value; 102 } 103 104 /** Whether or not the system location setting is enable */ 105 public static boolean isSystemLocationSettingEnabled(Context context) { 106 try { 107 return Secure.getInt(context.getContentResolver(), Secure.LOCATION_MODE) 108 != Secure.LOCATION_MODE_OFF; 109 } catch (SettingNotFoundException e) { 110 LogUtil.e( 111 "GoogleLocationSettingHelper.isSystemLocationSettingEnabled", 112 "Failed to get System Location setting", 113 e); 114 return false; 115 } 116 } 117 118 /** Convenience method that returns true is GLS is ON or if it's not enforceable. */ 119 public static boolean isGoogleLocationServicesEnabled(Context context) { 120 return !isEnforceable(context) 121 || getUseLocationForServices(context) == USE_LOCATION_FOR_SERVICES_ON; 122 } 123} 124