• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.bluetooth.btservice.storage;
18 
19 import android.content.Context;
20 
21 import androidx.room.Database;
22 import androidx.room.Room;
23 import androidx.room.RoomDatabase;
24 import androidx.room.migration.Migration;
25 import androidx.sqlite.db.SupportSQLiteDatabase;
26 
27 import java.util.List;
28 
29 /**
30  * MetadataDatabase is a Room database stores Bluetooth persistence data
31  */
32 @Database(entities = {Metadata.class}, exportSchema = false, version = 102)
33 public abstract class MetadataDatabase extends RoomDatabase {
34     /**
35      * The database file name
36      */
37     public static final String DATABASE_NAME = "bluetooth_db";
38 
mMetadataDao()39     protected abstract MetadataDao mMetadataDao();
40 
41     /**
42      * Create a {@link MetadataDatabase} database with migrations
43      *
44      * @param context the Context to create database
45      * @return the created {@link MetadataDatabase}
46      */
createDatabase(Context context)47     public static MetadataDatabase createDatabase(Context context) {
48         return Room.databaseBuilder(context,
49                 MetadataDatabase.class, DATABASE_NAME)
50                 .addMigrations(MIGRATION_100_101)
51                 .addMigrations(MIGRATION_101_102)
52                 .build();
53     }
54 
55     /**
56      * Create a {@link MetadataDatabase} database without migration, database
57      * would be reset if any load failure happens
58      *
59      * @param context the Context to create database
60      * @return the created {@link MetadataDatabase}
61      */
createDatabaseWithoutMigration(Context context)62     public static MetadataDatabase createDatabaseWithoutMigration(Context context) {
63         return Room.databaseBuilder(context,
64                 MetadataDatabase.class, DATABASE_NAME)
65                 .fallbackToDestructiveMigration()
66                 .build();
67     }
68 
69     /**
70      * Insert a {@link Metadata} to database
71      *
72      * @param metadata the data wish to put into storage
73      */
insert(Metadata... metadata)74     public void insert(Metadata... metadata) {
75         mMetadataDao().insert(metadata);
76     }
77 
78     /**
79      * Load all data from database as a {@link List} of {@link Metadata}
80      *
81      * @return a {@link List} of {@link Metadata}
82      */
load()83     public List<Metadata> load() {
84         return mMetadataDao().load();
85     }
86 
87     /**
88      * Delete one of the {@link Metadata} contains in database
89      *
90      * @param address the address of Metadata to delete
91      */
delete(String address)92     public void delete(String address) {
93         mMetadataDao().delete(address);
94     }
95 
96     /**
97      * Clear database.
98      */
deleteAll()99     public void deleteAll() {
100         mMetadataDao().deleteAll();
101     }
102 
103     private static final Migration MIGRATION_100_101 = new Migration(100, 101) {
104         @Override
105         public void migrate(SupportSQLiteDatabase database) {
106             database.execSQL("ALTER TABLE metadata ADD COLUMN `pbap_client_priority` INTEGER");
107         }
108     };
109 
110     private static final Migration MIGRATION_101_102 = new Migration(101, 102) {
111         @Override
112         public void migrate(SupportSQLiteDatabase database) {
113             database.execSQL("CREATE TABLE IF NOT EXISTS `metadata_tmp` ("
114                     + "`address` TEXT NOT NULL, `migrated` INTEGER NOT NULL, "
115                     + "`a2dpSupportsOptionalCodecs` INTEGER NOT NULL, "
116                     + "`a2dpOptionalCodecsEnabled` INTEGER NOT NULL, "
117                     + "`a2dp_priority` INTEGER, `a2dp_sink_priority` INTEGER, "
118                     + "`hfp_priority` INTEGER, `hfp_client_priority` INTEGER, "
119                     + "`hid_host_priority` INTEGER, `pan_priority` INTEGER, "
120                     + "`pbap_priority` INTEGER, `pbap_client_priority` INTEGER, "
121                     + "`map_priority` INTEGER, `sap_priority` INTEGER, "
122                     + "`hearing_aid_priority` INTEGER, `map_client_priority` INTEGER, "
123                     + "`manufacturer_name` BLOB, `model_name` BLOB, `software_version` BLOB, "
124                     + "`hardware_version` BLOB, `companion_app` BLOB, `main_icon` BLOB, "
125                     + "`is_untethered_headset` BLOB, `untethered_left_icon` BLOB, "
126                     + "`untethered_right_icon` BLOB, `untethered_case_icon` BLOB, "
127                     + "`untethered_left_battery` BLOB, `untethered_right_battery` BLOB, "
128                     + "`untethered_case_battery` BLOB, `untethered_left_charging` BLOB, "
129                     + "`untethered_right_charging` BLOB, `untethered_case_charging` BLOB, "
130                     + "`enhanced_settings_ui_uri` BLOB, PRIMARY KEY(`address`))");
131 
132             database.execSQL("INSERT INTO metadata_tmp ("
133                     + "address, migrated, a2dpSupportsOptionalCodecs, a2dpOptionalCodecsEnabled, "
134                     + "a2dp_priority, a2dp_sink_priority, hfp_priority, hfp_client_priority, "
135                     + "hid_host_priority, pan_priority, pbap_priority, pbap_client_priority, "
136                     + "map_priority, sap_priority, hearing_aid_priority, map_client_priority, "
137                     + "manufacturer_name, model_name, software_version, hardware_version, "
138                     + "companion_app, main_icon, is_untethered_headset, untethered_left_icon, "
139                     + "untethered_right_icon, untethered_case_icon, untethered_left_battery, "
140                     + "untethered_right_battery, untethered_case_battery, "
141                     + "untethered_left_charging, untethered_right_charging, "
142                     + "untethered_case_charging, enhanced_settings_ui_uri) "
143                     + "SELECT "
144                     + "address, migrated, a2dpSupportsOptionalCodecs, a2dpOptionalCodecsEnabled, "
145                     + "a2dp_priority, a2dp_sink_priority, hfp_priority, hfp_client_priority, "
146                     + "hid_host_priority, pan_priority, pbap_priority, pbap_client_priority, "
147                     + "map_priority, sap_priority, hearing_aid_priority, map_client_priority, "
148                     + "CAST (manufacturer_name AS BLOB), "
149                     + "CAST (model_name AS BLOB), "
150                     + "CAST (software_version AS BLOB), "
151                     + "CAST (hardware_version AS BLOB), "
152                     + "CAST (companion_app AS BLOB), "
153                     + "CAST (main_icon AS BLOB), "
154                     + "CAST (is_unthethered_headset AS BLOB), "
155                     + "CAST (unthethered_left_icon AS BLOB), "
156                     + "CAST (unthethered_right_icon AS BLOB), "
157                     + "CAST (unthethered_case_icon AS BLOB), "
158                     + "CAST (unthethered_left_battery AS BLOB), "
159                     + "CAST (unthethered_right_battery AS BLOB), "
160                     + "CAST (unthethered_case_battery AS BLOB), "
161                     + "CAST (unthethered_left_charging AS BLOB), "
162                     + "CAST (unthethered_right_charging AS BLOB), "
163                     + "CAST (unthethered_case_charging AS BLOB), "
164                     + "CAST (enhanced_settings_ui_uri AS BLOB)"
165                     + "FROM metadata");
166 
167             database.execSQL("DROP TABLE `metadata`");
168             database.execSQL("ALTER TABLE `metadata_tmp` RENAME TO `metadata`");
169         }
170     };
171 }
172