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 17 package com.android.incallui.calllocation.impl; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.PackageManager; 23 import android.content.pm.ResolveInfo; 24 import android.database.Cursor; 25 import android.net.Uri; 26 import android.provider.Settings.Secure; 27 import android.provider.Settings.SettingNotFoundException; 28 import com.android.dialer.common.LogUtil; 29 import com.android.dialer.strictmode.StrictModeUtils; 30 31 /** 32 * Helper class to check if Google Location Services is enabled. This class is based on 33 34 */ 35 public class GoogleLocationSettingHelper { 36 37 /** User has disagreed to use location for Google services. */ 38 public static final int USE_LOCATION_FOR_SERVICES_OFF = 0; 39 /** User has agreed to use location for Google services. */ 40 public static final int USE_LOCATION_FOR_SERVICES_ON = 1; 41 /** The user has neither agreed nor disagreed to use location for Google services yet. */ 42 public static final int USE_LOCATION_FOR_SERVICES_NOT_SET = 2; 43 44 private static final String GOOGLE_SETTINGS_AUTHORITY = "com.google.settings"; 45 private static final Uri GOOGLE_SETTINGS_CONTENT_URI = 46 Uri.parse("content://" + GOOGLE_SETTINGS_AUTHORITY + "/partner"); 47 private static final String NAME = "name"; 48 private static final String VALUE = "value"; 49 private static final String USE_LOCATION_FOR_SERVICES = "use_location_for_services"; 50 51 /** Determine if Google apps need to conform to the USE_LOCATION_FOR_SERVICES setting. */ isEnforceable(Context context)52 private static boolean isEnforceable(Context context) { 53 final ResolveInfo ri = 54 context 55 .getPackageManager() 56 .resolveActivity( 57 new Intent("com.google.android.gsf.GOOGLE_APPS_LOCATION_SETTINGS"), 58 PackageManager.MATCH_DEFAULT_ONLY); 59 return ri != null; 60 } 61 62 /** 63 * Get the current value for the 'Use value for location' setting. 64 * 65 * @return One of {@link #USE_LOCATION_FOR_SERVICES_NOT_SET}, {@link 66 * #USE_LOCATION_FOR_SERVICES_OFF} or {@link #USE_LOCATION_FOR_SERVICES_ON}. 67 */ getUseLocationForServices(Context context)68 private static int getUseLocationForServices(Context context) { 69 final ContentResolver resolver = context.getContentResolver(); 70 Cursor c = null; 71 String stringValue = null; 72 try { 73 c = 74 resolver.query( 75 GOOGLE_SETTINGS_CONTENT_URI, 76 new String[] {VALUE}, 77 NAME + "=?", 78 new String[] {USE_LOCATION_FOR_SERVICES}, 79 null); 80 if (c != null && c.moveToNext()) { 81 stringValue = c.getString(0); 82 } 83 } catch (final RuntimeException e) { 84 LogUtil.e( 85 "GoogleLocationSettingHelper.getUseLocationForServices", 86 "Failed to get 'Use My Location' setting", 87 e); 88 } finally { 89 if (c != null) { 90 c.close(); 91 } 92 } 93 if (stringValue == null) { 94 return USE_LOCATION_FOR_SERVICES_NOT_SET; 95 } 96 int value; 97 try { 98 value = Integer.parseInt(stringValue); 99 } catch (final NumberFormatException nfe) { 100 value = USE_LOCATION_FOR_SERVICES_NOT_SET; 101 } 102 return value; 103 } 104 105 /** Whether or not the system location setting is enable */ isSystemLocationSettingEnabled(Context context)106 static boolean isSystemLocationSettingEnabled(Context context) { 107 try { 108 return Secure.getInt(context.getContentResolver(), Secure.LOCATION_MODE) 109 != Secure.LOCATION_MODE_OFF; 110 } catch (SettingNotFoundException e) { 111 LogUtil.e( 112 "GoogleLocationSettingHelper.isSystemLocationSettingEnabled", 113 "Failed to get System Location setting", 114 e); 115 return false; 116 } 117 } 118 119 /** Convenience method that returns true is GLS is ON or if it's not enforceable. */ isGoogleLocationServicesEnabled(Context context)120 static boolean isGoogleLocationServicesEnabled(Context context) { 121 if (!isEnforceable(context)) { 122 return true; 123 } 124 int locationServiceStatus = StrictModeUtils.bypass(() -> getUseLocationForServices(context)); 125 return locationServiceStatus == USE_LOCATION_FOR_SERVICES_ON; 126 } 127 } 128