• 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.ClientData.IHprofDumpHandler;
20 import com.android.ddmlib.ClientData.IMethodProfilingHandler;
21 import com.android.ddmlib.SyncException;
22 import com.android.ddmlib.SyncService;
23 import com.android.ddmlib.SyncService.ISyncProgressMonitor;
24 import com.android.ddmlib.TimeoutException;
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                 @Override
82                 public void run(ISyncProgressMonitor monitor) throws SyncException, IOException,
83                         TimeoutException {
84                     sync.pullFile(remoteFilePath, localFilePath, monitor);
85                 }
86 
87                 @Override
88                 public void close() {
89                     sync.close();
90                 }
91             },
92             String.format("Pulling %1$s from the device", remoteFilePath), mParentShell);
93         }
94     }
95 
96     /**
97      * Prompts the user for a save location and copies a temp file into it.
98      * <p/>This <strong>must</strong> be called from the UI Thread.
99      * @param localFileName The default local name
100      * @param tempFilePath The name of the temp file to copy.
101      * @param title The title of the File Save dialog.
102      * @return true if success, false on error or cancel.
103      */
promptAndSave(String localFileName, byte[] data, String title)104     protected boolean promptAndSave(String localFileName, byte[] data, String title) {
105         FileDialog fileDialog = new FileDialog(mParentShell, SWT.SAVE);
106 
107         fileDialog.setText(title);
108         fileDialog.setFileName(localFileName);
109 
110         String localFilePath = fileDialog.open();
111         if (localFilePath != null) {
112             try {
113                 saveFile(data, new File(localFilePath));
114                 return true;
115             } catch (IOException e) {
116                 String errorMsg = e.getMessage();
117                 displayErrorInUiThread(
118                         "Failed to save file '%1$s'%2$s",
119                         localFilePath,
120                         errorMsg != null ? ":\n" + errorMsg : ".");
121             }
122         }
123 
124         return false;
125     }
126 
127     /**
128      * Display an error message.
129      * <p/>This will call about to {@link Display} to run this in an async {@link Runnable} in the
130      * UI Thread. This is safe to be called from a non-UI Thread.
131      * @param format the string to display
132      * @param args the string arguments
133      */
displayErrorInUiThread(final String format, final Object... args)134     protected void displayErrorInUiThread(final String format, final Object... args) {
135         mParentShell.getDisplay().asyncExec(new Runnable() {
136             @Override
137             public void run() {
138                 MessageDialog.openError(mParentShell, getDialogTitle(),
139                         String.format(format, args));
140             }
141         });
142     }
143 
144     /**
145      * Display an error message.
146      * This must be called from the UI Thread.
147      * @param format the string to display
148      * @param args the string arguments
149      */
displayErrorFromUiThread(final String format, final Object... args)150     protected void displayErrorFromUiThread(final String format, final Object... args) {
151         MessageDialog.openError(mParentShell, getDialogTitle(),
152                 String.format(format, args));
153     }
154 
155     /**
156      * Saves a given data into a temp file and returns its corresponding {@link File} object.
157      * @param data the data to save
158      * @return the File into which the data was written or null if it failed.
159      * @throws IOException
160      */
saveTempFile(byte[] data, String extension)161     protected File saveTempFile(byte[] data, String extension) throws IOException {
162         File f = File.createTempFile("ddms", extension);
163         saveFile(data, f);
164         return f;
165     }
166 
167     /**
168      * Saves some data into a given File.
169      * @param data the data to save
170      * @param output the file into the data is saved.
171      * @throws IOException
172      */
saveFile(byte[] data, File output)173     protected void saveFile(byte[] data, File output) throws IOException {
174         FileOutputStream fos = null;
175         try {
176             fos = new FileOutputStream(output);
177             fos.write(data);
178         } finally {
179             if (fos != null) {
180                 fos.close();
181             }
182         }
183     }
184 }
185