/*
 * 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 android.net;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.util.SharedLog;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.io.File;
import java.io.PrintWriter;

/**
 * Class used to communicate to the various networking mainline modules running in the network stack
 * process from {@link com.android.server.SystemServer}.
 * @hide
 */
public class ConnectivityModuleConnector {
    private static final String TAG = ConnectivityModuleConnector.class.getSimpleName();
    private static final String IN_PROCESS_SUFFIX = ".InProcess";

    private static final String PREFS_FILE = "ConnectivityModuleConnector.xml";
    private static final String PREF_KEY_LAST_CRASH_TIME = "lastcrash_time";
    private static final String CONFIG_MIN_CRASH_INTERVAL_MS = "min_crash_interval";
    private static final String CONFIG_MIN_UPTIME_BEFORE_CRASH_MS = "min_uptime_before_crash";
    private static final String CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH =
            "always_ratelimit_networkstack_crash";

    // Even if the network stack is lost, do not crash the system more often than this.
    // Connectivity would be broken, but if the user needs the device for something urgent
    // (like calling emergency services) we should not bootloop the device.
    // This is the default value: the actual value can be adjusted via device config.
    private static final long DEFAULT_MIN_CRASH_INTERVAL_MS = 6 * DateUtils.HOUR_IN_MILLIS;

    // Even if the network stack is lost, do not crash the system server if it was less than
    // this much after boot. This avoids bootlooping the device, and crashes should address very
    // infrequent failures, not failures on boot.
    private static final long DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS = 30 * DateUtils.MINUTE_IN_MILLIS;

    private static ConnectivityModuleConnector sInstance;

    private Context mContext;
    @GuardedBy("mLog")
    private final SharedLog mLog = new SharedLog(TAG);
    @GuardedBy("mHealthListeners")
    private final ArraySet<ConnectivityModuleHealthListener> mHealthListeners = new ArraySet<>();
    @NonNull
    private final Dependencies mDeps;

    private ConnectivityModuleConnector() {
        this(new DependenciesImpl());
    }

    @VisibleForTesting
    ConnectivityModuleConnector(@NonNull Dependencies deps) {
        mDeps = deps;
    }

    /**
     * Get the {@link ConnectivityModuleConnector} singleton instance.
     */
    public static synchronized ConnectivityModuleConnector getInstance() {
        if (sInstance == null) {
            sInstance = new ConnectivityModuleConnector();
        }
        return sInstance;
    }

    /**
     * Initialize the network stack connector. Should be called only once on device startup, before
     * any client attempts to use the network stack.
     */
    public void init(Context context) {
        log("Network stack init");
        mContext = context;
    }

    /**
     * Callback interface for severe failures of the NetworkStack.
     *
     * <p>Useful for health monitors such as PackageWatchdog.
     */
    public interface ConnectivityModuleHealthListener {
        /**
         * Called when there is a severe failure of the network stack.
         * @param packageName Package name of the network stack.
         */
        void onNetworkStackFailure(@NonNull String packageName);
    }

    /**
     * Callback invoked by the connector once the connection to the corresponding module is
     * established.
     */
    public interface ModuleServiceCallback {
        /**
         * Invoked when the corresponding service has connected.
         *
         * @param iBinder Binder object for the service.
         */
        void onModuleServiceConnected(@NonNull IBinder iBinder);
    }

    /**
     * Interface used to determine the intent to use to bind to the module. Useful for testing.
     */
    @VisibleForTesting
    protected interface Dependencies {
        /**
         * Determine the intent to use to bind to the module.
         * @return null if the intent could not be resolved, the intent otherwise.
         */
        @Nullable
        Intent getModuleServiceIntent(
                @NonNull PackageManager pm, @NonNull String serviceIntentBaseAction,
                @NonNull String servicePermissionName, boolean inSystemProcess);
    }

    private static class DependenciesImpl implements Dependencies {
        @Nullable
        @Override
        public Intent getModuleServiceIntent(
                @NonNull PackageManager pm, @NonNull String serviceIntentBaseAction,
                @NonNull String servicePermissionName, boolean inSystemProcess) {
            final Intent intent =
                    new Intent(inSystemProcess
                            ? serviceIntentBaseAction + IN_PROCESS_SUFFIX
                            : serviceIntentBaseAction);
            final ComponentName comp = intent.resolveSystemService(pm, 0);
            if (comp == null) {
                return null;
            }
            intent.setComponent(comp);

            final int uid;
            try {
                uid = pm.getPackageUidAsUser(comp.getPackageName(), UserHandle.USER_SYSTEM);
            } catch (PackageManager.NameNotFoundException e) {
                throw new SecurityException(
                        "Could not check network stack UID; package not found.", e);
            }

            final int expectedUid =
                    inSystemProcess ? Process.SYSTEM_UID : Process.NETWORK_STACK_UID;
            if (uid != expectedUid) {
                throw new SecurityException("Invalid network stack UID: " + uid);
            }

            if (!inSystemProcess) {
                checkModuleServicePermission(pm, comp, servicePermissionName);
            }

            return intent;
        }
    }


