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

Commit 87d260a3 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Allow default SMS app to be always running

Bug: 109809543
Test: atest CtsAppBindingHostTestCases
Test: atest services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
Change-Id: Ic016f2c073d178db4aa36268628ebf3880acb3c3
parent 1d65ea4e
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -10810,6 +10810,12 @@ public final class Settings {
        public static final String ACTIVITY_STARTS_LOGGING_ENABLED
                = "activity_starts_logging_enabled";
        /**
         * @hide
         * @see com.android.server.appbinding.AppBindingConstants
         */
        public static final String APP_BINDING_CONSTANTS = "app_binding_constants";
        /**
         * App ops specific settings.
         * This is encoded as a key=value list, separated by commas. Ex:
+1 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ public class SettingsBackupTest {
                    Settings.Global.ANOMALY_CONFIG_VERSION,
                    Settings.Global.APN_DB_UPDATE_CONTENT_URL,
                    Settings.Global.APN_DB_UPDATE_METADATA_URL,
                    Settings.Global.APP_BINDING_CONSTANTS,
                    Settings.Global.APP_IDLE_CONSTANTS,
                    Settings.Global.APP_OPS_CONSTANTS,
                    Settings.Global.APP_STANDBY_ENABLED,
+48 −14
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;
import android.util.Log;
import android.util.TimeUtils;

import com.android.internal.annotations.GuardedBy;
@@ -100,6 +100,15 @@ public abstract class PersistentConnection<T> {
    @GuardedBy("mLock")
    private T mService;

    @GuardedBy("mLock")
    private int mNumConnected;

    @GuardedBy("mLock")
    private int mNumDisconnected;

    @GuardedBy("mLock")
    private int mNumBindingDied;

    private final ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
@@ -108,13 +117,15 @@ public abstract class PersistentConnection<T> {
                    // Callback came in after PersistentConnection.unbind() was called.
                    // We just ignore this.
                    // (We've already called unbindService() already in unbind)
                    Slog.w(mTag, "Connected: " + mComponentName.flattenToShortString()
                    Log.w(mTag, "Connected: " + mComponentName.flattenToShortString()
                            + " u" + mUserId + " but not bound, ignore.");
                    return;
                }
                Slog.i(mTag, "Connected: " + mComponentName.flattenToShortString()
                Log.i(mTag, "Connected: " + mComponentName.flattenToShortString()
                        + " u" + mUserId);

                mNumConnected++;

                mIsConnected = true;
                mService = asInterface(service);
            }
@@ -123,9 +134,11 @@ public abstract class PersistentConnection<T> {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            synchronized (mLock) {
                Slog.i(mTag, "Disconnected: " + mComponentName.flattenToShortString()
                Log.i(mTag, "Disconnected: " + mComponentName.flattenToShortString()
                        + " u" + mUserId);

                mNumDisconnected++;

                cleanUpConnectionLocked();
            }
        }
@@ -136,13 +149,16 @@ public abstract class PersistentConnection<T> {
            synchronized (mLock) {
                if (!mBound) {
                    // Callback came in late?
                    Slog.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
                    Log.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
                            + " u" + mUserId + " but not bound, ignore.");
                    return;
                }

                Slog.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
                Log.w(mTag, "Binding died: " + mComponentName.flattenToShortString()
                        + " u" + mUserId);

                mNumBindingDied++;

                scheduleRebindLocked();
            }
        }
@@ -170,6 +186,12 @@ public abstract class PersistentConnection<T> {
        return mComponentName;
    }

    public final int getUserId() {
        return mUserId;
    }

    protected abstract int getBindFlags();

    /**
     * @return whether {@link #bind()} has been called and {@link #unbind()} hasn't.
     *
@@ -237,15 +259,15 @@ public abstract class PersistentConnection<T> {
        final Intent service = new Intent().setComponent(mComponentName);

        if (DEBUG) {
            Slog.d(mTag, "Attempting to connect to " + mComponentName);
            Log.d(mTag, "Attempting to connect to " + mComponentName);
        }

        final boolean success = mContext.bindServiceAsUser(service, mServiceConnection,
                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
                Context.BIND_AUTO_CREATE | getBindFlags(),
                mHandler, UserHandle.of(mUserId));

        if (!success) {
            Slog.e(mTag, "Binding: " + service.getComponent() + " u" + mUserId
            Log.e(mTag, "Binding: " + service.getComponent() + " u" + mUserId
                    + " failed.");
        }
    }
@@ -285,7 +307,7 @@ public abstract class PersistentConnection<T> {
        if (!mBound) {
            return;
        }
        Slog.i(mTag, "Stopping: " + mComponentName.flattenToShortString() + " u" + mUserId);
        Log.i(mTag, "Stopping: " + mComponentName.flattenToShortString() + " u" + mUserId);
        mBound = false;
        mContext.unbindService(mServiceConnection);

@@ -303,7 +325,7 @@ public abstract class PersistentConnection<T> {
        unbindLocked();

        if (!mRebindScheduled) {
            Slog.i(mTag, "Scheduling to reconnect in " + mNextBackoffMs + " ms (uptime)");
            Log.i(mTag, "Scheduling to reconnect in " + mNextBackoffMs + " ms (uptime)");

            mReconnectTime = injectUptimeMillis() + mNextBackoffMs;

@@ -323,6 +345,8 @@ public abstract class PersistentConnection<T> {
        synchronized (mLock) {
            pw.print(prefix);
            pw.print(mComponentName.flattenToShortString());
            pw.print(" u");
            pw.print(mUserId);
            pw.print(mBound ? " [bound]" : " [not bound]");
            pw.print(mIsConnected ? " [connected]" : " [not connected]");
            if (mRebindScheduled) {
@@ -334,6 +358,16 @@ public abstract class PersistentConnection<T> {
            pw.print(prefix);
            pw.print("  Next backoff(sec): ");
            pw.print(mNextBackoffMs / 1000);
            pw.println();

            pw.print(prefix);
            pw.print("  Connected: ");
            pw.print(mNumConnected);
            pw.print("  Disconnected: ");
            pw.print(mNumDisconnected);
            pw.print("  Died: ");
            pw.print(mNumBindingDied);
            pw.println();
        }
    }

+120 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.appbinding;

import android.util.KeyValueListParser;
import android.util.Slog;

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

/**
 * Constants that are configurable via the global settings for {@link AppBindingService}.
 */
class AppBindingConstants {
    private static final String TAG = AppBindingService.TAG;

    private static final String SERVICE_RECONNECT_BACKOFF_SEC_KEY =
            "service_reconnect_backoff_sec";

    private static final String SERVICE_RECONNECT_BACKOFF_INCREASE_KEY =
            "service_reconnect_backoff_increase";

    private static final String SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY =
            "service_reconnect_max_backoff_sec";

    public final String sourceSettings;

    /**
     * The back-off before re-connecting, when a service binding died, due to the app
     * crashing repeatedly.
     */
    public final long SERVICE_RECONNECT_BACKOFF_SEC;

    /**
     * The exponential back-off increase factor when a binding dies multiple times.
     */
    public final double SERVICE_RECONNECT_BACKOFF_INCREASE;

    /**
     * The max back-off
     */
    public final long SERVICE_RECONNECT_MAX_BACKOFF_SEC;

    private AppBindingConstants(String settings) {
        sourceSettings = settings;

        final KeyValueListParser parser = new KeyValueListParser(',');
        try {
            parser.setString(settings);
        } catch (IllegalArgumentException e) {
            // Failed to parse the settings string, log this and move on
            // with defaults.
            Slog.e(TAG, "Bad setting: " + settings);
        }

        long serviceReconnectBackoffSec = parser.getLong(
                SERVICE_RECONNECT_BACKOFF_SEC_KEY, TimeUnit.HOURS.toSeconds(1));

        double serviceReconnectBackoffIncrease = parser.getFloat(
                SERVICE_RECONNECT_BACKOFF_INCREASE_KEY, 2f);

        long serviceReconnectMaxBackoffSec = parser.getLong(
                SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY, TimeUnit.DAYS.toSeconds(1));

        // Set minimum: 5 seconds.
        serviceReconnectBackoffSec = Math.max(5, serviceReconnectBackoffSec);

        // Set minimum: 1.0.
        serviceReconnectBackoffIncrease =
                Math.max(1, serviceReconnectBackoffIncrease);

        // Make sure max >= default back off.
        serviceReconnectMaxBackoffSec = Math.max(serviceReconnectBackoffSec,
                serviceReconnectMaxBackoffSec);

        SERVICE_RECONNECT_BACKOFF_SEC = serviceReconnectBackoffSec;
        SERVICE_RECONNECT_BACKOFF_INCREASE = serviceReconnectBackoffIncrease;
        SERVICE_RECONNECT_MAX_BACKOFF_SEC = serviceReconnectMaxBackoffSec;
    }

    /**
     * Create a new instance from a settings string.
     */
    public static AppBindingConstants initializeFromString(String settings) {
        return new AppBindingConstants(settings);
    }

    /**
     * dumpsys support.
     */
    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix);
        pw.println("Constants:");

        pw.print(prefix);
        pw.print("  SERVICE_RECONNECT_BACKOFF_SEC: ");
        pw.println(SERVICE_RECONNECT_BACKOFF_SEC);

        pw.print(prefix);
        pw.print("  SERVICE_RECONNECT_BACKOFF_INCREASE: ");
        pw.println(SERVICE_RECONNECT_BACKOFF_INCREASE);

        pw.print(prefix);
        pw.print("  SERVICE_RECONNECT_MAX_BACKOFF_SEC: ");
        pw.println(SERVICE_RECONNECT_MAX_BACKOFF_SEC);
    }
}
+464 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading