1 /*
2  * Copyright (C) 2008 Esmertec AG.
3  * Copyright (C) 2008 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.google.android.mms.util;
19 
20 import android.app.ActivityManager;
21 import android.compat.annotation.UnsupportedAppUsage;
22 import android.content.ContentResolver;
23 import android.content.ContentValues;
24 import android.content.Context;
25 import android.database.Cursor;
26 import android.database.sqlite.SQLiteException;
27 import android.net.Uri;
28 import android.os.Build;
29 import android.util.Log;
30 import android.widget.Toast;
31 
32 public final class SqliteWrapper {
33     private static final String TAG = "SqliteWrapper";
34     private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE
35                 = "unable to open database file";
36 
SqliteWrapper()37     private SqliteWrapper() {
38         // Forbidden being instantiated.
39     }
40 
41     // FIXME: It looks like outInfo.lowMemory does not work well as we expected.
42     // after run command: adb shell fillup -p 100, outInfo.lowMemory is still false.
isLowMemory(Context context)43     private static boolean isLowMemory(Context context) {
44         if (null == context) {
45             return false;
46         }
47 
48         ActivityManager am = (ActivityManager)
49                         context.getSystemService(Context.ACTIVITY_SERVICE);
50         ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
51         am.getMemoryInfo(outInfo);
52 
53         return outInfo.lowMemory;
54     }
55 
56     // FIXME: need to optimize this method.
isLowMemory(SQLiteException e)57     private static boolean isLowMemory(SQLiteException e) {
58         return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
59     }
60 
61     @UnsupportedAppUsage
checkSQLiteException(Context context, SQLiteException e)62     public static void checkSQLiteException(Context context, SQLiteException e) {
63         if (isLowMemory(e)) {
64             Toast.makeText(context, com.android.internal.R.string.low_memory,
65                     Toast.LENGTH_SHORT).show();
66         } else {
67             throw e;
68         }
69     }
70 
71     @UnsupportedAppUsage
query(Context context, ContentResolver resolver, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)72     public static Cursor query(Context context, ContentResolver resolver, Uri uri,
73             String[] projection, String selection, String[] selectionArgs, String sortOrder) {
74         try {
75             return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
76         } catch (SQLiteException e) {
77             Log.e(TAG, "Catch a SQLiteException when query: ", e);
78             checkSQLiteException(context, e);
79             return null;
80         }
81     }
82 
83     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
requery(Context context, Cursor cursor)84     public static boolean requery(Context context, Cursor cursor) {
85         try {
86             return cursor.requery();
87         } catch (SQLiteException e) {
88             Log.e(TAG, "Catch a SQLiteException when requery: ", e);
89             checkSQLiteException(context, e);
90             return false;
91         }
92     }
93     @UnsupportedAppUsage
update(Context context, ContentResolver resolver, Uri uri, ContentValues values, String where, String[] selectionArgs)94     public static int update(Context context, ContentResolver resolver, Uri uri,
95             ContentValues values, String where, String[] selectionArgs) {
96         try {
97             return resolver.update(uri, values, where, selectionArgs);
98         } catch (SQLiteException e) {
99             Log.e(TAG, "Catch a SQLiteException when update: ", e);
100             checkSQLiteException(context, e);
101             return -1;
102         }
103     }
104 
105     @UnsupportedAppUsage
delete(Context context, ContentResolver resolver, Uri uri, String where, String[] selectionArgs)106     public static int delete(Context context, ContentResolver resolver, Uri uri,
107             String where, String[] selectionArgs) {
108         try {
109             return resolver.delete(uri, where, selectionArgs);
110         } catch (SQLiteException e) {
111             Log.e(TAG, "Catch a SQLiteException when delete: ", e);
112             checkSQLiteException(context, e);
113             return -1;
114         }
115     }
116 
117     @UnsupportedAppUsage
insert(Context context, ContentResolver resolver, Uri uri, ContentValues values)118     public static Uri insert(Context context, ContentResolver resolver,
119             Uri uri, ContentValues values) {
120         try {
121             return resolver.insert(uri, values);
122         } catch (SQLiteException e) {
123             Log.e(TAG, "Catch a SQLiteException when insert: ", e);
124             checkSQLiteException(context, e);
125             return null;
126         }
127     }
128 }
129