    /**
     * Add a {@link ConnectivityModuleHealthListener} to listen to network stack health events.
     */
    public void registerHealthListener(@NonNull ConnectivityModuleHealthListener listener) {
        synchronized (mHealthListeners) {
            mHealthListeners.add(listener);
        }
    }

    /**
     * Start a module running in the network stack or system_server process. Should be called only
     * once for each module per device startup.
     *
     * <p>This method will start a networking module either in the network stack
     * process, or inside the system server on devices that do not support the corresponding
     * mainline network . The corresponding networking module service's binder
     * object will then be delivered asynchronously via the provided {@link ModuleServiceCallback}.
     *
     * @param serviceIntentBaseAction Base action to use for constructing the intent needed to
     *                                bind to the corresponding module.
     * @param servicePermissionName Permission to be held by the corresponding module.
     */
    public void startModuleService(
            @NonNull String serviceIntentBaseAction,
            @NonNull String servicePermissionName,
            @NonNull ModuleServiceCallback callback) {
        log("Starting networking module " + serviceIntentBaseAction);

        final PackageManager pm = mContext.getPackageManager();

        // Try to bind in-process if the device was shipped with an in-process version
        Intent intent = mDeps.getModuleServiceIntent(pm, serviceIntentBaseAction,
                servicePermissionName, true /* inSystemProcess */);

        // Otherwise use the updatable module version
        if (intent == null) {
            intent = mDeps.getModuleServiceIntent(pm, serviceIntentBaseAction,
                    servicePermissionName, false /* inSystemProcess */);
            log("Starting networking module in network_stack process");
        } else {
            log("Starting networking module in system_server process");
        }

        if (intent == null) {
            maybeCrashWithTerribleFailure("Could not resolve the networking module", null);
            return;
        }

        final String packageName = intent.getComponent().getPackageName();

        // Start the network stack. The service will be added to the service manager by the
        // corresponding client in ModuleServiceCallback.onModuleServiceConnected().
        if (!mContext.bindServiceAsUser(
                intent, new ModuleServiceConnection(packageName, callback),
                Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) {
            maybeCrashWithTerribleFailure(
                    "Could not bind to networking module in-process, or in app with "
                            + intent, packageName);
            return;
        }

        log("Networking module service start requested");
    }

    private class ModuleServiceConnection implements ServiceConnection {
        @NonNull
        private final String mPackageName;
        @NonNull
        private final ModuleServiceCallback mModuleServiceCallback;

        private ModuleServiceConnection(
                @NonNull String packageName,
                @NonNull ModuleServiceCallback moduleCallback) {
            mPackageName = packageName;
            mModuleServiceCallback = moduleCallback;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            logi("Networking module service connected");
            mModuleServiceCallback.onModuleServiceConnected(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // onServiceDisconnected is not being called on device shutdown, so this method being
            // called always indicates a bad state for the system server.
            // This code path is only run by the system server: only the system server binds
            // to the NetworkStack as a service. Other processes get the NetworkStack from
            // the ServiceManager.
            maybeCrashWithTerribleFailure("Lost network stack", mPackageName);
        }
    }

    private static void checkModuleServicePermission(
            @NonNull PackageManager pm, @NonNull ComponentName comp,
            @NonNull String servicePermissionName) {
        final int hasPermission =
                pm.checkPermission(servicePermissionName, comp.getPackageName());
        if (hasPermission != PERMISSION_GRANTED) {
            throw new SecurityException(
                    "Networking module does not have permission " + servicePermissionName);
        }
    }

    private synchronized void maybeCrashWithTerribleFailure(@NonNull String message,
            @Nullable String packageName) {
        logWtf(message, null);
        // uptime is monotonic even after a framework restart
        final long uptime = SystemClock.elapsedRealtime();
        final long now = System.currentTimeMillis();
        final long minCrashIntervalMs = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY,
                CONFIG_MIN_CRASH_INTERVAL_MS, DEFAULT_MIN_CRASH_INTERVAL_MS);
        final long minUptimeBeforeCrash = DeviceConfig.getLong(DeviceConfig.NAMESPACE_CONNECTIVITY,
                CONFIG_MIN_UPTIME_BEFORE_CRASH_MS, DEFAULT_MIN_UPTIME_BEFORE_CRASH_MS);
        final boolean alwaysRatelimit = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_CONNECTIVITY,
                CONFIG_ALWAYS_RATELIMIT_NETWORKSTACK_CRASH, false);

        final SharedPreferences prefs = getSharedPreferences();
        final long lastCrashTime = tryGetLastCrashTime(prefs);

        // Only crash if there was enough time since boot, and (if known) enough time passed since
        // the last crash.
        // time and lastCrashTime may be unreliable if devices have incorrect clock time, but they
        // are only used to limit the number of crashes compared to only using the time since boot,
        // which would also be OK behavior by itself.
        // - If lastCrashTime is incorrectly more than the current time, only look at uptime
        // - If it is much less than current time, only look at uptime
        // - If current time is during the next few hours after last crash time, don't crash.
        //   Considering that this only matters if last boot was some time ago, it's likely that
        //   time will be set correctly. Otherwise, not crashing is not a big problem anyway. Being
        //   in this last state would also not last for long since the window is only a few hours.
        final boolean alwaysCrash = Build.IS_DEBUGGABLE && !alwaysRatelimit;
        final boolean justBooted = uptime < minUptimeBeforeCrash;
        final boolean haveLastCrashTime = (lastCrashTime != 0) && (lastCrashTime < now);
        final boolean haveKnownRecentCrash =
                haveLastCrashTime && (now < lastCrashTime + minCrashIntervalMs);
        if (alwaysCrash || (!justBooted && !haveKnownRecentCrash)) {
            // The system is not bound to its network stack (for example due to a crash in the
            // network stack process): better crash rather than stay in a bad state where all
            // networking is broken.
            // Using device-encrypted SharedPreferences as DeviceConfig does not have a synchronous
            // API to persist settings before a crash.
            tryWriteLastCrashTime(prefs, now);
            throw new IllegalStateException(message);
        }

        // Here the system crashed recently already. Inform listeners that something is
        // definitely wrong.
        if (packageName != null) {
            final ArraySet<ConnectivityModuleHealthListener> listeners;
            synchronized (mHealthListeners) {
                listeners = new ArraySet<>(mHealthListeners);
            }
            for (ConnectivityModuleHealthListener listener : listeners) {
                listener.onNetworkStackFailure(packageName);
            }
        }
    }

