1 /*
2  * Copyright (C) 2013 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.inputmethod.latin.personalization;
18 
19 import android.content.Context;
20 import android.util.Log;
21 
22 import com.android.inputmethod.latin.common.FileUtils;
23 
24 import java.io.File;
25 import java.io.FilenameFilter;
26 import java.lang.ref.SoftReference;
27 import java.util.Locale;
28 import java.util.concurrent.ConcurrentHashMap;
29 
30 import javax.annotation.Nonnull;
31 import javax.annotation.Nullable;
32 
33 /**
34  * Helps handle and manage personalized dictionaries such as {@link UserHistoryDictionary}.
35  */
36 public class PersonalizationHelper {
37     private static final String TAG = PersonalizationHelper.class.getSimpleName();
38     private static final boolean DEBUG = false;
39 
40     private static final ConcurrentHashMap<String, SoftReference<UserHistoryDictionary>>
41             sLangUserHistoryDictCache = new ConcurrentHashMap<>();
42 
43     @Nonnull
getUserHistoryDictionary( final Context context, final Locale locale, @Nullable final String accountName)44     public static UserHistoryDictionary getUserHistoryDictionary(
45             final Context context, final Locale locale, @Nullable final String accountName) {
46         String lookupStr = locale.toString();
47         if (accountName != null) {
48             lookupStr += "." + accountName;
49         }
50         synchronized (sLangUserHistoryDictCache) {
51             if (sLangUserHistoryDictCache.containsKey(lookupStr)) {
52                 final SoftReference<UserHistoryDictionary> ref =
53                         sLangUserHistoryDictCache.get(lookupStr);
54                 final UserHistoryDictionary dict = ref == null ? null : ref.get();
55                 if (dict != null) {
56                     if (DEBUG) {
57                         Log.d(TAG, "Use cached UserHistoryDictionary with lookup: " + lookupStr);
58                     }
59                     dict.reloadDictionaryIfRequired();
60                     return dict;
61                 }
62             }
63             final UserHistoryDictionary dict = new UserHistoryDictionary(
64                     context, locale, accountName);
65             sLangUserHistoryDictCache.put(lookupStr, new SoftReference<>(dict));
66             return dict;
67         }
68     }
69 
removeAllUserHistoryDictionaries(final Context context)70     public static void removeAllUserHistoryDictionaries(final Context context) {
71         synchronized (sLangUserHistoryDictCache) {
72             for (final ConcurrentHashMap.Entry<String, SoftReference<UserHistoryDictionary>> entry
73                     : sLangUserHistoryDictCache.entrySet()) {
74                 if (entry.getValue() != null) {
75                     final UserHistoryDictionary dict = entry.getValue().get();
76                     if (dict != null) {
77                         dict.clear();
78                     }
79                 }
80             }
81             sLangUserHistoryDictCache.clear();
82             final File filesDir = context.getFilesDir();
83             if (filesDir == null) {
84                 Log.e(TAG, "context.getFilesDir() returned null.");
85                 return;
86             }
87             final boolean filesDeleted = FileUtils.deleteFilteredFiles(
88                     filesDir, new DictFilter(UserHistoryDictionary.NAME));
89             if (!filesDeleted) {
90                 Log.e(TAG, "Cannot remove dictionary files. filesDir: " + filesDir.getAbsolutePath()
91                         + ", dictNamePrefix: " + UserHistoryDictionary.NAME);
92             }
93         }
94     }
95 
96     private static class DictFilter implements FilenameFilter {
97         private final String mName;
98 
DictFilter(final String name)99         DictFilter(final String name) {
100             mName = name;
101         }
102 
103         @Override
accept(final File dir, final String name)104         public boolean accept(final File dir, final String name) {
105             return name.startsWith(mName);
106         }
107     }
108 }
109