Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dee34387 authored by Anil Admal's avatar Anil Admal Committed by Android (Google) Code Review
Browse files

Merge "Add emergency session extension duration (framework)"

parents bc4bfd6a d71cf149
Loading
Loading
Loading
Loading
+8 −21
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package com.android.internal.location;

import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeUnit;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -26,20 +23,23 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.LocationManager;
import android.location.INetInitiatedListener;
import android.location.LocationManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.os.UserHandle;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneStateListener;
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.TelephonyManager;
import android.util.Log;

import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.R;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.telephony.GsmAlphabet;

import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeUnit;

/**
 * A GPS Network-initiated Handler class used by LocationManager.
 *
@@ -92,9 +92,6 @@ public class GpsNetInitiatedHandler {
    public static final int GPS_ENC_SUPL_UCS2 = 3;
    public static final int GPS_ENC_UNKNOWN = -1;

    // Limit on SUPL NI emergency mode time extension after emergency sessions ends
    private static final int MAX_EMERGENCY_MODE_EXTENSION_SECONDS = 300;  // 5 minute maximum

    private final Context mContext;
    private final TelephonyManager mTelephonyManager;
    private final PhoneStateListener mPhoneStateListener;
@@ -252,19 +249,9 @@ public class GpsNetInitiatedHandler {
    }

    public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) {
        if (emergencyExtensionSeconds > MAX_EMERGENCY_MODE_EXTENSION_SECONDS) {
            Log.w(TAG, "emergencyExtensionSeconds " + emergencyExtensionSeconds
                    + " too high, reset to " + MAX_EMERGENCY_MODE_EXTENSION_SECONDS);
            emergencyExtensionSeconds = MAX_EMERGENCY_MODE_EXTENSION_SECONDS;
        } else if (emergencyExtensionSeconds < 0) {
            Log.w(TAG, "emergencyExtensionSeconds " + emergencyExtensionSeconds
                    + " is negative, reset to zero.");
            emergencyExtensionSeconds = 0;
        }
        mEmergencyExtensionMillis = TimeUnit.SECONDS.toMillis(emergencyExtensionSeconds);
    }


    // Handles NI events from HAL
    public void handleNiNotification(GpsNiNotification notif) {
        if (DEBUG) Log.d(TAG, "in handleNiNotification () :"
+365 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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.android.server.location;

import android.content.Context;
import android.os.PersistableBundle;
import android.os.SystemProperties;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;

import libcore.io.IoUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

/**
 * A utility class to hold GNSS configuration properties.
 *
 * The trigger to load/reload the configuration parameters should be managed by the class
 * that owns an instance of this class.
 *
 * Instances of this class are not thread-safe and should either be used from a single thread
 * or with external synchronization when used by multiple threads.
 */
class GnssConfiguration {
    private static final String TAG = "GnssConfiguration";

    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    //TODO(b/33112647): Create gps_debug.conf with commented career parameters.
    private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";

    // config.xml properties
    private static final String CONFIG_SUPL_HOST = "SUPL_HOST";
    private static final String CONFIG_SUPL_PORT = "SUPL_PORT";
    private static final String CONFIG_C2K_HOST = "C2K_HOST";
    private static final String CONFIG_C2K_PORT = "C2K_PORT";
    private static final String CONFIG_SUPL_VER = "SUPL_VER";
    private static final String CONFIG_SUPL_MODE = "SUPL_MODE";
    private static final String CONFIG_SUPL_ES = "SUPL_ES";
    private static final String CONFIG_LPP_PROFILE = "LPP_PROFILE";
    private static final String CONFIG_A_GLONASS_POS_PROTOCOL_SELECT =
            "A_GLONASS_POS_PROTOCOL_SELECT";
    private static final String CONFIG_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL =
            "USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL";
    private static final String CONFIG_GPS_LOCK = "GPS_LOCK";
    private static final String CONFIG_ES_EXTENSION_SEC = "ES_EXTENSION_SEC";

    // Limit on NI emergency mode time extension after emergency sessions ends
    private static final int MAX_EMERGENCY_MODE_EXTENSION_SECONDS = 300;  // 5 minute maximum

    // Persist property for LPP_PROFILE
    static final String LPP_PROFILE = "persist.sys.gps.lpp";

    // Represents an HAL interface version. Instances of this class are created in the JNI layer
    // and returned through native methods.
    private static class HalInterfaceVersion {
        final int mMajor;
        final int mMinor;

        HalInterfaceVersion(int major, int minor) {
            mMajor = major;
            mMinor = minor;
        }
    }

    /**
     * Properties loaded from PROPERTIES_FILE.
     */
    private Properties mProperties;

    private int mEsExtensionSec = 0;

    private final Context mContext;

    GnssConfiguration(Context context) {
        mContext = context;
        mProperties = new Properties();
    }

