Skip to content

Commit 3ac5365

Browse files
committed
Add application bootsrap files to the project template.
1 parent 75214bf commit 3ac5365

14 files changed

Lines changed: 1743 additions & 0 deletions

build/project-template-gradle/src/main/java/com/tns/Async.java

Lines changed: 414 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package com.tns;
2+
3+
import java.io.BufferedReader;
4+
import java.io.BufferedWriter;
5+
import java.io.File;
6+
import java.io.FileInputStream;
7+
import java.io.FileNotFoundException;
8+
import java.io.FileOutputStream;
9+
import java.io.IOException;
10+
import java.io.InputStreamReader;
11+
import java.io.OutputStreamWriter;
12+
13+
import android.content.Context;
14+
import android.content.pm.PackageInfo;
15+
import android.content.pm.PackageManager;
16+
17+
import com.tns.Logger;
18+
import com.tns.ExtractPolicy;
19+
import com.tns.FileExtractor;
20+
21+
public class DefaultExtractPolicy implements ExtractPolicy
22+
{
23+
private final Logger logger;
24+
25+
private final static String ASSETS_THUMB_FILENAME = "assetsThumb";
26+
27+
public DefaultExtractPolicy(Logger logger)
28+
{
29+
this.logger = logger;
30+
}
31+
32+
public boolean shouldExtract(android.content.Context context)
33+
{
34+
String assetsThumb = generateAssetsThumb(context);
35+
if (assetsThumb != null)
36+
{
37+
String assetsThumbFilePath = context.getFilesDir().getPath() + File.separatorChar + ASSETS_THUMB_FILENAME;
38+
String oldAssetsThumb = getCachedAssetsThumb(assetsThumbFilePath);
39+
if (oldAssetsThumb == null || !assetsThumb.equals(oldAssetsThumb))
40+
{
41+
saveNewAssetsThumb(assetsThumb, assetsThumbFilePath);
42+
return true;
43+
}
44+
}
45+
46+
return false;
47+
}
48+
49+
public boolean forceOverwrite()
50+
{
51+
return true;
52+
}
53+
54+
public FileExtractor extractor()
55+
{
56+
return null;
57+
}
58+
59+
private String generateAssetsThumb(Context context)
60+
{
61+
try
62+
{
63+
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
64+
int code = packageInfo.versionCode;
65+
long updateTime = packageInfo.lastUpdateTime;
66+
return String.valueOf(updateTime) + "-" + String.valueOf(code);
67+
}
68+
catch (PackageManager.NameNotFoundException e)
69+
{
70+
logger.write("Error while getting current assets thumb");
71+
e.printStackTrace();
72+
}
73+
74+
return null;
75+
}
76+
77+
private String getCachedAssetsThumb(String assetsThumbFilePath)
78+
{
79+
try
80+
{
81+
File cachedThumbFile = new File(assetsThumbFilePath);
82+
if (cachedThumbFile.exists())
83+
{
84+
FileInputStream in = new FileInputStream(cachedThumbFile);
85+
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
86+
String cachedThumb = reader.readLine();
87+
reader.close();
88+
in.close();
89+
return cachedThumb;
90+
}
91+
}
92+
catch (FileNotFoundException e)
93+
{
94+
logger.write("Error while getting current assets thumb");
95+
e.printStackTrace();
96+
}
97+
catch (IOException e)
98+
{
99+
logger.write("Error while getting current asstes thumb");
100+
e.printStackTrace();
101+
}
102+
103+
return null;
104+
}
105+
106+
private void saveNewAssetsThumb(String newThumb, String assetsThumbFile)
107+
{
108+
File cachedThumbFile = new File(assetsThumbFile);
109+
try
110+
{
111+
FileOutputStream out = new FileOutputStream(cachedThumbFile, false);
112+
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
113+
try
114+
{
115+
writer.write(newThumb);
116+
writer.newLine();
117+
writer.flush();
118+
}
119+
finally
120+
{
121+
writer.close();
122+
out.close();
123+
}
124+
}
125+
catch (FileNotFoundException e)
126+
{
127+
logger.write("Error while writting current assets thumb");
128+
e.printStackTrace();
129+
}
130+
catch (IOException e)
131+
{
132+
logger.write("Error while writting current assets thumb");
133+
e.printStackTrace();
134+
}
135+
}
136+
137+
}
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
package com.tns;
2+
3+
import java.io.ByteArrayOutputStream;
4+
import java.io.File;
5+
import java.io.IOException;
6+
import java.io.PrintStream;
7+
import java.io.UnsupportedEncodingException;
8+
9+
import android.app.Activity;
10+
import android.app.PendingIntent;
11+
import android.app.PendingIntent.CanceledException;
12+
import android.content.ClipData;
13+
import android.content.ClipboardManager;
14+
import android.content.Context;
15+
import android.content.Intent;
16+
import android.graphics.drawable.GradientDrawable;
17+
import android.text.method.ScrollingMovementMethod;
18+
import android.util.Log;
19+
import android.view.View;
20+
import android.view.View.OnClickListener;
21+
import android.widget.Button;
22+
import android.widget.LinearLayout;
23+
import android.widget.TextView;
24+
25+
class ErrorReport
26+
{
27+
public static final String ERROR_FILE_NAME = "hasError";
28+
private final Activity activity;
29+
30+
private final static String EXTRA_NATIVESCRIPT_ERROR_REPORT = "NativeScriptErrorMessage";
31+
private final static String EXTRA_ERROR_REPORT_MSG = "msg";
32+
private final static int EXTRA_ERROR_REPORT_VALUE = 1;
33+
34+
public ErrorReport(Activity activity)
35+
{
36+
this.activity = activity;
37+
}
38+
39+
static boolean startActivity(final Context context, String errorMessage)
40+
{
41+
final Intent intent = getIntent(context);
42+
if (intent == null)
43+
{
44+
return false; // (if in release mode) don't do anything
45+
}
46+
47+
intent.putExtra(EXTRA_ERROR_REPORT_MSG, errorMessage);
48+
49+
createErrorFile(context);
50+
51+
try
52+
{
53+
startPendingErrorActivity(context, intent);
54+
}
55+
catch (CanceledException e)
56+
{
57+
Log.d("ErrorReport", "Couldn't send pending intent! Exception: " + e.getMessage());
58+
}
59+
60+
killProcess(context);
61+
62+
return true;
63+
}
64+
65+
static void killProcess(Context context)
66+
{
67+
// finish current activity and all below it first
68+
if (context instanceof Activity)
69+
{
70+
((Activity) context).finishAffinity();
71+
}
72+
73+
// kill process
74+
android.os.Process.killProcess(android.os.Process.myPid());
75+
}
76+
77+
static void startPendingErrorActivity(Context context, Intent intent) throws CanceledException
78+
{
79+
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
80+
81+
pendingIntent.send(context, 0, intent);
82+
}
83+
84+
static String getErrorMessage(Throwable ex)
85+
{
86+
String content;
87+
PrintStream ps = null;
88+
89+
try
90+
{
91+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
92+
ps = new PrintStream(baos);
93+
ex.printStackTrace(ps);
94+
95+
try
96+
{
97+
content = baos.toString("US-ASCII");
98+
}
99+
catch (UnsupportedEncodingException e)
100+
{
101+
content = e.getMessage();
102+
}
103+
}
104+
finally
105+
{
106+
if (ps != null)
107+
ps.close();
108+
}
109+
110+
return content;
111+
}
112+
113+
static Intent getIntent(Context context)
114+
{
115+
Class<?> errorActivityClass = Platform.getErrorActivityClass(); // can be null or can be provided beforehand
116+
117+
// if in debug and errorActivityClass is not provided use ErrorReportActivity class
118+
if (errorActivityClass == null && JsDebugger.isDebuggableApp(context))
119+
{
120+
errorActivityClass = ErrorReportActivity.class;
121+
}
122+
123+
// if not in debug mode should return null and use the errorActivityClass implementation provided
124+
if (errorActivityClass == null)
125+
{
126+
return null;
127+
}
128+
129+
Intent intent = new Intent(context, errorActivityClass);
130+
131+
intent.putExtra(EXTRA_NATIVESCRIPT_ERROR_REPORT, EXTRA_ERROR_REPORT_VALUE);
132+
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
133+
134+
return intent;
135+
}
136+
137+
static boolean hasIntent(Intent intent)
138+
{
139+
int value = intent.getIntExtra(EXTRA_NATIVESCRIPT_ERROR_REPORT, 0);
140+
141+
return value == EXTRA_ERROR_REPORT_VALUE;
142+
}
143+
144+
void buildUI()
145+
{
146+
Context context = activity;
147+
Intent intent = activity.getIntent();
148+
final String msg = intent.getStringExtra(EXTRA_ERROR_REPORT_MSG);
149+
150+
// container
151+
LinearLayout layout = new LinearLayout(context);
152+
layout.setOrientation(LinearLayout.VERTICAL);
153+
activity.setContentView(layout);
154+
155+
// header
156+
TextView txtHeader = new TextView(context);
157+
txtHeader.setText("Unhandled Exception");
158+
159+
// error + stacktrace
160+
TextView txtErrorMsg = new TextView(context);
161+
txtErrorMsg.setText(msg);
162+
txtErrorMsg.setHeight(1000);
163+
txtErrorMsg.setMovementMethod(new ScrollingMovementMethod());
164+
165+
// copy button
166+
Button copyToClipboard = new Button(context);
167+
copyToClipboard.setText("Copy to clipboard");
168+
copyToClipboard.setOnClickListener(new OnClickListener()
169+
{
170+
@Override
171+
public void onClick(View v)
172+
{
173+
174+
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
175+
ClipData clip = ClipData.newPlainText("nsError", msg);
176+
clipboard.setPrimaryClip(clip);
177+
}
178+
});
179+
180+
layout.addView(txtHeader);
181+
layout.addView(txtErrorMsg);
182+
layout.addView(copyToClipboard);
183+
}
184+
185+
private static void createErrorFile(final Context context)
186+
{
187+
try
188+
{
189+
File errFile = new File(context.getFilesDir(), ERROR_FILE_NAME);
190+
errFile.createNewFile();
191+
}
192+
catch (IOException e)
193+
{
194+
Log.d("ErrorReport", e.getMessage());
195+
}
196+
}
197+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.tns;
2+
3+
import android.app.Activity;
4+
import android.os.Bundle;
5+
6+
public class ErrorReportActivity extends Activity
7+
{
8+
public void onCreate(Bundle savedInstanceState)
9+
{
10+
super.onCreate(savedInstanceState);
11+
new ErrorReport(this).buildUI();
12+
}
13+
14+
@Override
15+
protected void onPause()
16+
{
17+
// the moment the error activity is not in the foreground we want to kill the process
18+
super.onPause();
19+
ErrorReport.killProcess(this);
20+
}
21+
}

0 commit comments

Comments
 (0)