10a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy/*
20a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * Copyright (C) 2009 The Android Open Source Project
30a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy *
40a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
50a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * you may not use this file except in compliance with the License.
60a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * You may obtain a copy of the License at
70a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy *
80a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
90a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy *
100a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * Unless required by applicable law or agreed to in writing, software
110a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
120a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * See the License for the specific language governing permissions and
140a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy * limitations under the License.
150a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy */
160a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
170a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guypackage android.gesture;
180a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
190a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport android.util.Log;
200a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport static android.gesture.GestureConstants.*;
210a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport android.content.Context;
220a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
230a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport java.io.File;
240a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport java.io.FileOutputStream;
250a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport java.io.FileNotFoundException;
260a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport java.io.IOException;
270a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport java.io.FileInputStream;
280a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport java.io.InputStream;
290a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guyimport java.lang.ref.WeakReference;
300a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
310a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guypublic final class GestureLibraries {
320a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    private GestureLibraries() {
330a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    }
340a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
350a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    public static GestureLibrary fromFile(String path) {
360a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        return fromFile(new File(path));
370a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    }
380a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
390a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    public static GestureLibrary fromFile(File path) {
400a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        return new FileGestureLibrary(path);
410a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    }
420a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
430a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    public static GestureLibrary fromPrivateFile(Context context, String name) {
440a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        return fromFile(context.getFileStreamPath(name));
450a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    }
460a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
470a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    public static GestureLibrary fromRawResource(Context context, int resourceId) {
480a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        return new ResourceGestureLibrary(context, resourceId);
490a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    }
500a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
510a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    private static class FileGestureLibrary extends GestureLibrary {
520a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        private final File mPath;
530a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
540a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public FileGestureLibrary(File path) {
550a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            mPath = path;
560a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
570a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
580a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        @Override
590a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public boolean isReadOnly() {
600a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            return !mPath.canWrite();
610a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
620a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
630a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public boolean save() {
6403f0b21b5a317aa6c0f0cd4d7ac91cabdf379d3eRomain Guy            if (!mStore.hasChanged()) return true;
6503f0b21b5a317aa6c0f0cd4d7ac91cabdf379d3eRomain Guy
660a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            final File file = mPath;
670a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
6803f0b21b5a317aa6c0f0cd4d7ac91cabdf379d3eRomain Guy            final File parentFile = file.getParentFile();
6903f0b21b5a317aa6c0f0cd4d7ac91cabdf379d3eRomain Guy            if (!parentFile.exists()) {
7003f0b21b5a317aa6c0f0cd4d7ac91cabdf379d3eRomain Guy                if (!parentFile.mkdirs()) {
710a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    return false;
720a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                }
730a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            }
740a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
750a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            boolean result = false;
760a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            try {
7703f0b21b5a317aa6c0f0cd4d7ac91cabdf379d3eRomain Guy                //noinspection ResultOfMethodCallIgnored
7803f0b21b5a317aa6c0f0cd4d7ac91cabdf379d3eRomain Guy                file.createNewFile();
790a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                mStore.save(new FileOutputStream(file), true);
800a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                result = true;
810a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            } catch (FileNotFoundException e) {
820a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                Log.d(LOG_TAG, "Could not save the gesture library in " + mPath, e);
830a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            } catch (IOException e) {
840a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                Log.d(LOG_TAG, "Could not save the gesture library in " + mPath, e);
850a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            }
860a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
870a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            return result;
880a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
890a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
900a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public boolean load() {
910a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            boolean result = false;
920a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            final File file = mPath;
930a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            if (file.exists() && file.canRead()) {
940a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                try {
950a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    mStore.load(new FileInputStream(file), true);
960a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    result = true;
970a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                } catch (FileNotFoundException e) {
980a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    Log.d(LOG_TAG, "Could not load the gesture library from " + mPath, e);
990a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                } catch (IOException e) {
1000a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    Log.d(LOG_TAG, "Could not load the gesture library from " + mPath, e);
1010a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                }
1020a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            }
1030a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
1040a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            return result;
1050a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
1060a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    }
1070a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
1080a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    private static class ResourceGestureLibrary extends GestureLibrary {
1090a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        private final WeakReference<Context> mContext;
1100a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        private final int mResourceId;
1110a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
1120a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public ResourceGestureLibrary(Context context, int resourceId) {
1130a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            mContext = new WeakReference<Context>(context);
1140a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            mResourceId = resourceId;
1150a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
1160a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
1170a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        @Override
1180a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public boolean isReadOnly() {
1190a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            return true;
1200a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
1210a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
1220a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public boolean save() {
1230a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            return false;
1240a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
1250a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
1260a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        public boolean load() {
1270a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            boolean result = false;
1280a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            final Context context = mContext.get();
1290a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            if (context != null) {
1300a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                final InputStream in = context.getResources().openRawResource(mResourceId);
1310a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                try {
1320a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    mStore.load(in, true);
1330a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    result = true;
1340a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                } catch (IOException e) {
1350a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                    Log.d(LOG_TAG, "Could not load the gesture library from raw resource " +
1360a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                            context.getResources().getResourceName(mResourceId), e);
1370a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy                }
1380a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            }
1390a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy
1400a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy            return result;
1410a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy        }
1420a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy    }
1430a63716ed0e44f7cd32b81a444429318d42d8f08Romain Guy}
144