/* //device/content/providers/telephony/TelephonyProvider.java
**
** Copyright 2016, 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.providers.telephony;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MatrixCursor.RowBuilder;
import android.net.Uri;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.SubscriptionController;

import java.lang.NumberFormatException;
import java.util.HashMap;

import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionId;
import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionIdAndField;

import static android.provider.Telephony.ServiceStateTable;
import static android.provider.Telephony.ServiceStateTable.CONTENT_URI;

import static android.provider.Telephony.ServiceStateTable.VOICE_REG_STATE;
import static android.provider.Telephony.ServiceStateTable.DATA_REG_STATE;
import static android.provider.Telephony.ServiceStateTable.VOICE_ROAMING_TYPE;
import static android.provider.Telephony.ServiceStateTable.DATA_ROAMING_TYPE;
import static android.provider.Telephony.ServiceStateTable.VOICE_OPERATOR_ALPHA_LONG;
import static android.provider.Telephony.ServiceStateTable.VOICE_OPERATOR_ALPHA_SHORT;
import static android.provider.Telephony.ServiceStateTable.VOICE_OPERATOR_NUMERIC;
import static android.provider.Telephony.ServiceStateTable.DATA_OPERATOR_ALPHA_LONG;
import static android.provider.Telephony.ServiceStateTable.DATA_OPERATOR_ALPHA_SHORT;
import static android.provider.Telephony.ServiceStateTable.DATA_OPERATOR_NUMERIC;
import static android.provider.Telephony.ServiceStateTable.IS_MANUAL_NETWORK_SELECTION;
import static android.provider.Telephony.ServiceStateTable.RIL_VOICE_RADIO_TECHNOLOGY;
import static android.provider.Telephony.ServiceStateTable.RIL_DATA_RADIO_TECHNOLOGY;
import static android.provider.Telephony.ServiceStateTable.CSS_INDICATOR;
import static android.provider.Telephony.ServiceStateTable.NETWORK_ID;
import static android.provider.Telephony.ServiceStateTable.SYSTEM_ID;
import static android.provider.Telephony.ServiceStateTable.CDMA_ROAMING_INDICATOR;
import static android.provider.Telephony.ServiceStateTable.CDMA_DEFAULT_ROAMING_INDICATOR;
import static android.provider.Telephony.ServiceStateTable.CDMA_ERI_ICON_INDEX;
import static android.provider.Telephony.ServiceStateTable.CDMA_ERI_ICON_MODE;
import static android.provider.Telephony.ServiceStateTable.IS_EMERGENCY_ONLY;
import static android.provider.Telephony.ServiceStateTable.IS_DATA_ROAMING_FROM_REGISTRATION;
import static android.provider.Telephony.ServiceStateTable.IS_USING_CARRIER_AGGREGATION;


public class ServiceStateProvider extends ContentProvider {
    private static final String TAG = "ServiceStateProvider";

    public static final String AUTHORITY = ServiceStateTable.AUTHORITY;
    public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);

    private final HashMap<Integer, ServiceState> mServiceStates = new HashMap<>();
    private static final String[] sColumns = {
        VOICE_REG_STATE,
        DATA_REG_STATE,
        VOICE_ROAMING_TYPE,
        DATA_ROAMING_TYPE,
        VOICE_OPERATOR_ALPHA_LONG,
        VOICE_OPERATOR_ALPHA_SHORT,
        VOICE_OPERATOR_NUMERIC,
        DATA_OPERATOR_ALPHA_LONG,
        DATA_OPERATOR_ALPHA_SHORT,
        DATA_OPERATOR_NUMERIC,
        IS_MANUAL_NETWORK_SELECTION,
        RIL_VOICE_RADIO_TECHNOLOGY,
        RIL_DATA_RADIO_TECHNOLOGY,
        CSS_INDICATOR,
        NETWORK_ID,
        SYSTEM_ID,
        CDMA_ROAMING_INDICATOR,
        CDMA_DEFAULT_ROAMING_INDICATOR,
        CDMA_ERI_ICON_INDEX,
        CDMA_ERI_ICON_MODE,
        IS_EMERGENCY_ONLY,
        IS_DATA_ROAMING_FROM_REGISTRATION,
        IS_USING_CARRIER_AGGREGATION,
    };

    @Override
    public boolean onCreate() {
        return true;
    }

    @VisibleForTesting
    public ServiceState getServiceState(int subId) {
        return mServiceStates.get(subId);
    }

    @VisibleForTesting
    public int getDefaultSubId() {
        return SubscriptionController.getInstance().getDefaultSubId();
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (uri.isPathPrefixMatch(CONTENT_URI)) {
            // Parse the subId
            int subId = 0;
            try {
                subId = Integer.parseInt(uri.getLastPathSegment());
            } catch (NumberFormatException e) {
                Log.e(TAG, "insert: no subId provided in uri");
                throw e;
            }
            Log.d(TAG, "subId=" + subId);

            // handle DEFAULT_SUBSCRIPTION_ID
            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
                subId = getDefaultSubId();
            }

            // create the new service state
            ServiceState newSS = new ServiceState();
            newSS.setVoiceRegState(values.getAsInteger(VOICE_REG_STATE));
            newSS.setDataRegState(values.getAsInteger(DATA_REG_STATE));
            newSS.setVoiceOperatorName(values.getAsString(VOICE_OPERATOR_ALPHA_LONG),
                        values.getAsString(VOICE_OPERATOR_ALPHA_SHORT),
                        values.getAsString(VOICE_OPERATOR_NUMERIC));
            newSS.setDataOperatorName(values.getAsString(DATA_OPERATOR_ALPHA_LONG),
                    values.getAsString(DATA_OPERATOR_ALPHA_SHORT),
                    values.getAsString(DATA_OPERATOR_NUMERIC));
            newSS.setIsManualSelection(values.getAsBoolean(IS_MANUAL_NETWORK_SELECTION));
            newSS.setRilVoiceRadioTechnology(values.getAsInteger(RIL_VOICE_RADIO_TECHNOLOGY));
            newSS.setRilDataRadioTechnology(values.getAsInteger(RIL_DATA_RADIO_TECHNOLOGY));
            newSS.setCssIndicator(values.getAsInteger(CSS_INDICATOR));
            newSS.setCdmaSystemAndNetworkId(values.getAsInteger(SYSTEM_ID),
                    values.getAsInteger(NETWORK_ID));
            newSS.setCdmaRoamingIndicator(values.getAsInteger(CDMA_ROAMING_INDICATOR));
            newSS.setCdmaDefaultRoamingIndicator(
                    values.getAsInteger(CDMA_DEFAULT_ROAMING_INDICATOR));
            newSS.setCdmaEriIconIndex(values.getAsInteger(CDMA_ERI_ICON_INDEX));
            newSS.setCdmaEriIconMode(values.getAsInteger(CDMA_ERI_ICON_MODE));
            newSS.setEmergencyOnly(values.getAsBoolean(IS_EMERGENCY_ONLY));
            newSS.setDataRoamingFromRegistration(
                    values.getAsBoolean(IS_DATA_ROAMING_FROM_REGISTRATION));
            newSS.setIsUsingCarrierAggregation(values.getAsBoolean(IS_USING_CARRIER_AGGREGATION));

            // notify listeners
            // if ss is null (e.g. first service state update) we will notify for all fields
            ServiceState ss = getServiceState(subId);
            notifyChangeForSubIdAndField(getContext(), ss, newSS, subId);
            notifyChangeForSubId(getContext(), ss, newSS, subId);

            // store the new service state
            mServiceStates.put(subId, newSS);
            return uri;
        }
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        throw new RuntimeException("Not supported");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        throw new RuntimeException("Not supported");
    }

    @Override
    public String getType(Uri uri) {
        throw new RuntimeException("Not supported");
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        if (!uri.isPathPrefixMatch(CONTENT_URI)) {
            throw new IllegalArgumentException("Invalid URI: " + uri);
        } else {
            // Parse the subId
            int subId = 0;
            try {
                subId = Integer.parseInt(uri.getLastPathSegment());
            } catch (NumberFormatException e) {
                Log.d(TAG, "query: no subId provided in uri, using default.");
                subId = getDefaultSubId();
            }
            Log.d(TAG, "subId=" + subId);

            // handle DEFAULT_SUBSCRIPTION_ID
            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
                subId = getDefaultSubId();
            }

            // Get the service state
            ServiceState ss = getServiceState(subId);
            if (ss == null) {
                Log.d(TAG, "returning null");
                return null;
            }

            // Build the result
            final int voice_reg_state = ss.getVoiceRegState();
            final int data_reg_state = ss.getDataRegState();
            final int voice_roaming_type = ss.getVoiceRoamingType();
            final int data_roaming_type = ss.getDataRoamingType();
            final String voice_operator_alpha_long = ss.getVoiceOperatorAlphaLong();
            final String voice_operator_alpha_short = ss.getVoiceOperatorAlphaShort();
            final String voice_operator_numeric = ss.getVoiceOperatorNumeric();
            final String data_operator_alpha_long = ss.getDataOperatorAlphaLong();
            final String data_operator_alpha_short = ss.getDataOperatorAlphaShort();
            final String data_operator_numeric = ss.getDataOperatorNumeric();
            final int is_manual_network_selection = (ss.getIsManualSelection()) ? 1 : 0;
            final int ril_voice_radio_technology = ss.getRilVoiceRadioTechnology();
            final int ril_data_radio_technology = ss.getRilDataRadioTechnology();
            final int css_indicator = ss.getCssIndicator();
            final int network_id = ss.getCdmaNetworkId();
            final int system_id = ss.getCdmaSystemId();
            final int cdma_roaming_indicator = ss.getCdmaRoamingIndicator();
            final int cdma_default_roaming_indicator = ss.getCdmaDefaultRoamingIndicator();
            final int cdma_eri_icon_index = ss.getCdmaEriIconIndex();
            final int cdma_eri_icon_mode = ss.getCdmaEriIconMode();
            final int is_emergency_only = (ss.isEmergencyOnly()) ? 1 : 0;
            final int is_data_roaming_from_registration =
                    (ss.getDataRoamingFromRegistration()) ? 1 : 0;
            final int is_using_carrier_aggregation = (ss.isUsingCarrierAggregation()) ? 1 : 0;

            return buildSingleRowResult(projection, sColumns, new Object[] {
                        voice_reg_state,
                        data_reg_state,
                        voice_roaming_type,
                        data_roaming_type,
                        voice_operator_alpha_long,
                        voice_operator_alpha_short,
                        voice_operator_numeric,
                        data_operator_alpha_long,
                        data_operator_alpha_short,
                        data_operator_numeric,
                        is_manual_network_selection,
                        ril_voice_radio_technology,
                        ril_data_radio_technology,
                        css_indicator,
                        network_id,
                        system_id,
                        cdma_roaming_indicator,
                        cdma_default_roaming_indicator,
                        cdma_eri_icon_index,
                        cdma_eri_icon_mode,
                        is_emergency_only,
                        is_data_roaming_from_registration,
                        is_using_carrier_aggregation,
            });
        }
    }

    private static Cursor buildSingleRowResult(String[] projection, String[] availableColumns,
            Object[] data) {
        if (projection == null) {
            projection = availableColumns;
        }
        final MatrixCursor c = new MatrixCursor(projection, 1);
        final RowBuilder row = c.newRow();
        for (int i = 0; i < c.getColumnCount(); i++) {
            final String columnName = c.getColumnName(i);
            boolean found = false;
            for (int j = 0; j < availableColumns.length; j++) {
                if (availableColumns[j].equals(columnName)) {
                    row.add(data[j]);
                    found = true;
                    break;
                }
            }
            if (!found) {
                throw new IllegalArgumentException("Invalid column " + projection[i]);
            }
        }
        return c;
    }

    /**
     * Notify interested apps that certain fields of the ServiceState have changed.
     *
     * Apps which want to wake when specific fields change can use
     * JobScheduler's TriggerContentUri.  This replaces the waking functionality of the implicit
     * broadcast of ACTION_SERVICE_STATE_CHANGED for apps targetting version O.
     *
     * We will only notify for certain fields. This is an intentional change from the behavior of
     * the broadcast. Listeners will be notified when the voice or data registration state or
     * roaming type changes.
     */
    @VisibleForTesting
    public static void notifyChangeForSubIdAndField(Context context, ServiceState oldSS,
            ServiceState newSS, int subId) {
        final boolean firstUpdate = (oldSS == null) ? true : false;

        // for every field, if the field has changed values, notify via the provider
        if (firstUpdate || voiceRegStateChanged(oldSS, newSS)) {
            context.getContentResolver().notifyChange(
                    getUriForSubscriptionIdAndField(subId, VOICE_REG_STATE),
                    /* observer= */ null, /* syncToNetwork= */ false);
        }
        if (firstUpdate || dataRegStateChanged(oldSS, newSS)) {
            context.getContentResolver().notifyChange(
                    getUriForSubscriptionIdAndField(subId, DATA_REG_STATE), null, false);
        }
        if (firstUpdate || voiceRoamingTypeChanged(oldSS, newSS)) {
            context.getContentResolver().notifyChange(
                    getUriForSubscriptionIdAndField(subId, VOICE_ROAMING_TYPE), null, false);
        }
        if (firstUpdate || dataRoamingTypeChanged(oldSS, newSS)) {
            context.getContentResolver().notifyChange(
                    getUriForSubscriptionIdAndField(subId, DATA_ROAMING_TYPE), null, false);
        }
    }

    private static boolean voiceRegStateChanged(ServiceState oldSS, ServiceState newSS) {
        return oldSS.getVoiceRegState() != newSS.getVoiceRegState();
    }

    private static boolean dataRegStateChanged(ServiceState oldSS, ServiceState newSS) {
        return oldSS.getDataRegState() != newSS.getDataRegState();
    }

    private static boolean voiceRoamingTypeChanged(ServiceState oldSS, ServiceState newSS) {
        return oldSS.getVoiceRoamingType() != newSS.getVoiceRoamingType();
    }

    private static boolean dataRoamingTypeChanged(ServiceState oldSS, ServiceState newSS) {
        return oldSS.getDataRoamingType() != newSS.getDataRoamingType();
    }

    /**
     * Notify interested apps that the ServiceState has changed.
     *
     * Apps which want to wake when any field in the ServiceState has changed can use
     * JobScheduler's TriggerContentUri.  This replaces the waking functionality of the implicit
     * broadcast of ACTION_SERVICE_STATE_CHANGED for apps targetting version O.
     *
     * We will only notify for certain fields. This is an intentional change from the behavior of
     * the broadcast. Listeners will be notified when the voice or data registration state or
     * roaming type changes.
     */
    @VisibleForTesting
    public static void notifyChangeForSubId(Context context, ServiceState oldSS, ServiceState newSS,
            int subId) {
        // if the voice or data registration or roaming state field has changed values, notify via
        // the provider.
        // If oldSS is null and newSS is not (e.g. first update of service state) this will also
        // notify
        if (oldSS == null || voiceRegStateChanged(oldSS, newSS) || dataRegStateChanged(oldSS, newSS)
                || voiceRoamingTypeChanged(oldSS, newSS) || dataRoamingTypeChanged(oldSS, newSS)) {
            context.getContentResolver().notifyChange(getUriForSubscriptionId(subId), null, false);
        }
    }
}
