2  *   ownCloud Android client application 
   4  *   Copyright (C) 2015 ownCloud Inc. 
   6  *   This program is free software: you can redistribute it and/or modify 
   7  *   it under the terms of the GNU General Public License version 2, 
   8  *   as published by the Free Software Foundation. 
  10  *   This program is distributed in the hope that it will be useful, 
  11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
  12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  13  *   GNU General Public License for more details. 
  15  *   You should have received a copy of the GNU General Public License 
  16  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
  20 package com
.owncloud
.android
.ui
.activity
; 
  22 import java
.io
.BufferedReader
; 
  24 import java
.io
.FileReader
; 
  25 import java
.io
.IOException
; 
  26 import java
.lang
.ref
.WeakReference
; 
  27 import java
.lang
.reflect
.Field
; 
  28 import java
.util
.ArrayList
; 
  30 import android
.content
.ActivityNotFoundException
; 
  31 import android
.content
.Intent
; 
  32 import android
.net
.Uri
; 
  33 import android
.os
.AsyncTask
; 
  34 import android
.os
.Bundle
; 
  35 import android
.support
.v4
.app
.Fragment
; 
  36 import android
.support
.v4
.app
.FragmentManager
; 
  37 import android
.support
.v4
.app
.FragmentTransaction
; 
  38 import android
.support
.v7
.app
.ActionBar
; 
  39 import android
.support
.v7
.app
.AppCompatActivity
; 
  40 import android
.view
.MenuItem
; 
  41 import android
.view
.View
; 
  42 import android
.view
.View
.OnClickListener
; 
  43 import android
.widget
.Button
; 
  44 import android
.widget
.TextView
; 
  45 import android
.widget
.Toast
; 
  47 import com
.owncloud
.android
.R
; 
  48 import com
.owncloud
.android
.lib
.common
.utils
.Log_OC
; 
  49 import com
.owncloud
.android
.ui
.dialog
.LoadingDialog
; 
  50 import com
.owncloud
.android
.utils
.DisplayUtils
; 
  51 import com
.owncloud
.android
.utils
.FileStorageUtils
; 
  54 public class LogHistoryActivity 