    @Nullable
    private SharedPreferences getSharedPreferences() {
        try {
            final File prefsFile = new File(
                    Environment.getDataSystemDeDirectory(UserHandle.USER_SYSTEM), PREFS_FILE);
            return mContext.createDeviceProtectedStorageContext()
                    .getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
        } catch (Throwable e) {
            logWtf("Error loading shared preferences", e);
            return null;
        }
    }

    private long tryGetLastCrashTime(@Nullable SharedPreferences prefs) {
        if (prefs == null) return 0L;
        try {
            return prefs.getLong(PREF_KEY_LAST_CRASH_TIME, 0L);
        } catch (Throwable e) {
            logWtf("Error getting last crash time", e);
            return 0L;
        }
    }

    private void tryWriteLastCrashTime(@Nullable SharedPreferences prefs, long value) {
        if (prefs == null) return;
        try {
            prefs.edit().putLong(PREF_KEY_LAST_CRASH_TIME, value).commit();
        } catch (Throwable e) {
            logWtf("Error writing last crash time", e);
        }
    }

    private void log(@NonNull String message) {
        Slog.d(TAG, message);
        synchronized (mLog) {
            mLog.log(message);
        }
    }

    private void logWtf(@NonNull String message, @Nullable Throwable e) {
        Slog.wtf(TAG, message, e);
        synchronized (mLog) {
            mLog.e(message);
        }
    }

    private void loge(@NonNull String message, @Nullable Throwable e) {
        Slog.e(TAG, message, e);
        synchronized (mLog) {
            mLog.e(message);
        }
    }

    private void logi(@NonNull String message) {
        Slog.i(TAG, message);
        synchronized (mLog) {
            mLog.i(message);
        }
    }

    /**
     * Dump ConnectivityModuleConnector logs to the specified {@link PrintWriter}.
     */
    public void dump(PrintWriter pw) {
        // dump is thread-safe on SharedLog
        mLog.dump(null, pw, null);
    }
}