    /**
     * Returns the full set of properties loaded.
     */
    Properties getProperties() {
        return mProperties;
    }

    /**
     * Returns the value of config parameter ES_EXTENSION_SEC. The value is range checked
     * and constrained to min/max limits.
     */
    int getEsExtensionSec() {
        return mEsExtensionSec;
    }

    /**
     * Returns the value of config parameter SUPL_HOST or {@code null} if no value is
     * provided.
     */
    String getSuplHost() {
        return mProperties.getProperty(CONFIG_SUPL_HOST);
    }

    /**
     * Returns the value of config parameter SUPL_PORT or {@code defaultPort} if no value is
     * provided or if there is an error parsing the configured value.
     */
    int getSuplPort(int defaultPort) {
        return getIntConfig(CONFIG_SUPL_PORT, defaultPort);
    }

    /**
     * Returns the value of config parameter C2K_HOST or {@code null} if no value is
     * provided.
     */
    String getC2KHost() {
        return mProperties.getProperty(CONFIG_C2K_HOST);
    }

    /**
     * Returns the value of config parameter C2K_PORT or {@code defaultPort} if no value is
     * provided or if there is an error parsing the configured value.
     */
    int getC2KPort(int defaultPort) {
        return getIntConfig(CONFIG_C2K_PORT, defaultPort);
    }

    /**
     * Returns the value of config parameter SUPL_MODE or {@code defaultMode} if no value is
     * provided or if there is an error parsing the configured value.
     */
    int getSuplMode(int defaultMode) {
        return getIntConfig(CONFIG_SUPL_MODE, defaultMode);
    }

    /**
     * Returns the value of config parameter SUPL_ES or {@code defaultSuplEs} if no value is
     * provided or if there is an error parsing the configured value.
     */
    int getSuplEs(int defaulSuplEs) {
        return getIntConfig(CONFIG_SUPL_ES, defaulSuplEs);
    }

    /**
     * Returns the value of config parameter LPP_PROFILE or {@code null} if no value is
     * provided.
     */
    String getLppProfile() {
        return mProperties.getProperty(CONFIG_LPP_PROFILE);
    }

    /**
     * Updates the GNSS HAL satellite blacklist.
     */
    void setSatelliteBlacklist(int[] constellations, int[] svids) {
        native_set_satellite_blacklist(constellations, svids);
    }

    interface SetCarrierProperty {
        boolean set(int value);
    }

    /**
     * Loads the GNSS properties from carrier config file followed by the properties from
     * gps debug config file.
     */
    void reloadGpsProperties() {
        if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + mProperties.size());
        loadPropertiesFromCarrierConfig();

        String lpp_prof = SystemProperties.get(LPP_PROFILE);
        if (!TextUtils.isEmpty(lpp_prof)) {
            // override default value of this if lpp_prof is not empty
            mProperties.setProperty(CONFIG_LPP_PROFILE, lpp_prof);
        }
        /*
         * Overlay carrier properties from a debug configuration file.
         */
        loadPropertiesFromGpsDebugConfig(mProperties);

        mEsExtensionSec = getRangeCheckedConfigEsExtensionSec();

