1 /*
2  * Copyright (C) 2009 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 android.gesture;
18 
19 import android.annotation.NonNull;
20 import android.annotation.RawRes;
21 import android.os.ParcelFileDescriptor;
22 import android.util.Log;
23 import static android.gesture.GestureConstants.*;
24 import android.content.Context;
25 
26 import java.io.File;
27 import java.io.FileDescriptor;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.io.FileInputStream;
31 import java.io.InputStream;
32 import java.lang.ref.WeakReference;
33 
34 public final class GestureLibraries {
GestureLibraries()35     private GestureLibraries() {
36     }
37 
fromFile(String path)38     public static GestureLibrary fromFile(String path) {
39         return fromFile(new File(path));
40     }
41 
fromFile(File path)42     public static GestureLibrary fromFile(File path) {
43         return new FileGestureLibrary(path);
44     }
45 
46     @NonNull
fromFileDescriptor(@onNull ParcelFileDescriptor pfd)47     public static GestureLibrary fromFileDescriptor(@NonNull ParcelFileDescriptor pfd) {
48         return new FileGestureLibrary(pfd.getFileDescriptor());
49     }
50 
fromPrivateFile(Context context, String name)51     public static GestureLibrary fromPrivateFile(Context context, String name) {
52         return fromFile(context.getFileStreamPath(name));
53     }
54 
fromRawResource(Context context, @RawRes int resourceId)55     public static GestureLibrary fromRawResource(Context context, @RawRes int resourceId) {
56         return new ResourceGestureLibrary(context, resourceId);
57     }
58 
59     private static class FileGestureLibrary extends GestureLibrary {
60         // Either a file or an fd is used
61         private final File mPath;
62         private final FileDescriptor mFd;
63 
FileGestureLibrary(File path)64         public FileGestureLibrary(File path) {
65             mPath = path;
66             mFd = null;
67         }
68 
FileGestureLibrary(FileDescriptor fd)69         public FileGestureLibrary(FileDescriptor fd) {
70             mPath = null;
71             mFd = fd;
72         }
73 
74         /**
75          * <p>If this GestureLibrary was created using a FileDescriptor,
76          * this method will always return false.
77          */
78         @Override
isReadOnly()79         public boolean isReadOnly() {
80             if (mPath != null) {
81                 return !mPath.canWrite();
82             }
83             return false;
84         }
85 
save()86         public boolean save() {
87             if (!mStore.hasChanged()) return true;
88             boolean result = false;
89 
90             if (mPath != null) {
91                 final File file = mPath;
92 
93                 final File parentFile = file.getParentFile();
94                 if (!parentFile.exists()) {
95                     if (!parentFile.mkdirs()) {
96                         return false;
97                     }
98                 }
99 
100                 try {
101                     //noinspection ResultOfMethodCallIgnored
102                     file.createNewFile();
103                     mStore.save(new FileOutputStream(file), true);
104                     result = true;
105                 } catch (IOException e) {
106                     Log.d(LOG_TAG, "Could not save the gesture library in " + mPath, e);
107                 }
108             } else {
109                 try {
110                     mStore.save(new FileOutputStream(mFd), true);
111                     result = true;
112                 } catch (IOException e) {
113                     Log.d(LOG_TAG, "Could not save the gesture library", e);
114                 }
115             }
116             return result;
117         }
118 
load()119         public boolean load() {
120             boolean result = false;
121             if (mPath != null) {
122                 final File file = mPath;
123                 if (file.exists() && file.canRead()) {
124                     try {
125                         mStore.load(new FileInputStream(file), true);
126                         result = true;
127                     } catch (IOException e) {
128                         Log.d(LOG_TAG, "Could not load the gesture library from " + mPath, e);
129                     }
130                 }
131             } else {
132                 try {
133                     mStore.load(new FileInputStream(mFd), true);
134                     result = true;
135                 } catch (IOException e) {
136                     Log.d(LOG_TAG, "Could not load the gesture library", e);
137                 }
138             }
139 
140             return result;
141         }
142     }
143 
144     private static class ResourceGestureLibrary extends GestureLibrary {
145         private final WeakReference<Context> mContext;
146         private final int mResourceId;
147 
ResourceGestureLibrary(Context context, int resourceId)148         public ResourceGestureLibrary(Context context, int resourceId) {
149             mContext = new WeakReference<Context>(context);
150             mResourceId = resourceId;
151         }
152 
153         @Override
isReadOnly()154         public boolean isReadOnly() {
155             return true;
156         }
157 
save()158         public boolean save() {
159             return false;
160         }
161 
load()162         public boolean load() {
163             boolean result = false;
164             final Context context = mContext.get();
165             if (context != null) {
166                 final InputStream in = context.getResources().openRawResource(mResourceId);
167                 try {
168                     mStore.load(in, true);
169                     result = true;
170                 } catch (IOException e) {
171                     Log.d(LOG_TAG, "Could not load the gesture library from raw resource " +
172                             context.getResources().getResourceName(mResourceId), e);
173                 }
174             }
175 
176             return result;
177         }
178     }
179 }
180