// Signature format: 3.0
package androidx.room {

  public class DatabaseConfiguration {
    method public boolean isMigrationRequired(int, int);
    method @Deprecated public boolean isMigrationRequiredFrom(int);
    field public final boolean allowDestructiveMigrationOnDowngrade;
    field public final boolean allowMainThreadQueries;
    field public final java.util.List<androidx.room.RoomDatabase.Callback!>? callbacks;
    field public final android.content.Context context;
    field public final String? copyFromAssetPath;
    field public final java.io.File? copyFromFile;
    field public final java.util.concurrent.Callable<java.io.InputStream!>? copyFromInputStream;
    field public final androidx.room.RoomDatabase.JournalMode! journalMode;
    field public final androidx.room.RoomDatabase.MigrationContainer migrationContainer;
    field public final boolean multiInstanceInvalidation;
    field public final String? name;
    field public final androidx.room.RoomDatabase.PrepackagedDatabaseCallback? prepackagedDatabaseCallback;
    field public final java.util.concurrent.Executor queryExecutor;
    field public final boolean requireMigration;
    field public final androidx.sqlite.db.SupportSQLiteOpenHelper.Factory sqliteOpenHelperFactory;
    field public final java.util.concurrent.Executor transactionExecutor;
  }

  public class InvalidationTracker {
    method @WorkerThread public void addObserver(androidx.room.InvalidationTracker.Observer);
    method public void refreshVersionsAsync();
    method @WorkerThread public void removeObserver(androidx.room.InvalidationTracker.Observer);
  }

  public abstract static class InvalidationTracker.Observer {
    ctor protected InvalidationTracker.Observer(String, java.lang.String!...);
    ctor public InvalidationTracker.Observer(String![]);
    method public abstract void onInvalidated(java.util.Set<java.lang.String!>);
  }

  public class Room {
    ctor @Deprecated public Room();
    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> databaseBuilder(android.content.Context, Class<T!>, String);
    method public static <T extends androidx.room.RoomDatabase> androidx.room.RoomDatabase.Builder<T!> inMemoryDatabaseBuilder(android.content.Context, Class<T!>);
    field public static final String MASTER_TABLE_NAME = "room_master_table";
  }

  public abstract class RoomDatabase {
    ctor public RoomDatabase();
    method @Deprecated public void beginTransaction();
    method @WorkerThread public abstract void clearAllTables();
    method public void close();
    method public androidx.sqlite.db.SupportSQLiteStatement! compileStatement(String);
    method protected abstract androidx.room.InvalidationTracker createInvalidationTracker();
    method protected abstract androidx.sqlite.db.SupportSQLiteOpenHelper createOpenHelper(androidx.room.DatabaseConfiguration!);
    method @Deprecated public void endTransaction();
    method public androidx.room.InvalidationTracker getInvalidationTracker();
    method public androidx.sqlite.db.SupportSQLiteOpenHelper getOpenHelper();
    method public java.util.concurrent.Executor getQueryExecutor();
    method public java.util.concurrent.Executor getTransactionExecutor();
    method public boolean inTransaction();
    method @CallSuper public void init(androidx.room.DatabaseConfiguration);
    method protected void internalInitInvalidationTracker(androidx.sqlite.db.SupportSQLiteDatabase);
    method public boolean isOpen();
    method public android.database.Cursor query(String, Object![]?);
    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery);
    method public android.database.Cursor query(androidx.sqlite.db.SupportSQLiteQuery, android.os.CancellationSignal?);
    method public void runInTransaction(Runnable);
    method public <V> V! runInTransaction(java.util.concurrent.Callable<V!>);
    method @Deprecated public void setTransactionSuccessful();
    field @Deprecated protected java.util.List<androidx.room.RoomDatabase.Callback!>? mCallbacks;
    field @Deprecated protected volatile androidx.sqlite.db.SupportSQLiteDatabase! mDatabase;
  }

  public static class RoomDatabase.Builder<T extends androidx.room.RoomDatabase> {
    method public androidx.room.RoomDatabase.Builder<T!> addCallback(androidx.room.RoomDatabase.Callback);
    method public androidx.room.RoomDatabase.Builder<T!> addMigrations(androidx.room.migration.Migration!...);
    method public androidx.room.RoomDatabase.Builder<T!> allowMainThreadQueries();
    method public T build();
    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String);
    method public androidx.room.RoomDatabase.Builder<T!> createFromAsset(String, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File);
    method public androidx.room.RoomDatabase.Builder<T!> createFromFile(java.io.File, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>);
    method public androidx.room.RoomDatabase.Builder<T!> createFromInputStream(java.util.concurrent.Callable<java.io.InputStream!>, androidx.room.RoomDatabase.PrepackagedDatabaseCallback);
    method public androidx.room.RoomDatabase.Builder<T!> enableMultiInstanceInvalidation();
    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigration();
    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationFrom(int...);
    method public androidx.room.RoomDatabase.Builder<T!> fallbackToDestructiveMigrationOnDowngrade();
    method public androidx.room.RoomDatabase.Builder<T!> openHelperFactory(androidx.sqlite.db.SupportSQLiteOpenHelper.Factory?);
    method public androidx.room.RoomDatabase.Builder<T!> setJournalMode(androidx.room.RoomDatabase.JournalMode);
    method public androidx.room.RoomDatabase.Builder<T!> setQueryExecutor(java.util.concurrent.Executor);
    method public androidx.room.RoomDatabase.Builder<T!> setTransactionExecutor(java.util.concurrent.Executor);
  }

  public abstract static class RoomDatabase.Callback {
    ctor public RoomDatabase.Callback();
    method public void onCreate(androidx.sqlite.db.SupportSQLiteDatabase);
    method public void onDestructiveMigration(androidx.sqlite.db.SupportSQLiteDatabase);
    method public void onOpen(androidx.sqlite.db.SupportSQLiteDatabase);
  }

  public enum RoomDatabase.JournalMode {
    enum_constant public static final androidx.room.RoomDatabase.JournalMode AUTOMATIC;
    enum_constant public static final androidx.room.RoomDatabase.JournalMode TRUNCATE;
    enum_constant @RequiresApi(android.os.Build.VERSION_CODES.JELLY_BEAN) public static final androidx.room.RoomDatabase.JournalMode WRITE_AHEAD_LOGGING;
  }

  public static class RoomDatabase.MigrationContainer {
    ctor public RoomDatabase.MigrationContainer();
    method public void addMigrations(androidx.room.migration.Migration!...);
    method public java.util.List<androidx.room.migration.Migration!>? findMigrationPath(int, int);
  }

  public abstract static class RoomDatabase.PrepackagedDatabaseCallback {
    ctor public RoomDatabase.PrepackagedDatabaseCallback();
    method public void onOpenPrepackagedDatabase(androidx.sqlite.db.SupportSQLiteDatabase);
  }

}

package androidx.room.migration {

  public abstract class Migration {
    ctor public Migration(int, int);
    method public abstract void migrate(androidx.sqlite.db.SupportSQLiteDatabase);
    field public final int endVersion;
    field public final int startVersion;
  }

}

