• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.ddmuilib.handler;
18 
19 import com.android.ddmlib.SyncException;
20 import com.android.ddmlib.SyncService;
21 import com.android.ddmlib.TimeoutException;
22 import com.android.ddmlib.ClientData.IHprofDumpHandler;
23 import com.android.ddmlib.ClientData.IMethodProfilingHandler;
24 import com.android.ddmlib.SyncService.ISyncProgressMonitor;
25 import com.android.ddmuilib.SyncProgressHelper;
26 import com.android.ddmuilib.SyncProgressHelper.SyncRunnable;
27 
28 import org.eclipse.jface.dialogs.MessageDialog;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.widgets.Display;
31 import org.eclipse.swt.widgets.FileDialog;
32 import org.eclipse.swt.widgets.Shell;
33 
34 import java.io.File;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.lang.reflect.InvocationTargetException;
38 
39 /**
40  * Base handler class for handler dealing with files located on a device.
41  *
42  * @see IHprofDumpHandler
43  * @see IMethodProfilingHandler
44  */
45 public abstract class BaseFileHandler {
46 
47     protected final Shell mParentShell;
48 
BaseFileHandler(Shell parentShell)49     public BaseFileHandler(Shell parentShell) {
50         mParentShell = parentShell;
51     }
52 
getDialogTitle()53     protected abstract String getDialogTitle();
54 
55     /**
56      * Prompts the user for a save location and pulls the remote files into this location.
57      * <p/>This <strong>must</strong> be called from the UI Thread.
58      * @param sync the {@link SyncService} to use to pull the file from the device
59      * @param localFileName The default local name
60      * @param remoteFilePath The name of the file to pull off of the device
61      * @param title The title of the File Save dialog.
62      * @return The result of the pull as a {@link SyncResult} object, or null if the sync
63      * didn't happen (canceled by the user).
64      * @throws InvocationTargetException
65      * @throws InterruptedException
66      * @throws SyncException if an error happens during the push of the package on the device.
67      * @throws IOException
68      */
promptAndPull(final SyncService sync, String localFileName, final String remoteFilePath, String title)69     protected void promptAndPull(final SyncService sync,
70             String localFileName, final String remoteFilePath, String title)
71             throws InvocationTargetException, InterruptedException, SyncException, TimeoutException,
72             IOException {
73         FileDialog fileDialog = new FileDialog(mParentShell, SWT.SAVE);
74 
75         fileDialog.setText(title);
76         fileDialog.setFileName(localFileName);
77 
78         final String localFilePath = fileDialog.open();
79         if (localFilePath != null) {
80             SyncProgressHelper.run(new SyncRunnable() {
81                 public void run(ISyncProgressMonitor monitor) throws SyncException, IOException,
82                         TimeoutException {
83                     sync.pullFile(remoteFilePath, localFilePath, monitor);
84                 }
85 
86                 public void close() {
87                     sync.close();
88                 }
89             },
90             String.format("Pulling %1$s from the device", remoteFilePath), mParentShell);
91         }
92     }
93 
94     /**
95      * Prompts the user for a save location and copies a temp file into it.
96      * <p/>This <strong>must</strong> be called from the UI Thread.
97      * @param localFileName The default local name
98      * @param tempFilePath The name of the temp file to copy.
99      * @param title The title of the File Save dialog.
100      * @return true if success, false on error or cancel.
101      */
promptAndSave(String localFileName, byte[] data, String title)102     protected boolean promptAndSave(String localFileName, byte[] data, String title) {
103         FileDialog fileDialog = new FileDialog(mParentShell, SWT.SAVE);
104 
105         fileDialog.setText(title);
106         fileDialog.setFileName(localFileName);
107 
108         String localFilePath = fileDialog.open();
109         if (localFilePath != null) {
110             try {
111                 saveFile(data, new File(localFilePath));
112                 return true;
113             } catch (IOException e) {
114                 String errorMsg = e.getMessage();
115                 displayErrorInUiThread(
116                         "Failed to save file '%1$s'%2$s",
117                         localFilePath,
118                         errorMsg != null ? ":\n" + errorMsg : ".");
119             }
120         }
121 
122         return false;
123     }
124 
125     /**
126      * Display an error message.
127      * <p/>This will call about to {@link Display} to run this in an async {@link Runnable} in the
128      * UI Thread. This is safe to be called from a non-UI Thread.
129      * @param format the string to display
130      * @param args the string arguments
131      */
displayErrorInUiThread(final String format, final Object... args)132     protected void displayErrorInUiThread(final String format, final Object... args) {
133         mParentShell.getDisplay().asyncExec(new Runnable() {
134             public void run() {
135                 MessageDialog.openError(mParentShell, getDialogTitle(),
136                         String.format(format, args));
137             }
138         });
139     }
140 
141     /**
142      * Display an error message.
143      * This must be called from the UI Thread.
144      * @param format the string to display
145      * @param args the string arguments
146      */
displayErrorFromUiThread(final String format, final Object... args)147     protected void displayErrorFromUiThread(final String format, final Object... args) {
148         MessageDialog.openError(mParentShell, getDialogTitle(),
149                 String.format(format, args));
150     }
151 
152     /**
153      * Saves a given data into a temp file and returns its corresponding {@link File} object.
154      * @param data the data to save
155      * @return the File into which the data was written or null if it failed.
156      * @throws IOException
157      */
saveTempFile(byte[] data, String extension)158     protected File saveTempFile(byte[] data, String extension) throws IOException {
159         File f = File.createTempFile("ddms", extension);
160         saveFile(data, f);
161         return f;
162     }
163 
164     /**
165      * Saves some data into a given File.
166      * @param data the data to save
167      * @param output the file into the data is saved.
168      * @throws IOException
169      */
saveFile(byte[] data, File output)170     protected void saveFile(byte[] data, File output) throws IOException {
171         FileOutputStream fos = null;
172         try {
173             fos = new FileOutputStream(output);
174             fos.write(data);
175         } finally {
176             if (fos != null) {
177                 fos.close();
178             }
179         }
180     }
181 }
182