        final HalInterfaceVersion gnssConfigurationIfaceVersion =
                native_get_gnss_configuration_version();
        if (gnssConfigurationIfaceVersion != null) {
            // Set to a range checked value.
            if (isConfigEsExtensionSecSupported(gnssConfigurationIfaceVersion)
                    && !native_set_es_extension_sec(mEsExtensionSec)) {
                Log.e(TAG, "Unable to set " + CONFIG_ES_EXTENSION_SEC + ": " + mEsExtensionSec);
            }

            Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() {
                {
                    put(CONFIG_SUPL_VER, GnssConfiguration::native_set_supl_version);
                    put(CONFIG_SUPL_MODE, GnssConfiguration::native_set_supl_mode);

                    if (isConfigSuplEsSupported(gnssConfigurationIfaceVersion)) {
                        put(CONFIG_SUPL_ES, GnssConfiguration::native_set_supl_es);
                    }

                    put(CONFIG_LPP_PROFILE, GnssConfiguration::native_set_lpp_profile);
                    put(CONFIG_A_GLONASS_POS_PROTOCOL_SELECT,
                            GnssConfiguration::native_set_gnss_pos_protocol_select);
                    put(CONFIG_USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL,
                            GnssConfiguration::native_set_emergency_supl_pdn);

                    if (isConfigGpsLockSupported(gnssConfigurationIfaceVersion)) {
                        put(CONFIG_GPS_LOCK, GnssConfiguration::native_set_gps_lock);
                    }
                }
            };

            for (Entry<String, SetCarrierProperty> entry : map.entrySet()) {
                String propertyName = entry.getKey();
                String propertyValueString = mProperties.getProperty(propertyName);
                if (propertyValueString != null) {
                    try {
                        int propertyValueInt = Integer.decode(propertyValueString);
                        boolean result = entry.getValue().set(propertyValueInt);
                        if (!result) {
                            Log.e(TAG, "Unable to set " + propertyName);
                        }
                    } catch (NumberFormatException e) {
                        Log.e(TAG, "Unable to parse propertyName: " + propertyValueString);
                    }
                }
            }
        } else if (DEBUG) {
            Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not"
                    + " supported");
        }
    }

    /**
     * Loads GNSS properties from carrier config file.
     */
    void loadPropertiesFromCarrierConfig() {
        CarrierConfigManager configManager = (CarrierConfigManager)
                mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
        if (configManager == null) {
            return;
        }
        PersistableBundle configs = configManager.getConfigForSubId(
                SubscriptionManager.getDefaultDataSubscriptionId());
        if (configs == null) {
            if (DEBUG) Log.d(TAG, "SIM not ready, use default carrier config.");
            configs = CarrierConfigManager.getDefaultConfig();
        }
        for (String configKey : configs.keySet()) {
            if (configKey.startsWith(CarrierConfigManager.Gps.KEY_PREFIX)) {
                String key = configKey
                        .substring(CarrierConfigManager.Gps.KEY_PREFIX.length())
                        .toUpperCase();
                Object value = configs.get(configKey);
                if (value instanceof String) {
                    // All GPS properties are of String type; convert so.
                    if (DEBUG) Log.d(TAG, "Gps config: " + key + " = " + value);
                    mProperties.setProperty(key, (String) value);
                }
            }
        }
    }

    private void loadPropertiesFromGpsDebugConfig(Properties properties) {
        try {
            File file = new File(DEBUG_PROPERTIES_FILE);
            FileInputStream stream = null;
            try {
                stream = new FileInputStream(file);
                properties.load(stream);
            } finally {
                IoUtils.closeQuietly(stream);
            }
        } catch (IOException e) {
            if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + DEBUG_PROPERTIES_FILE);
        }
    }

    private int getRangeCheckedConfigEsExtensionSec() {
        int emergencyExtensionSeconds = getIntConfig(CONFIG_ES_EXTENSION_SEC, 0);
        if (emergencyExtensionSeconds > MAX_EMERGENCY_MODE_EXTENSION_SECONDS) {
            Log.w(TAG, CONFIG_ES_EXTENSION_SEC + ": " + emergencyExtensionSeconds
                    + " too high, reset to " + MAX_EMERGENCY_MODE_EXTENSION_SECONDS);
            emergencyExtensionSeconds = MAX_EMERGENCY_MODE_EXTENSION_SECONDS;
        } else if (emergencyExtensionSeconds < 0) {
            Log.w(TAG, CONFIG_ES_EXTENSION_SEC + ": " + emergencyExtensionSeconds
                    + " is negative, reset to zero.");
            emergencyExtensionSeconds = 0;
        }
        return emergencyExtensionSeconds;
    }

    private int getIntConfig(String configParameter, int defaultValue) {
        String valueString = mProperties.getProperty(configParameter);
        if (TextUtils.isEmpty(valueString)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(valueString);
        } catch (NumberFormatException e) {
            Log.e(TAG, "Unable to parse config parameter " + configParameter + " value: "
                    + valueString + ". Using default value: " + defaultValue);
            return defaultValue;
        }
    }

    private static boolean isConfigEsExtensionSecSupported(
            HalInterfaceVersion gnssConfiguartionIfaceVersion) {
        // ES_EXTENSION_SEC is introduced in @2.0::IGnssConfiguration.hal
        return gnssConfiguartionIfaceVersion.mMajor >= 2;
    }

    private static boolean isConfigSuplEsSupported(
            HalInterfaceVersion gnssConfiguartionIfaceVersion) {
        // SUPL_ES is deprecated in @2.0::IGnssConfiguration.hal
        return gnssConfiguartionIfaceVersion.mMajor < 2;
    }

    private static boolean isConfigGpsLockSupported(
            HalInterfaceVersion gnssConfiguartionIfaceVersion) {
        // GPS_LOCK is deprecated in @2.0::IGnssConfiguration.hal
        return gnssConfiguartionIfaceVersion.mMajor < 2;
    }

    private static native HalInterfaceVersion native_get_gnss_configuration_version();

    private static native boolean native_set_supl_version(int version);

    private static native boolean native_set_supl_mode(int mode);

    private static native boolean native_set_supl_es(int es);

    private static native boolean native_set_lpp_profile(int lppProfile);

    private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect);

    private static native boolean native_set_gps_lock(int gpsLock);

    private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);

    private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds);

    private static native boolean native_set_es_extension_sec(int emergencyExtensionSeconds);
}
+29 −197

File changed.

Preview size limit exceeded, changes collapsed.

+131 −53

File changed.

Preview size limit exceeded, changes collapsed.