extends AppCompatActivity 
{ 
  56     private static final String MAIL_ATTACHMENT_TYPE 
= "text/plain"; 
  58     private static final String KEY_LOG_TEXT 
= "LOG_TEXT"; 
  60     private static final String TAG 
= LogHistoryActivity
.class.getSimpleName(); 
  62     private static final String DIALOG_WAIT_TAG 
= "DIALOG_WAIT"; 
  64     private String mLogPath 
= FileStorageUtils
.getLogPath(); 
  65     private File logDIR 
= null
; 
  66     private String mLogText
; 
  70     protected void onCreate(Bundle savedInstanceState
) { 
  71         super.onCreate(savedInstanceState
); 
  73         setContentView(R
.layout
.log_send_file
); 
  74         setTitle(getText(R
.string
.actionbar_logger
)); 
  75         ActionBar actionBar 
= getSupportActionBar(); 
  76         actionBar
.setIcon(DisplayUtils
.getSeasonalIconId()); 
  77         actionBar
.setDisplayHomeAsUpEnabled(true
); 
  78         Button deleteHistoryButton 
= (Button
) findViewById(R
.id
.deleteLogHistoryButton
); 
  79         Button sendHistoryButton 
= (Button
) findViewById(R
.id
.sendLogHistoryButton
); 
  80         TextView logTV 
= (TextView
) findViewById(R
.id
.logTV
); 
  82         deleteHistoryButton
.setOnClickListener(new OnClickListener() { 
  85             public void onClick(View v
) { 
  87                 Log_OC
.deleteHistoryLogging(); 
  92         sendHistoryButton
.setOnClickListener(new OnClickListener() { 
  95             public void onClick(View v
) { 
 100         if (savedInstanceState 
== null
) { 
 101             if (mLogPath 
!= null
) { 
 102                 logDIR 
= new File(mLogPath
); 
 105             if (logDIR 
!= null 
&& logDIR
.isDirectory()) { 
 106                 // Show a dialog while log data is being loaded 
 109                 // Start a new thread that will load all the log data 
 110                 LoadingLogTask task 
= new LoadingLogTask(logTV
); 
 114             mLogText 
= savedInstanceState
.getString(KEY_LOG_TEXT
); 
 115             logTV
.setText(mLogText
); 
 120     public boolean onOptionsItemSelected(MenuItem item
) { 
 121         super.onOptionsItemSelected(item
); 
 122         switch (item
.getItemId()) { 
 123             case android
.R
.id
.home
: 
 134      * Start activity for sending email with logs attached 
 136     private void sendMail() { 
 138         // For the moment we need to consider the possibility that setup.xml 
 139         // does not include the "mail_logger" entry. This block prevents that 
 140         // compilation fails in this case. 
 143             Class
<?
> stringClass 
= R
.string
.class; 
 144             Field mailLoggerField 
= stringClass
.getField("mail_logger"); 
 145             int emailAddressId 
= (Integer
) mailLoggerField
.get(null
); 
 146             emailAddress 
= getString(emailAddressId
); 
 147         } catch (Exception e
) { 
 151         ArrayList
<Uri
> uris 
= new ArrayList
<Uri
>(); 
 153         // Convert from paths to Android friendly Parcelable Uri's 
 154         for (String file 
: Log_OC
.getLogFileNames()) 
 156             File logFile 
= new File(mLogPath
, file
); 
 157             if (logFile
.exists()) { 
 158                 uris
.add(Uri
.fromFile(logFile
)); 
 162         Intent intent 
= new Intent(Intent
.ACTION_SEND_MULTIPLE
); 
 164         intent
.putExtra(Intent
.EXTRA_EMAIL
, emailAddress
); 
 165         String subject 
= String
.format(getString(R
.string
.log_send_mail_subject
), getString(R
.string
.app_name
)); 
 166         intent
.putExtra(Intent
.EXTRA_SUBJECT
, subject
); 
 167         intent
.setFlags(Intent
.FLAG_ACTIVITY_NEW_TASK
); 
 168         intent
.setType(MAIL_ATTACHMENT_TYPE
); 
 169         intent
.putParcelableArrayListExtra(Intent
.EXTRA_STREAM
, uris
); 
 171             startActivity(intent
); 
 172         } catch (ActivityNotFoundException e
) { 
 173             Toast
.makeText(this, getString(R
.string
.log_send_no_mail_app
), Toast
.LENGTH_LONG
).show(); 
 174             Log_OC
.i(TAG
, "Could not find app for sending log history."); 
 181      * Class for loading the log data async 
 184     private class LoadingLogTask 
extends AsyncTask
<String
, Void
, String
> { 
 185         private final WeakReference
<TextView
> textViewReference
; 
 187         public LoadingLogTask(TextView logTV
){ 
 188             // Use of a WeakReference to ensure the TextView can be garbage collected 
 189             textViewReference  
= new WeakReference
<TextView
>(logTV
); 
 192         protected String 
doInBackground(String
... args
) { 
 193             return readLogFile(); 
 196         protected void onPostExecute(String result
) { 
 197             if (textViewReference 
!= null 
&& result 
!= null
) { 
 198                 final TextView logTV 
= textViewReference
.get(); 
 201                     logTV
.setText(mLogText
); 
 202                     dismissLoadingDialog(); 
 208          * Read and show log file info 
 210         private String 
readLogFile() { 
 212             String
[] logFileName 
= Log_OC
.getLogFileNames(); 
 214             //Read text from files 
 215             StringBuilder text 
= new StringBuilder(); 
 217             BufferedReader br 
= null
; 
 221                 for (int i 
= logFileName
.length
-1; i 
>= 0; i
--) { 
 222                     File file 
= new File(mLogPath
,logFileName
[i
]); 
 224                         // Check if FileReader is ready 
 225                         if (new FileReader(file
).ready()) { 
 226                             br 
= new BufferedReader(new FileReader(file
)); 
 227                             while ((line 
= br
.readLine()) != null
) { 
 228                                 // Append the log info 
 236             catch (IOException e
) { 
 237                 Log_OC
.d(TAG
, e
.getMessage().toString()); 
 243                     } catch (IOException e
) { 
 249             return text
.toString(); 
 254      * Show loading dialog 
 256     public void showLoadingDialog() { 
 258         LoadingDialog loading 
= new LoadingDialog( 
 259                 getResources().getString(R
.string
.log_progress_dialog_text
) 
 261         FragmentManager fm 
= getSupportFragmentManager(); 
 262         FragmentTransaction ft 
= fm
.beginTransaction(); 
 263         loading
.show(ft
, DIALOG_WAIT_TAG
); 
 267      * Dismiss loading dialog 
 269     public void dismissLoadingDialog(){ 
 270         Fragment frag 
= getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG
); 
 272             LoadingDialog loading 
= (LoadingDialog
) frag
; 
 278     protected void onSaveInstanceState(Bundle outState
) { 
 279         super.onSaveInstanceState(outState
); 
 282         outState
.putString(KEY_LOG_TEXT
, mLogText
);