14
14
15
15
package com .google .firebase .crashlytics .internal .persistence ;
16
16
17
- import android .annotation .SuppressLint ;
18
- import android .app .Application ;
19
17
import android .content .Context ;
20
- import android .os .Build .VERSION ;
21
- import android .os .Build .VERSION_CODES ;
22
18
import androidx .annotation .Nullable ;
23
19
import androidx .annotation .VisibleForTesting ;
24
20
import com .google .firebase .crashlytics .internal .Logger ;
21
+ import com .google .firebase .crashlytics .internal .ProcessDetailsProvider ;
22
+ import com .google .firebase .crashlytics .internal .common .CommonUtils ;
25
23
import java .io .File ;
26
24
import java .io .FilenameFilter ;
27
25
import java .util .Arrays ;
52
50
* convention, any use of new File(...) or similar outside of this class is a code smell.
53
51
*/
54
52
public class FileStore {
53
+
54
+ /** Deprecated old file system for systems that are not process aware. */
55
55
private static final String CRASHLYTICS_PATH_V1 = ".com.google.firebase.crashlytics.files.v1" ;
56
+
57
+ /** Deprecated old file system, process aware. Use v3, there is no use for this system anymore. */
56
58
private static final String CRASHLYTICS_PATH_V2 = ".com.google.firebase.crashlytics.files.v2" ;
59
+
60
+ /** Current file system, avoids long file names. */
61
+ private static final String CRASHLYTICS_PATH_V3 = ".crashlytics.v3" ;
62
+
57
63
private static final String SESSIONS_PATH = "open-sessions" ;
58
64
private static final String NATIVE_SESSION_SUBDIR = "native" ;
59
65
private static final String REPORTS_PATH = "reports" ;
60
66
private static final String PRIORITY_REPORTS_PATH = "priority-reports" ;
61
67
private static final String NATIVE_REPORTS_PATH = "native-reports" ;
62
68
69
+ final String processName ;
63
70
private final File filesDir ;
64
71
private final File crashlyticsDir ;
65
72
private final File sessionsDir ;
@@ -68,10 +75,12 @@ public class FileStore {
68
75
private final File nativeReportsDir ;
69
76
70
77
public FileStore (Context context ) {
78
+ processName =
79
+ ProcessDetailsProvider .INSTANCE .getCurrentProcessDetails (context ).getProcessName ();
71
80
filesDir = context .getFilesDir ();
72
81
String crashlyticsPath =
73
- useV2FileSystem ()
74
- ? CRASHLYTICS_PATH_V2 + File .pathSeparator + sanitizeName (Application . getProcessName () )
82
+ useV3FileSystem ()
83
+ ? CRASHLYTICS_PATH_V3 + File .separator + sanitizeName (processName )
75
84
: CRASHLYTICS_PATH_V1 ;
76
85
crashlyticsDir = prepareBaseDir (new File (filesDir , crashlyticsPath ));
77
86
sessionsDir = prepareBaseDir (new File (crashlyticsDir , SESSIONS_PATH ));
@@ -88,21 +97,35 @@ public void deleteAllCrashlyticsFiles() {
88
97
/** Clean up files from previous file systems. */
89
98
public void cleanupPreviousFileSystems () {
90
99
// Clean up pre-versioned file systems.
91
- cleanupDir (new File (filesDir , ".com.google.firebase.crashlytics" ));
92
- cleanupDir (new File (filesDir , ".com.google.firebase.crashlytics-ndk" ));
93
-
94
- // Clean up v1 file system.
95
- if (useV2FileSystem ()) {
96
- cleanupDir (new File (filesDir , CRASHLYTICS_PATH_V1 ));
100
+ cleanupFileSystemDir (".com.google.firebase.crashlytics" );
101
+ cleanupFileSystemDir (".com.google.firebase.crashlytics-ndk" );
102
+
103
+ // Clean up old versioned file systems.
104
+ if (useV3FileSystem ()) {
105
+ cleanupFileSystemDir (CRASHLYTICS_PATH_V1 );
106
+ // The v2 file system named dirs like ".com....v2:process_name"
107
+ cleanupFileSystemDirs (CRASHLYTICS_PATH_V2 + File .pathSeparator );
97
108
}
98
109
}
99
110
100
- private void cleanupDir (File dir ) {
111
+ private void cleanupFileSystemDir (String child ) {
112
+ File dir = new File (filesDir , child );
101
113
if (dir .exists () && recursiveDelete (dir )) {
102
114
Logger .getLogger ().d ("Deleted previous Crashlytics file system: " + dir .getPath ());
103
115
}
104
116
}
105
117
118
+ private void cleanupFileSystemDirs (String prefix ) {
119
+ if (filesDir .exists ()) {
120
+ String [] list = filesDir .list ((dir , name ) -> name .startsWith (prefix ));
121
+ if (list != null ) {
122
+ for (String child : list ) {
123
+ cleanupFileSystemDir (child );
124
+ }
125
+ }
126
+ }
127
+ }
128
+
106
129
static boolean recursiveDelete (File fileOrDirectory ) {
107
130
File [] files = fileOrDirectory .listFiles ();
108
131
if (files != null ) {
@@ -113,12 +136,16 @@ static boolean recursiveDelete(File fileOrDirectory) {
113
136
return fileOrDirectory .delete ();
114
137
}
115
138
116
- /** @return internal File used by Crashlytics, that is not specific to a session */
139
+ /**
140
+ * @return internal File used by Crashlytics, that is not specific to a session
141
+ */
117
142
public File getCommonFile (String filename ) {
118
143
return new File (crashlyticsDir , filename );
119
144
}
120
145
121
- /** @return all common (non session specific) files matching the given filter. */
146
+ /**
147
+ * @return all common (non session specific) files matching the given filter.
148
+ */
122
149
public List <File > getCommonFiles (FilenameFilter filter ) {
123
150
return safeArrayToList (crashlyticsDir .listFiles (filter ));
124
151
}
@@ -206,14 +233,21 @@ private static <T> List<T> safeArrayToList(@Nullable T[] array) {
206
233
return (array == null ) ? Collections .emptyList () : Arrays .asList (array );
207
234
}
208
235
209
- @ SuppressLint ( "AnnotateVersionCheck" )
210
- private static boolean useV2FileSystem () {
211
- return VERSION . SDK_INT >= VERSION_CODES . P ;
236
+ private boolean useV3FileSystem () {
237
+ // If the process name is known, use the v3 file system.
238
+ return ! processName . isEmpty () ;
212
239
}
213
240
214
- /** Replace potentially unsafe chars with underscores to make a safe file name. */
241
+ /**
242
+ * Replace potentially unsafe chars with underscores to make a safe file name.
243
+ *
244
+ * <p>If the filename is too long, hash it to a short name.
245
+ */
215
246
@ VisibleForTesting
216
247
static String sanitizeName (String filename ) {
248
+ if (filename .length () > 40 ) {
249
+ return CommonUtils .sha1 (filename );
250
+ }
217
251
return filename .replaceAll ("[^a-zA-Z0-9.]" , "_" );
218
252
}
219
253
}
0 commit comments