android: Migrate to the Gradle build system
[strongswan.git] / src / frontends / android / app / src / main / java / org / strongswan / android / data / LogContentProvider.java
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 package org.strongswan.android.data;
17
18 import java.io.File;
19 import java.io.FileNotFoundException;
20 import java.security.NoSuchAlgorithmException;
21 import java.security.SecureRandom;
22 import java.util.concurrent.ConcurrentHashMap;
23
24 import org.strongswan.android.logic.CharonVpnService;
25
26 import android.content.ContentProvider;
27 import android.content.ContentValues;
28 import android.database.Cursor;
29 import android.database.MatrixCursor;
30 import android.net.Uri;
31 import android.os.ParcelFileDescriptor;
32 import android.os.SystemClock;
33 import android.provider.OpenableColumns;
34
35 public class LogContentProvider extends ContentProvider
36 {
37 private static final String AUTHORITY = "org.strongswan.android.content.log";
38 /* an Uri is valid for 30 minutes */
39 private static final long URI_VALIDITY = 30 * 60 * 1000;
40 private static ConcurrentHashMap<Uri, Long> mUris = new ConcurrentHashMap<Uri, Long>();
41 private File mLogFile;
42
43 public LogContentProvider()
44 {
45 }
46
47 @Override
48 public boolean onCreate()
49 {
50 mLogFile = new File(getContext().getFilesDir(), CharonVpnService.LOG_FILE);
51 return true;
52 }
53
54 /**
55 * The log file can only be accessed by Uris created with this method
56 * @return null if failed to create the Uri
57 */
58 public static Uri createContentUri()
59 {
60 SecureRandom random;
61 try
62 {
63 random = SecureRandom.getInstance("SHA1PRNG");
64 }
65 catch (NoSuchAlgorithmException e)
66 {
67 return null;
68 }
69 Uri uri = Uri.parse("content://" + AUTHORITY + "/" + random.nextLong());
70 mUris.put(uri, SystemClock.uptimeMillis());
71 return uri;
72 }
73
74 @Override
75 public String getType(Uri uri)
76 {
77 /* MIME type for our log file */
78 return "text/plain";
79 }
80
81 @Override
82 public Cursor query(Uri uri, String[] projection, String selection,
83 String[] selectionArgs, String sortOrder)
84 {
85 /* this is called by apps to find out the name and size of the file.
86 * since we only provide a single file this is simple to implement */
87 if (projection == null || projection.length < 1)
88 {
89 return null;
90 }
91 Long timestamp = mUris.get(uri);
92 if (timestamp == null)
93 { /* don't check the validity as this information is not really private */
94 return null;
95 }
96 MatrixCursor cursor = new MatrixCursor(projection, 1);
97 if (OpenableColumns.DISPLAY_NAME.equals(cursor.getColumnName(0)))
98 {
99 cursor.newRow().add(CharonVpnService.LOG_FILE);
100 }
101 else if (OpenableColumns.SIZE.equals(cursor.getColumnName(0)))
102 {
103 cursor.newRow().add(mLogFile.length());
104 }
105 else
106 {
107 return null;
108 }
109 return cursor;
110 }
111
112 @Override
113 public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
114 {
115 Long timestamp = mUris.get(uri);
116 if (timestamp != null)
117 {
118 long elapsed = SystemClock.uptimeMillis() - timestamp;
119 if (elapsed > 0 && elapsed < URI_VALIDITY)
120 { /* we fail if clock wrapped, should happen rarely though */
121 return ParcelFileDescriptor.open(mLogFile, ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_ONLY);
122 }
123 mUris.remove(uri);
124 }
125 return super.openFile(uri, mode);
126 }
127
128 @Override
129 public Uri insert(Uri uri, ContentValues values)
130 {
131 /* not supported */
132 return null;
133 }
134
135 @Override
136 public int delete(Uri uri, String selection, String[] selectionArgs)
137 {
138 /* not supported */
139 return 0;
140 }
141
142 @Override
143 public int update(Uri uri, ContentValues values, String selection,
144 String[] selectionArgs)
145 {
146 /* not supported */
147 return 0;
148 }
149 }