11package org .pocketworkstation .pckeyboard ;
22
3- import java .io .IOException ;
4- import java .io .InputStream ;
5- import java .util .ArrayList ;
6- import java .util .HashMap ;
7- import java .util .List ;
8- import java .util .Map ;
9-
10- import org .xmlpull .v1 .XmlPullParserException ;
11-
123import android .content .BroadcastReceiver ;
134import android .content .Context ;
145import android .content .Intent ;
156import android .content .pm .ApplicationInfo ;
167import android .content .pm .PackageManager ;
17- import android .content .pm .ResolveInfo ;
188import android .content .pm .PackageManager .NameNotFoundException ;
9+ import android .content .pm .ResolveInfo ;
1910import android .content .res .Resources ;
11+ import android .content .res .TypedArray ;
2012import android .content .res .XmlResourceParser ;
2113import android .util .Log ;
2214
15+ import org .xmlpull .v1 .XmlPullParserException ;
16+
17+ import java .io .IOException ;
18+ import java .io .InputStream ;
19+ import java .util .ArrayList ;
20+ import java .util .HashMap ;
21+ import java .util .List ;
22+ import java .util .Map ;
23+
2324public class PluginManager extends BroadcastReceiver {
2425 private static String TAG = "PCKeyboard" ;
2526 private static String HK_INTENT_DICT = "org.pocketworkstation.DICT" ;
2627 private static String SOFTKEYBOARD_INTENT_DICT = "com.menny.android.anysoftkeyboard.DICTIONARY" ;
2728 private LatinIME mIME ;
28-
29+
2930 // Apparently anysoftkeyboard doesn't use ISO 639-1 language codes for its locales?
3031 // Add exceptions as needed.
3132 private static Map <String , String > SOFTKEYBOARD_LANG_MAP = new HashMap <String , String >();
33+
3234 static {
3335 SOFTKEYBOARD_LANG_MAP .put ("dk" , "da" );
3436 }
35-
36- PluginManager (LatinIME ime ) {
37- super ();
38- mIME = ime ;
39- }
40-
41- private static Map <String , DictPluginSpec > mPluginDicts =
42- new HashMap <String , DictPluginSpec >();
43-
44- static interface DictPluginSpec {
45- BinaryDictionary getDict (Context context );
46- }
47-
48- static private abstract class DictPluginSpecBase
49- implements DictPluginSpec {
50- String mPackageName ;
51-
52- Resources getResources (Context context ) {
53- PackageManager packageManager = context .getPackageManager ();
54- Resources res = null ;
55- try {
56- ApplicationInfo appInfo = packageManager .getApplicationInfo (mPackageName , 0 );
57- res = packageManager .getResourcesForApplication (appInfo );
58- } catch (NameNotFoundException e ) {
59- Log .i (TAG , "couldn't get resources" );
60- }
61- return res ;
62- }
63-
64- abstract InputStream [] getStreams (Resources res );
65-
66- public BinaryDictionary getDict (Context context ) {
67- Resources res = getResources (context );
68- if (res == null ) return null ;
69-
70- InputStream [] dicts = getStreams (res );
71- if (dicts == null ) return null ;
72- BinaryDictionary dict = new BinaryDictionary (
73- context , dicts , Suggest .DIC_MAIN );
74- if (dict .getSize () == 0 ) return null ;
75- //Log.i(TAG, "dict size=" + dict.getSize());
76- return dict ;
77- }
78- }
79-
80- static private class DictPluginSpecHK
81- extends DictPluginSpecBase {
82-
83- int [] mRawIds ;
8437
85- public DictPluginSpecHK (String pkg , int [] ids ) {
86- mPackageName = pkg ;
87- mRawIds = ids ;
88- }
38+ private static Map <String , DictPluginSpec > mPluginDicts =
39+ new HashMap <String , DictPluginSpec >();
8940
90- @ Override
91- InputStream [] getStreams (Resources res ) {
92- if (mRawIds == null || mRawIds .length == 0 ) return null ;
93- InputStream [] streams = new InputStream [mRawIds .length ];
94- for (int i = 0 ; i < mRawIds .length ; ++i ) {
95- streams [i ] = res .openRawResource (mRawIds [i ]);
96- }
97- return streams ;
98- }
41+ PluginManager (LatinIME ime ) {
42+ super ();
43+ mIME = ime ;
9944 }
100-
101- static private class DictPluginSpecSoftKeyboard
102- extends DictPluginSpecBase {
103-
104- String mAssetName ;
10545
106- public DictPluginSpecSoftKeyboard (String pkg , String asset ) {
107- mPackageName = pkg ;
108- mAssetName = asset ;
109- }
110-
111- @ Override
112- InputStream [] getStreams (Resources res ) {
113- if (mAssetName == null ) return null ;
114- try {
115- InputStream in = res .getAssets ().open (mAssetName );
116- return new InputStream [] {in };
117- } catch (IOException e ) {
118- Log .e (TAG , "Dictionary asset loading failure" );
119- return null ;
120- }
121- }
122- }
123-
124- @ Override
125- public void onReceive (Context context , Intent intent ) {
126- Log .i (TAG , "Package information changed, updating dictionaries." );
127- getPluginDictionaries (context );
128- Log .i (TAG , "Finished updating dictionaries." );
129- mIME .toggleLanguage (true , true );
46+ static interface DictPluginSpec {
47+ BinaryDictionary getDict (Context context );
13048 }
13149
13250 static void getSoftKeyboardDictionaries (PackageManager packageManager ) {
13351 Intent dictIntent = new Intent (SOFTKEYBOARD_INTENT_DICT );
13452 List <ResolveInfo > dictPacks = packageManager .queryBroadcastReceivers (
135- dictIntent , PackageManager .GET_RECEIVERS );
53+ dictIntent , PackageManager .GET_RECEIVERS );
13654 for (ResolveInfo ri : dictPacks ) {
13755 ApplicationInfo appInfo = ri .activityInfo .applicationInfo ;
13856 String pkgName = appInfo .packageName ;
@@ -145,6 +63,7 @@ static void getSoftKeyboardDictionaries(PackageManager packageManager) {
14563 XmlResourceParser xrp = res .getXml (dictId );
14664
14765 String assetName = null ;
66+ int resId = 0 ;
14867 String lang = null ;
14968 try {
15069 int current = xrp .getEventType ();
@@ -157,8 +76,9 @@ static void getSoftKeyboardDictionaries(PackageManager packageManager) {
15776 String convLang = SOFTKEYBOARD_LANG_MAP .get (lang );
15877 if (convLang != null ) lang = convLang ;
15978 String type = xrp .getAttributeValue (null , "type" );
160- if (type == null || type .equals ("raw" ) || type .equals ("binary" )) {
79+ if (type == null || type .equals ("raw" ) || type .equals ("binary" ) || type . equals ( "binary_resource" ) ) {
16180 assetName = xrp .getAttributeValue (null , "dictionaryAssertName" ); // sic
81+ resId = xrp .getAttributeResourceValue (null , "dictionaryResourceId" , 0 );
16282 } else {
16383 Log .w (TAG , "Unsupported AnySoftKeyboard dict type " + type );
16484 }
@@ -175,8 +95,8 @@ static void getSoftKeyboardDictionaries(PackageManager packageManager) {
17595 Log .e (TAG , "Dictionary XML IOException" );
17696 }
17797
178- if (assetName == null || lang == null ) continue ;
179- DictPluginSpec spec = new DictPluginSpecSoftKeyboard (pkgName , assetName );
98+ if (( assetName == null && resId == 0 ) || lang == null ) continue ;
99+ DictPluginSpec spec = new DictPluginSpecSoftKeyboard (pkgName , assetName , resId );
180100 mPluginDicts .put (lang , spec );
181101 Log .i (TAG , "Found plugin dictionary: lang=" + lang + ", pkg=" + pkgName );
182102 success = true ;
@@ -204,11 +124,11 @@ static void getHKDictionaries(PackageManager packageManager) {
204124 if (langId == 0 ) continue ;
205125 String lang = res .getString (langId );
206126 int [] rawIds = null ;
207-
127+
208128 // Try single-file version first
209129 int rawId = res .getIdentifier ("main" , "raw" , pkgName );
210130 if (rawId != 0 ) {
211- rawIds = new int [] { rawId };
131+ rawIds = new int []{ rawId };
212132 } else {
213133 // try multi-part version
214134 int parts = 0 ;
@@ -237,13 +157,117 @@ static void getHKDictionaries(PackageManager packageManager) {
237157 }
238158 }
239159
160+ @ Override
161+ public void onReceive (Context context , Intent intent ) {
162+ Log .i (TAG , "Package information changed, updating dictionaries." );
163+ getPluginDictionaries (context );
164+ Log .i (TAG , "Finished updating dictionaries." );
165+ mIME .toggleLanguage (true , true );
166+ }
167+
168+ static private abstract class DictPluginSpecBase
169+ implements DictPluginSpec {
170+ String mPackageName ;
171+
172+ Resources getResources (Context context ) {
173+ PackageManager packageManager = context .getPackageManager ();
174+ Resources res = null ;
175+ try {
176+ ApplicationInfo appInfo = packageManager .getApplicationInfo (mPackageName , 0 );
177+ res = packageManager .getResourcesForApplication (appInfo );
178+ } catch (NameNotFoundException e ) {
179+ Log .i (TAG , "couldn't get resources" );
180+ }
181+ return res ;
182+ }
183+
184+ abstract InputStream [] getStreams (Resources res );
185+
186+ public BinaryDictionary getDict (Context context ) {
187+ Resources res = getResources (context );
188+ if (res == null ) return null ;
189+
190+ InputStream [] dicts = getStreams (res );
191+ if (dicts == null ) return null ;
192+ BinaryDictionary dict = new BinaryDictionary (
193+ context , dicts , Suggest .DIC_MAIN );
194+ if (dict .getSize () == 0 ) return null ;
195+ //Log.i(TAG, "dict size=" + dict.getSize());
196+ return dict ;
197+ }
198+ }
199+
200+ static private class DictPluginSpecHK
201+ extends DictPluginSpecBase {
202+
203+ int [] mRawIds ;
204+
205+ public DictPluginSpecHK (String pkg , int [] ids ) {
206+ mPackageName = pkg ;
207+ mRawIds = ids ;
208+ }
209+
210+ @ Override
211+ InputStream [] getStreams (Resources res ) {
212+ if (mRawIds == null || mRawIds .length == 0 ) return null ;
213+ InputStream [] streams = new InputStream [mRawIds .length ];
214+ for (int i = 0 ; i < mRawIds .length ; ++i ) {
215+ streams [i ] = res .openRawResource (mRawIds [i ]);
216+ }
217+ return streams ;
218+ }
219+ }
220+
221+ static private class DictPluginSpecSoftKeyboard
222+ extends DictPluginSpecBase {
223+
224+ String mAssetName ;
225+ int mResId ;
226+
227+ public DictPluginSpecSoftKeyboard (String pkg , String asset , int resId ) {
228+ mPackageName = pkg ;
229+ mAssetName = asset ;
230+ mResId = resId ;
231+ }
232+
233+ @ Override
234+ InputStream [] getStreams (Resources res ) {
235+ if (mAssetName == null ) {
236+ if (mResId == 0 ) return null ;
237+ TypedArray a = res .obtainTypedArray (mResId );
238+ int [] resIds ;
239+ try {
240+ resIds = new int [a .length ()];
241+ for (int i = 0 ; i < a .length (); ++i ) {
242+ resIds [i ] = a .getResourceId (i , 0 );
243+ }
244+ } finally {
245+ a .recycle ();
246+ }
247+ InputStream [] in = new InputStream [resIds .length ];
248+ for (int i = 0 ; i < resIds .length ; ++i ) {
249+ in [i ] = res .openRawResource (resIds [i ]);
250+ }
251+ return in ;
252+ } else {
253+ try {
254+ InputStream in = res .getAssets ().open (mAssetName );
255+ return new InputStream []{in };
256+ } catch (IOException e ) {
257+ Log .e (TAG , "Dictionary asset loading failure" );
258+ return null ;
259+ }
260+ }
261+ }
262+ }
263+
240264 static void getPluginDictionaries (Context context ) {
241265 mPluginDicts .clear ();
242266 PackageManager packageManager = context .getPackageManager ();
243267 getSoftKeyboardDictionaries (packageManager );
244268 getHKDictionaries (packageManager );
245269 }
246-
270+
247271 static BinaryDictionary getDictionary (Context context , String lang ) {
248272 //Log.i(TAG, "Looking for plugin dictionary for lang=" + lang);
249273 DictPluginSpec spec = mPluginDicts .get (lang );
0 commit comments