88import android .content .Intent ;
99import android .net .Uri ;
1010import android .os .Bundle ;
11+ import android .text .TextUtils ;
12+ import android .view .LayoutInflater ;
13+ import android .view .View ;
1114import android .widget .Toast ;
1215
1316import androidx .annotation .NonNull ;
1922import androidx .work .PeriodicWorkRequest ;
2023import androidx .work .WorkManager ;
2124
25+ import com .google .android .material .textfield .TextInputEditText ;
2226import com .nononsenseapps .filepicker .Utils ;
2327
28+ import net .lingala .zip4j .ZipFile ;
29+ import net .lingala .zip4j .exception .ZipException ;
30+
2431import org .schabi .newpipe .R ;
2532import org .schabi .newpipe .database .BackupRestoreHelper ;
2633import org .schabi .newpipe .report .ErrorActivity ;
3441import java .net .URLDecoder ;
3542import java .nio .charset .StandardCharsets ;
3643import java .text .SimpleDateFormat ;
44+ import java .util .Arrays ;
3745import java .util .Date ;
3846import java .util .Locale ;
3947import java .util .concurrent .TimeUnit ;
@@ -110,8 +118,7 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
110118 });
111119 autoBackupPathPreference .setSummary (backupRestoreHelper .getAutoBackupPath ());
112120
113-
114- autoBackupSwitchPreference = (SwitchPreference ) findPreference (getString (R .string .scheduled_backups_key ));
121+ autoBackupSwitchPreference = findPreference (getString (R .string .scheduled_backups_key ));
115122 autoBackupSwitchPreference .setOnPreferenceChangeListener ((preference , newValue ) -> {
116123 if ((Boolean ) newValue ) PermissionHelper .checkStoragePermissions (getActivity (), BACKUP_STORAGE_PERMISSION_REQUEST_CODE );
117124 return true ;
@@ -206,17 +213,88 @@ public void onActivityResult(int requestCode, int resultCode, @NonNull Intent da
206213 }
207214
208215 private void exportDatabase (String path ) {
209- try {
210- backupRestoreHelper .exportDatabase (path );
211- Toast .makeText (ctx , R .string .export_complete_toast , Toast .LENGTH_SHORT ).show ();
212- } catch (Exception e ) {
213- onError (e );
214- }
216+
217+ AlertDialog .Builder alert = new AlertDialog .Builder (ctx );
218+ LayoutInflater inflater = LayoutInflater .from (ctx );
219+ View view = inflater .inflate (R .layout .dialog_password , null );
220+ TextInputEditText editText = view .findViewById (android .R .id .edit );
221+ alert .setView (view );
222+ alert .setTitle (R .string .auto_backup_password_title );
223+ alert .setMessage (R .string .backup_password_message );
224+
225+ alert .setNegativeButton (R .string .backup_no_password , (dialog , which ) -> {
226+ dialog .dismiss ();
227+ try {
228+ backupRestoreHelper .exportDatabase (path , null );
229+ Toast .makeText (ctx , R .string .export_complete_toast , Toast .LENGTH_SHORT ).show ();
230+ } catch (Exception e ) {
231+ onError (e );
232+ }
233+ });
234+ alert .setPositiveButton (R .string .finish , (dialog , which ) -> {
235+ dialog .dismiss ();
236+ char [] password = getPassword (editText );
237+ try {
238+ backupRestoreHelper .exportDatabase (path , password );
239+ Toast .makeText (ctx , R .string .export_complete_toast , Toast .LENGTH_SHORT ).show ();
240+ } catch (Exception e ) {
241+ onError (e );
242+ } finally {
243+ clearPassword (password );
244+ }
245+ });
246+
247+ alert .show ();
248+ }
249+
250+ private char [] getPassword (TextInputEditText editText ) {
251+ int length = editText .length ();
252+ char [] password = new char [length ];
253+ editText .getText ().getChars (0 , length , password , 0 );
254+ return password ;
255+ }
256+
257+ private void clearPassword (char [] password ){
258+ Arrays .fill (password ,'0' );
215259 }
216260
217261 private void importDatabase (String filePath ) {
262+
263+ ZipFile zipFile = new ZipFile (filePath );
264+ if (!zipFile .isValidZipFile ()){
265+ Toast .makeText (ctx , R .string .no_valid_zip_file , Toast .LENGTH_SHORT ).show ();
266+ return ;
267+ }
268+
218269 try {
219- backupRestoreHelper .importDatabase (filePath );
270+ if (zipFile .isEncrypted ()){
271+ AlertDialog .Builder alert = new AlertDialog .Builder (ctx );
272+ LayoutInflater inflater = LayoutInflater .from (ctx );
273+ View view = inflater .inflate (R .layout .dialog_password , null );
274+ TextInputEditText editText = view .findViewById (android .R .id .edit );
275+ alert .setView (view );
276+
277+ alert .setTitle (R .string .auto_backup_password_title );
278+
279+ alert .setNegativeButton (android .R .string .no , (dialog , which ) -> {
280+ dialog .dismiss ();
281+ });
282+ alert .setPositiveButton (R .string .finish , (dialog , which ) -> {
283+ dialog .dismiss ();
284+ char [] password = getPassword (editText );
285+ try {
286+ backupRestoreHelper .importDatabase (filePath , password );
287+ } catch (Exception e ) {
288+ onError (e );
289+ } finally {
290+ clearPassword (password );
291+ }
292+ });
293+
294+ alert .show ();
295+ }else {
296+ backupRestoreHelper .importDatabase (filePath , null );
297+ }
220298 } catch (Exception e ) {
221299 onError (e );
222300 }
@@ -225,9 +303,13 @@ private void importDatabase(String filePath) {
225303 private void scheduleWork (String tag ) {
226304 Boolean autoBackup = defaultPreferences .getBoolean (getString (R .string .scheduled_backups_key ), false );
227305 if (autoBackup ){
306+ if (TextUtils .isEmpty (defaultPreferences .getString (ctx .getString (R .string .backup_password_key ), null ))){
307+ Toast .makeText (ctx , R .string .auto_backup_password_mandatory , Toast .LENGTH_LONG ).show ();
308+ }
228309 Integer interval = Integer .valueOf (defaultPreferences .getString (getString (R .string .backup_frequency_key ), "24" ));
229310 PeriodicWorkRequest .Builder autoBackupRequestBuilder =
230311 new PeriodicWorkRequest .Builder (AutoBackupWorker .class , interval , TimeUnit .HOURS );
312+ autoBackupRequestBuilder .setInitialDelay (15 , TimeUnit .MINUTES );
231313 PeriodicWorkRequest request = autoBackupRequestBuilder .build ();
232314 WorkManager .getInstance (ctx ).enqueueUniquePeriodicWork (tag , ExistingPeriodicWorkPolicy .REPLACE , request );
233315 }else {
@@ -246,12 +328,17 @@ public void onPause() {
246328 //////////////////////////////////////////////////////////////////////////*/
247329
248330 protected void onError (Throwable e ) {
249- final Activity activity = getActivity ();
250- ErrorActivity .reportError (activity , e ,
251- activity .getClass (),
252- null ,
253- ErrorActivity .ErrorInfo .make (UserAction .UI_ERROR ,
254- "none" , "" , R .string .app_ui_crash ));
331+
332+ if (e instanceof ZipException && ((ZipException )e ).getType () == ZipException .Type .WRONG_PASSWORD ){
333+ Toast .makeText (ctx , R .string .no_valid_password , Toast .LENGTH_SHORT ).show ();
334+ }else {
335+ final Activity activity = getActivity ();
336+ ErrorActivity .reportError (activity , e ,
337+ activity .getClass (),
338+ null ,
339+ ErrorActivity .ErrorInfo .make (UserAction .UI_ERROR ,
340+ "none" , "" , R .string .app_ui_crash ));
341+ }
255342 }
256343
257344}
0 commit comments