Merge inbound to m-c a=merge
2
CLOBBER
|
@ -22,4 +22,4 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1253431 - Testing to see if a clobber fixes OSX debug build issues
|
||||
Bug 1223729 - Touching CLOBBER for moving files under dom/bluetooth/common
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "nsEventShell.h"
|
||||
#include "nsTextEquivUtils.h"
|
||||
#include "DocAccessibleChild.h"
|
||||
#include "Logging.h"
|
||||
#include "Relation.h"
|
||||
#include "Role.h"
|
||||
#include "RootAccessible.h"
|
||||
|
@ -1960,18 +1959,7 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
|
|||
|
||||
if (mParent) {
|
||||
if (mParent != aParent) {
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eTree)) {
|
||||
logging::MsgBegin("TREE", "BindToParent: stealing accessible");
|
||||
logging::AccessibleInfo("old parent", mParent);
|
||||
logging::AccessibleInfo("new parent", aParent);
|
||||
logging::AccessibleInfo("child", this);
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
// XXX: legalize adoption. As long as we don't invalidate the children,
|
||||
// the accessibles start to steal them.
|
||||
|
||||
NS_ERROR("Adopting child!");
|
||||
mParent->InvalidateChildrenGroupInfo();
|
||||
mParent->RemoveChild(this);
|
||||
} else {
|
||||
|
|
|
@ -394,14 +394,6 @@ public:
|
|||
bool AppendChild(Accessible* aChild)
|
||||
{ return InsertChildAt(mChildren.Length(), aChild); }
|
||||
virtual bool InsertChildAt(uint32_t aIndex, Accessible* aChild);
|
||||
|
||||
bool InsertAfter(Accessible* aNewChild, Accessible* aRefChild)
|
||||
{
|
||||
MOZ_ASSERT(aNewChild, "No new child to insert");
|
||||
return InsertChildAt(aRefChild ? aRefChild->IndexInParent() + 1 : 0,
|
||||
aNewChild);
|
||||
}
|
||||
|
||||
virtual bool RemoveChild(Accessible* aChild);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1391,21 +1391,8 @@ DocAccessible::ProcessInvalidationList()
|
|||
nsIContent* content = mInvalidationList[idx];
|
||||
if (!HasAccessible(content)) {
|
||||
Accessible* container = GetContainerAccessible(content);
|
||||
if (container) {
|
||||
TreeWalker walker(container);
|
||||
if (container->IsAcceptableChild(content) && walker.Seek(content)) {
|
||||
Accessible* child =
|
||||
GetAccService()->GetOrCreateAccessible(content, container);
|
||||
if (child) {
|
||||
AutoTreeMutation mMut(container);
|
||||
RefPtr<AccReorderEvent> reorderEvent =
|
||||
new AccReorderEvent(container);
|
||||
container->InsertAfter(child, walker.Prev());
|
||||
uint32_t flags = UpdateTreeInternal(child, true, reorderEvent);
|
||||
FireEventsOnInsertion(container, reorderEvent, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (container)
|
||||
UpdateTreeOnInsertion(container);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1683,195 +1670,45 @@ DocAccessible::UpdateAccessibleOnAttrChange(dom::Element* aElement,
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content insertion helper.
|
||||
*/
|
||||
class InsertIterator final
|
||||
{
|
||||
public:
|
||||
InsertIterator(Accessible* aContext,
|
||||
const nsTArray<nsCOMPtr<nsIContent> >* aNodes) :
|
||||
mChild(nullptr), mChildBefore(nullptr), mWalker(aContext),
|
||||
mStopNode(nullptr), mNodes(aNodes), mNodesIdx(0)
|
||||
{
|
||||
MOZ_ASSERT(aContext, "No context");
|
||||
MOZ_ASSERT(aNodes, "No nodes to search for accessible elements");
|
||||
MOZ_COUNT_CTOR(InsertIterator);
|
||||
}
|
||||
~InsertIterator() { MOZ_COUNT_DTOR(InsertIterator); }
|
||||
|
||||
Accessible* Context() const { return mWalker.Context(); }
|
||||
Accessible* Child() const { return mChild; }
|
||||
Accessible* ChildBefore() const { return mChildBefore; }
|
||||
DocAccessible* Document() const { return mWalker.Document(); }
|
||||
|
||||
/**
|
||||
* Iterates to a next accessible within the inserted content.
|
||||
*/
|
||||
bool Next();
|
||||
|
||||
private:
|
||||
Accessible* mChild;
|
||||
Accessible* mChildBefore;
|
||||
TreeWalker mWalker;
|
||||
nsIContent* mStopNode;
|
||||
|
||||
const nsTArray<nsCOMPtr<nsIContent> >* mNodes;
|
||||
uint32_t mNodesIdx;
|
||||
};
|
||||
|
||||
bool
|
||||
InsertIterator::Next()
|
||||
{
|
||||
if (mNodesIdx > 0) {
|
||||
Accessible* nextChild = mWalker.Next(mStopNode);
|
||||
if (nextChild) {
|
||||
mChildBefore = mChild;
|
||||
mChild = nextChild;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
while (mNodesIdx < mNodes->Length()) {
|
||||
// Ignore nodes that are not contained by the container anymore.
|
||||
|
||||
// The container might be changed, for example, because of the subsequent
|
||||
// overlapping content insertion (i.e. other content was inserted between
|
||||
// this inserted content and its container or the content was reinserted
|
||||
// into different container of unrelated part of tree). To avoid a double
|
||||
// processing of the content insertion ignore this insertion notification.
|
||||
// Note, the inserted content might be not in tree at all at this point
|
||||
// what means there's no container. Ignore the insertion too.
|
||||
nsIContent* prevNode = mNodes->SafeElementAt(mNodesIdx - 1);
|
||||
nsIContent* node = mNodes->ElementAt(mNodesIdx++);
|
||||
Accessible* container = Document()->GetContainerAccessible(node);
|
||||
if (container != Context() || !container->IsAcceptableChild(node)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("traversing an inserted node", logging::eVerbose,
|
||||
"container", container, "node", node);
|
||||
#endif
|
||||
|
||||
// If inserted nodes are siblings then just move the walker next.
|
||||
if (prevNode && prevNode->GetNextSibling() == node) {
|
||||
mStopNode = node;
|
||||
Accessible* nextChild = mWalker.Next(mStopNode);
|
||||
if (nextChild) {
|
||||
mChildBefore = mChild;
|
||||
mChild = nextChild;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (mWalker.Seek(node)) {
|
||||
mStopNode = node;
|
||||
mChildBefore = mWalker.Prev();
|
||||
mChild = mWalker.Next(mStopNode);
|
||||
if (mChild) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::ProcessContentInserted(Accessible* aContainer,
|
||||
const nsTArray<nsCOMPtr<nsIContent> >* aNodes)
|
||||
const nsTArray<nsCOMPtr<nsIContent> >* aInsertedContent)
|
||||
{
|
||||
// Process insertions if the container accessible is still in tree.
|
||||
if (!HasAccessible(aContainer->GetNode()))
|
||||
return;
|
||||
|
||||
// If new root content has been inserted then update it.
|
||||
if (aContainer == this) {
|
||||
UpdateRootElIfNeeded();
|
||||
}
|
||||
for (uint32_t idx = 0; idx < aInsertedContent->Length(); idx++) {
|
||||
// The container might be changed, for example, because of the subsequent
|
||||
// overlapping content insertion (i.e. other content was inserted between
|
||||
// this inserted content and its container or the content was reinserted
|
||||
// into different container of unrelated part of tree). To avoid a double
|
||||
// processing of the content insertion ignore this insertion notification.
|
||||
// Note, the inserted content might be not in tree at all at this point what
|
||||
// means there's no container. Ignore the insertion too.
|
||||
|
||||
uint32_t updateFlags = 0;
|
||||
AutoTreeMutation mut(aContainer);
|
||||
RefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aContainer);
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("children before insertion", logging::eVerbose,
|
||||
aContainer);
|
||||
#endif
|
||||
|
||||
InsertIterator iter(aContainer, aNodes);
|
||||
while (iter.Next()) {
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("accessible is found", logging::eVerbose,
|
||||
"container", aContainer, "child", iter.Child(), nullptr);
|
||||
#endif
|
||||
|
||||
Accessible* parent = iter.Child()->Parent();
|
||||
if (parent) {
|
||||
if (parent != aContainer) {
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("stealing accessible", 0,
|
||||
"old parent", parent, "new parent",
|
||||
aContainer, "child", iter.Child(), nullptr);
|
||||
#endif
|
||||
MOZ_ASSERT_UNREACHABLE("stealing accessible");
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("binding to same parent", logging::eVerbose,
|
||||
"parent", aContainer, "child", iter.Child(), nullptr);
|
||||
#endif
|
||||
Accessible* container =
|
||||
GetContainerAccessible(aInsertedContent->ElementAt(idx));
|
||||
if (container != aContainer)
|
||||
continue;
|
||||
|
||||
if (container == this) {
|
||||
// If new root content has been inserted then update it.
|
||||
UpdateRootElIfNeeded();
|
||||
|
||||
// Continue to update the tree even if we don't have root content.
|
||||
// For example, elements may be inserted under the document element while
|
||||
// there is no HTML body element.
|
||||
}
|
||||
|
||||
if (aContainer->InsertAfter(iter.Child(), iter.ChildBefore())) {
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("accessible was accepted", 0,
|
||||
"container", aContainer, "child", iter.Child(), nullptr);
|
||||
#endif
|
||||
|
||||
updateFlags |= UpdateTreeInternal(iter.Child(), true, reorderEvent);
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_UNREACHABLE("accessible was rejected");
|
||||
// We have a DOM/layout change under the container accessible, and its tree
|
||||
// might need an update. Since DOM/layout change of the element may affect
|
||||
// on the accessibleness of adjacent elements (for example, insertion of
|
||||
// extra HTML:body make the old body accessible) then we have to recache
|
||||
// children of the container, and then fire show/hide events for a change.
|
||||
UpdateTreeOnInsertion(container);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("children after insertion", logging::eVerbose,
|
||||
aContainer);
|
||||
#endif
|
||||
|
||||
FireEventsOnInsertion(aContainer, reorderEvent, updateFlags);
|
||||
}
|
||||
|
||||
void
|
||||
DocAccessible::FireEventsOnInsertion(Accessible* aContainer,
|
||||
AccReorderEvent* aReorderEvent,
|
||||
uint32_t aUpdateFlags)
|
||||
{
|
||||
// Content insertion did not cause an accessible tree change.
|
||||
if (aUpdateFlags == eNoAccessible) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check to see if change occurred inside an alert, and fire an EVENT_ALERT
|
||||
// if it did.
|
||||
if (!(aUpdateFlags & eAlertAccessible) &&
|
||||
(aContainer->IsAlert() || aContainer->IsInsideAlert())) {
|
||||
Accessible* ancestor = aContainer;
|
||||
do {
|
||||
if (ancestor->IsAlert()) {
|
||||
FireDelayedEvent(nsIAccessibleEvent::EVENT_ALERT, ancestor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ((ancestor = ancestor->Parent()));
|
||||
}
|
||||
|
||||
MaybeNotifyOfValueChange(aContainer);
|
||||
FireDelayedEvent(aReorderEvent);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2419,3 +2256,4 @@ DocAccessible::IsLoadEventTarget() const
|
|||
// It's content (not chrome) root document.
|
||||
return (treeItem->ItemType() == nsIDocShellTreeItem::typeContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,9 +187,6 @@ public:
|
|||
*/
|
||||
void FireDelayedEvent(AccEvent* aEvent);
|
||||
void FireDelayedEvent(uint32_t aEventType, Accessible* aTarget);
|
||||
void FireEventsOnInsertion(Accessible* aContainer,
|
||||
AccReorderEvent* aReorderEvent,
|
||||
uint32_t aUpdateFlags);
|
||||
|
||||
/**
|
||||
* Fire value change event on the given accessible if applicable.
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree,verbose"); // debug
|
||||
|
||||
if (navigator.platform.startsWith("Mac")) {
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
} else {
|
||||
|
|
|
@ -55,8 +55,7 @@
|
|||
}
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree");
|
||||
gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree,verbose");
|
||||
function doPreTest()
|
||||
{
|
||||
var tabDocument = currentTabDocument();
|
||||
|
|
|
@ -296,8 +296,6 @@ function editableTextTest(aID)
|
|||
invoke: aInvokeFunc,
|
||||
finalCheck: function finalCheck()
|
||||
{
|
||||
//dumpTree(aID, `'${aID}' tree:`);
|
||||
|
||||
aChecker.check();
|
||||
et.unwrapNextTest(); // replace dummy invoker on real invoker object.
|
||||
},
|
||||
|
|
|
@ -19,8 +19,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452161
|
|||
src="editabletext.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree,verbose"); // debug
|
||||
|
||||
function addTestEditable(aID, aTestRun, aBeforeContent, aAfterContent)
|
||||
{
|
||||
|
|
|
@ -328,7 +328,6 @@
|
|||
|
||||
var gQueue = null;
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
//enableLogging("tree");
|
||||
|
||||
function doTests()
|
||||
{
|
||||
|
|
|
@ -414,13 +414,11 @@
|
|||
return aNode.parentNode;
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
//enableLogging("tree,verbose");
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
function doTests()
|
||||
{
|
||||
|
@ -571,5 +569,6 @@
|
|||
<div style="visibility:hidden" id="c4_middle">
|
||||
<div style="visibility:visible" id="c4_child"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug
|
||||
//enableLogging("tree,verbose");
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
|
@ -55,7 +55,7 @@
|
|||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=723833"
|
||||
title="IAccessibleText::setCaretOffset on location or search bar causes focus to jump">
|
||||
Bug 723833
|
||||
Mozilla Bug 723833
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
@ -63,5 +63,7 @@
|
|||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="eventdump"></vbox>
|
||||
</vbox>
|
||||
</window>
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree,verbose");
|
||||
function doTest()
|
||||
{
|
||||
var tree =
|
||||
|
|
|
@ -201,9 +201,6 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree,verbose,stack");
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree,verbose"); // debug stuff
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
|
@ -163,7 +160,6 @@
|
|||
SimpleTest.ok(true, "Testing (New) Toolkit autocomplete widget.");
|
||||
|
||||
// Dumb access to trigger popup lazy creation.
|
||||
dump("Trigget popup lazy creation");
|
||||
waitForEvent(EVENT_REORDER, txc, test_AutocompleteControl);
|
||||
txc.popup;
|
||||
|
||||
|
|
|
@ -72,7 +72,6 @@
|
|||
|
||||
function doTest()
|
||||
{
|
||||
//enableLogging("tree");
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// make the accessible an inaccessible
|
||||
|
|
|
@ -194,8 +194,8 @@
|
|||
// newly inserted child.
|
||||
var tree =
|
||||
{ SECTION: [
|
||||
{ CHECKBUTTON: [ ] }, // existing explicit, t1_checkbox
|
||||
{ RADIOBUTTON: [ ] }, // new explicit, t1_child3
|
||||
{ CHECKBUTTON: [ ] },
|
||||
{ RADIOBUTTON: [ ] },
|
||||
{ PUSHBUTTON: [ ] }, // ARIA owned, t1_button
|
||||
{ SECTION: [ ] }, // ARIA owned, t1_subdiv
|
||||
{ GROUPING: [ ] } // ARIA owned, t1_group
|
||||
|
@ -228,8 +228,8 @@
|
|||
// subdiv should go away
|
||||
var tree =
|
||||
{ SECTION: [
|
||||
{ CHECKBUTTON: [ ] }, // explicit, t1_checkbox
|
||||
{ RADIOBUTTON: [ ] }, // explicit, t1_child3
|
||||
{ CHECKBUTTON: [ ] },
|
||||
{ RADIOBUTTON: [ ] },
|
||||
{ PUSHBUTTON: [ ] }, // ARIA owned, t1_button
|
||||
{ GROUPING: [ ] } // ARIA owned, t1_group
|
||||
] };
|
||||
|
|
|
@ -117,8 +117,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
//enableLogging("tree,verbose");
|
||||
|
||||
var gQueue = null;
|
||||
var gContextTree = {};
|
||||
|
@ -312,6 +312,8 @@
|
|||
</menupopup>
|
||||
|
||||
<button context="context" id="button">btn</button>
|
||||
|
||||
<vbox id="eventdump" role="log"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"extensions.blocklist.url": "http://localhost/extensions-dummy/blocklistURL",
|
||||
"extensions.webservice.discoverURL": "http://localhost/extensions-dummy/discoveryURL",
|
||||
"extensions.getAddons.maxResults": 0,
|
||||
"services.kinto.base": "http://localhost/dummy-kinto/v1",
|
||||
"geo.wifi.uri": "http://localhost/location-dummy/locationURL",
|
||||
"browser.search.geoip.url": "http://localhost/location-dummy/locationURL",
|
||||
"browser.search.isUS": true,
|
||||
|
|
|
@ -64,10 +64,18 @@ pref("extensions.blocklist.itemURL", "https://blocklist.addons.mozilla.org/%LOCA
|
|||
|
||||
// Kinto blocklist preferences
|
||||
pref("services.kinto.base", "https://firefox.settings.services.mozilla.com/v1");
|
||||
pref("services.kinto.changes.path", "/buckets/monitor/collections/changes/records");
|
||||
pref("services.kinto.bucket", "blocklists");
|
||||
pref("services.kinto.onecrl.collection", "certificates");
|
||||
pref("services.kinto.onecrl.checked", 0);
|
||||
|
||||
// for now, let's keep kinto update out of the release channel
|
||||
#ifdef RELEASE_BUILD
|
||||
pref("services.kinto.update_enabled", false);
|
||||
#else
|
||||
pref("services.kinto.update_enabled", true);
|
||||
#endif
|
||||
|
||||
pref("extensions.update.autoUpdateDefault", true);
|
||||
|
||||
pref("extensions.hotfix.id", "firefox-hotfix@mozilla.org");
|
||||
|
|
|
@ -23,9 +23,14 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
|||
|
||||
const COLLECT_RESULTS_AFTER_MS = 10000;
|
||||
|
||||
const TOPICS = ["sessionstore-restoring-on-startup", "sessionstore-initiating-manual-restore"];
|
||||
const OBSERVED_TOPICS = ["sessionstore-restoring-on-startup", "sessionstore-initiating-manual-restore"];
|
||||
|
||||
this.StartupPerformance = {
|
||||
/**
|
||||
* Once we have finished restoring initial tabs, we broadcast on this topic.
|
||||
*/
|
||||
RESTORED_TOPIC: "sessionstore-finished-restoring-initial-tabs",
|
||||
|
||||
// Instant at which we have started restoration (notification "sessionstore-restoring-on-startup")
|
||||
_startTimeStamp: null,
|
||||
|
||||
|
@ -44,22 +49,42 @@ this.StartupPerformance = {
|
|||
// `true` once the timer has fired
|
||||
_hasFired: false,
|
||||
|
||||
// `true` once we are restored
|
||||
_isRestored: false,
|
||||
|
||||
// Statistics on the session we need to restore.
|
||||
_totalNumberOfEagerTabs: 0,
|
||||
_totalNumberOfTabs: 0,
|
||||
_totalNumberOfWindows: 0,
|
||||
|
||||
init: function() {
|
||||
for (let topic of TOPICS) {
|
||||
for (let topic of OBSERVED_TOPICS) {
|
||||
Services.obs.addObserver(this, topic, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the timestamp at which we finished restoring the latest tab.
|
||||
*
|
||||
* This information is not really interesting until we have finished restoring
|
||||
* tabs.
|
||||
*/
|
||||
get latestRestoredTimeStamp() {
|
||||
return this._latestRestoredTimeStamp;
|
||||
},
|
||||
|
||||
/**
|
||||
* `true` once we have finished restoring startup tabs.
|
||||
*/
|
||||
get isRestored() {
|
||||
return this._isRestored;
|
||||
},
|
||||
|
||||
// Called when restoration starts.
|
||||
// Record the start timestamp, setup the timer and `this._promiseFinished`.
|
||||
// Behavior is unspecified if there was already an ongoing measure.
|
||||
_onRestorationStarts: function(isAutoRestore) {
|
||||
this._startTimeStamp = Date.now();
|
||||
this._latestRestoredTimeStamp = this._startTimeStamp = Date.now();
|
||||
this._totalNumberOfEagerTabs = 0;
|
||||
this._totalNumberOfTabs = 0;
|
||||
this._totalNumberOfWindows = 0;
|
||||
|
@ -68,7 +93,7 @@ this.StartupPerformance = {
|
|||
// that's a very unusual case, and not really worth measuring, so let's
|
||||
// stop listening for further restorations.
|
||||
|
||||
for (let topic of TOPICS) {
|
||||
for (let topic of OBSERVED_TOPICS) {
|
||||
Services.obs.removeObserver(this, topic);
|
||||
}
|
||||
|
||||
|
@ -78,7 +103,10 @@ this.StartupPerformance = {
|
|||
});
|
||||
this._promiseFinished.then(() => {
|
||||
try {
|
||||
if (!this._latestRestoredTimeStamp) {
|
||||
this._isRestored = true;
|
||||
Services.obs.notifyObservers(null, this.RESTORED_TOPIC, "");
|
||||
|
||||
if (this._latestRestoredTimeStamp == this._startTimeStamp) {
|
||||
// Apparently, we haven't restored any tab.
|
||||
return;
|
||||
}
|
||||
|
@ -95,7 +123,6 @@ this.StartupPerformance = {
|
|||
Services.telemetry.getHistogramById("FX_SESSION_RESTORE_NUMBER_OF_TABS_RESTORED").add(this._totalNumberOfTabs);
|
||||
Services.telemetry.getHistogramById("FX_SESSION_RESTORE_NUMBER_OF_WINDOWS_RESTORED").add(this._totalNumberOfWindows);
|
||||
|
||||
|
||||
// Reset
|
||||
this._startTimeStamp = null;
|
||||
} catch (ex) {
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
import mozunit
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from os import path
|
||||
from buildconfig import substs
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
def determine_platform():
|
||||
|
@ -25,39 +28,41 @@ def determine_platform():
|
|||
cpu_type = substs['TARGET_CPU']
|
||||
return platform_mapping.get(os_type, {}).get(cpu_type, None)
|
||||
|
||||
def main():
|
||||
""" A wrapper script that calls compare-mozconfig.py
|
||||
based on the platform that the machine is building for"""
|
||||
platform = determine_platform()
|
||||
|
||||
if platform is not None:
|
||||
python_exe = substs['PYTHON']
|
||||
topsrcdir = substs['top_srcdir']
|
||||
class TestCompareMozconfigs(unittest.TestCase):
|
||||
def test_compare_mozconfigs(self):
|
||||
""" A wrapper script that calls compare-mozconfig.py
|
||||
based on the platform that the machine is building for"""
|
||||
platform = determine_platform()
|
||||
|
||||
# construct paths and args for compare-mozconfig
|
||||
browser_dir = path.join(topsrcdir, 'browser')
|
||||
script_path = path.join(topsrcdir, 'build/compare-mozconfig/compare-mozconfigs.py')
|
||||
whitelist_path = path.join(browser_dir, 'config/mozconfigs/whitelist')
|
||||
beta_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'beta')
|
||||
release_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'release')
|
||||
nightly_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'nightly')
|
||||
if platform is not None:
|
||||
python_exe = substs['PYTHON']
|
||||
topsrcdir = substs['top_srcdir']
|
||||
|
||||
log.info("Comparing beta against nightly mozconfigs")
|
||||
ret_code = subprocess.call([python_exe, script_path, '--whitelist',
|
||||
whitelist_path, '--no-download',
|
||||
platform + ',' + beta_mozconfig_path +
|
||||
',' + nightly_mozconfig_path])
|
||||
# construct paths and args for compare-mozconfig
|
||||
browser_dir = path.join(topsrcdir, 'browser')
|
||||
script_path = path.join(topsrcdir, 'build/compare-mozconfig/compare-mozconfigs.py')
|
||||
whitelist_path = path.join(browser_dir, 'config/mozconfigs/whitelist')
|
||||
beta_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'beta')
|
||||
release_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'release')
|
||||
nightly_mozconfig_path = path.join(browser_dir, 'config/mozconfigs', platform, 'nightly')
|
||||
|
||||
if ret_code > 0:
|
||||
return ret_code
|
||||
log.info("Comparing beta against nightly mozconfigs")
|
||||
ret_code = subprocess.call([python_exe, script_path, '--whitelist',
|
||||
whitelist_path, '--no-download',
|
||||
platform + ',' + beta_mozconfig_path +
|
||||
',' + nightly_mozconfig_path])
|
||||
|
||||
log.info("Comparing release against nightly mozconfigs")
|
||||
ret_code = subprocess.call([python_exe, script_path, '--whitelist',
|
||||
whitelist_path, '--no-download',
|
||||
platform + ',' + release_mozconfig_path +
|
||||
',' + nightly_mozconfig_path])
|
||||
if ret_code > 0:
|
||||
return ret_code
|
||||
|
||||
return ret_code
|
||||
log.info("Comparing release against nightly mozconfigs")
|
||||
ret_code = subprocess.call([python_exe, script_path, '--whitelist',
|
||||
whitelist_path, '--no-download',
|
||||
platform + ',' + release_mozconfig_path +
|
||||
',' + nightly_mozconfig_path])
|
||||
|
||||
self.assertEqual(0, ret_code)
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
mozunit.main()
|
||||
|
|
|
@ -1,327 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Timer;
|
||||
|
||||
import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
|
||||
import com.mozilla.SUTAgentAndroid.R;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import javax.jmdns.JmDNS;
|
||||
import javax.jmdns.ServiceInfo;
|
||||
|
||||
public class ASMozStub extends android.app.Service {
|
||||
private final static int COMMAND_PORT = 20701;
|
||||
private final static int DATA_PORT = 20700;
|
||||
|
||||
private ServerSocket cmdChnl = null;
|
||||
private ServerSocket dataChnl = null;
|
||||
private Handler handler = new Handler();
|
||||
RunCmdThread runCmdThrd = null;
|
||||
RunDataThread runDataThrd = null;
|
||||
Thread monitor = null;
|
||||
Timer timer = null;
|
||||
boolean doZeroConfig = false;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Class<?>[] mSetForegroundSignature = new Class[] {
|
||||
boolean.class};
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Class<?>[] mStartForegroundSignature = new Class[] {
|
||||
int.class, Notification.class};
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Class<?>[] mStopForegroundSignature = new Class[] {
|
||||
boolean.class};
|
||||
|
||||
private NotificationManager mNM;
|
||||
private Method mSetForeground;
|
||||
private Method mStartForeground;
|
||||
private Method mStopForeground;
|
||||
private Object[] mSetForegroundArgs = new Object[1];
|
||||
private Object[] mStartForegroundArgs = new Object[2];
|
||||
private Object[] mStopForegroundArgs = new Object[1];
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
|
||||
try {
|
||||
mStartForeground = getClass().getMethod("startForeground", mStartForegroundSignature);
|
||||
mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
// Might be running on an older platform.
|
||||
mStartForeground = mStopForeground = null;
|
||||
Log.w("SUTAgent", "unable to find start/stopForeground method(s) -- older platform?");
|
||||
}
|
||||
|
||||
try {
|
||||
mSetForeground = getClass().getMethod("setForeground", mSetForegroundSignature);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
mSetForeground = null;
|
||||
Log.e("SUTAgent", "unable to find setForeground method!");
|
||||
}
|
||||
|
||||
doToast("Listener Service created...");
|
||||
}
|
||||
|
||||
WifiManager.MulticastLock multicastLock;
|
||||
JmDNS jmdns;
|
||||
|
||||
void startZeroConf() {
|
||||
if (multicastLock == null) {
|
||||
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
|
||||
multicastLock = wifi.createMulticastLock("SUTAgent");
|
||||
multicastLock.setReferenceCounted(true);
|
||||
}
|
||||
|
||||
multicastLock.acquire();
|
||||
|
||||
try {
|
||||
InetAddress inetAddress = SUTAgentAndroid.getLocalInetAddress();
|
||||
|
||||
if (jmdns == null) {
|
||||
jmdns = JmDNS.create(inetAddress, null);
|
||||
}
|
||||
|
||||
if (jmdns != null) {
|
||||
String name = "SUTAgent";
|
||||
|
||||
String hwid = SUTAgentAndroid.getHWID(this);
|
||||
if (hwid != null) {
|
||||
name += " [hwid:" + hwid + "]";
|
||||
}
|
||||
|
||||
// multicast reception is broken for some reason, so
|
||||
// this service can't be resolved; it can only be
|
||||
// broadcast. So, we cheat -- we put the IP address
|
||||
// in the broadcast that we can pull out later.
|
||||
// However, periods aren't legal, so replace them.
|
||||
// The IP address will show up as [ip:127_0_0_1]
|
||||
name += " [ip:" + inetAddress.getHostAddress().toString().replace('.', '_') + "]";
|
||||
|
||||
final ServiceInfo serviceInfo = ServiceInfo.create("_sutagent._tcp.local.",
|
||||
name,
|
||||
COMMAND_PORT,
|
||||
"Android SUTAgent");
|
||||
final JmDNS dns = jmdns;
|
||||
// we want to call registerService on a new thread, because it can block
|
||||
// for a little while.
|
||||
Thread registerThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
dns.registerService(serviceInfo);
|
||||
} catch (IOException e) {
|
||||
Log.e("SUTAgent", "Failed to register JmDNS service!", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
registerThread.setDaemon(true);
|
||||
registerThread.start();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e("SUTAgent", "Failed to register JmDNS service!", e);
|
||||
}
|
||||
}
|
||||
|
||||
void stopZeroConf() {
|
||||
if (jmdns != null) {
|
||||
try {
|
||||
jmdns.unregisterAllServices();
|
||||
jmdns.close();
|
||||
} catch (IOException e) {
|
||||
Log.e("SUTAgent", "Failed to close JmDNS service!", e);
|
||||
}
|
||||
jmdns = null;
|
||||
}
|
||||
|
||||
if (multicastLock != null) {
|
||||
multicastLock.release();
|
||||
multicastLock = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void onStart(Intent intent, int startId) {
|
||||
super.onStart(intent, startId);
|
||||
|
||||
try {
|
||||
cmdChnl = new ServerSocket(COMMAND_PORT);
|
||||
runCmdThrd = new RunCmdThread(cmdChnl, this, handler);
|
||||
runCmdThrd.start();
|
||||
doToast(String.format("Command channel port %d ...", COMMAND_PORT));
|
||||
|
||||
dataChnl = new ServerSocket(DATA_PORT);
|
||||
runDataThrd = new RunDataThread(dataChnl, this);
|
||||
runDataThrd.start();
|
||||
doToast(String.format("Data channel port %d ...", DATA_PORT));
|
||||
|
||||
DoCommand tmpdc = new DoCommand(getApplication());
|
||||
File dir = getFilesDir();
|
||||
File iniFile = new File(dir, "SUTAgent.ini");
|
||||
String sIniFile = iniFile.getAbsolutePath();
|
||||
String zeroconf = tmpdc.GetIniData("General", "ZeroConfig", sIniFile);
|
||||
if (zeroconf != "" && Integer.parseInt(zeroconf) == 1) {
|
||||
this.doZeroConfig = true;
|
||||
}
|
||||
|
||||
if (this.doZeroConfig) {
|
||||
startZeroConf();
|
||||
}
|
||||
|
||||
Notification notification = new Notification();
|
||||
startForegroundCompat(R.string.foreground_service_started, notification);
|
||||
}
|
||||
catch (Exception e) {
|
||||
doToast(e.toString());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
|
||||
if (this.doZeroConfig) {
|
||||
stopZeroConf();
|
||||
}
|
||||
|
||||
if (runCmdThrd.isAlive())
|
||||
{
|
||||
runCmdThrd.StopListening();
|
||||
}
|
||||
|
||||
if (runDataThrd.isAlive())
|
||||
{
|
||||
runDataThrd.StopListening();
|
||||
}
|
||||
|
||||
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.cancel(1959);
|
||||
|
||||
stopForegroundCompat(R.string.foreground_service_started);
|
||||
|
||||
doToast("Listener Service destroyed...");
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public void SendToDataChannel(String strToSend)
|
||||
{
|
||||
if (runDataThrd.isAlive())
|
||||
runDataThrd.SendToDataChannel(strToSend);
|
||||
}
|
||||
|
||||
public void doToast(String sMsg) {
|
||||
Toast toast = Toast.makeText(this, sMsg, Toast.LENGTH_LONG);
|
||||
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL, 0, 100);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a wrapper around the new startForeground method, using the older
|
||||
* APIs if it is not available.
|
||||
*/
|
||||
void startForegroundCompat(int id, Notification notification) {
|
||||
// If we have the new startForeground API, then use it.
|
||||
if (mStartForeground != null) {
|
||||
mStartForegroundArgs[0] = Integer.valueOf(id);
|
||||
mStartForegroundArgs[1] = notification;
|
||||
try {
|
||||
mStartForeground.invoke(this, mStartForegroundArgs);
|
||||
} catch (InvocationTargetException e) {
|
||||
// Should not happen.
|
||||
Log.e("SUTAgent", "Unable to invoke startForeground", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
// Should not happen.
|
||||
Log.e("SUTAgent", "Unable to invoke startForeground", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Fall back on the old API.
|
||||
if (mSetForeground != null) {
|
||||
try {
|
||||
mSetForegroundArgs[0] = Boolean.TRUE;
|
||||
mSetForeground.invoke(this, mSetForegroundArgs);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e("SUTAgent", "Unable to invoke setForeground", e);
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e("SUTAgent", "Unable to invoke setForeground", e);
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("SUTAgent", "Unable to invoke setForeground", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mNM.notify(id, notification);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a wrapper around the new stopForeground method, using the older
|
||||
* APIs if it is not available.
|
||||
*/
|
||||
void stopForegroundCompat(int id) {
|
||||
// If we have the new stopForeground API, then use it.
|
||||
if (mStopForeground != null) {
|
||||
mStopForegroundArgs[0] = Boolean.TRUE;
|
||||
try {
|
||||
mStopForeground.invoke(this, mStopForegroundArgs);
|
||||
} catch (InvocationTargetException e) {
|
||||
// Should not happen.
|
||||
Log.e("SUTAgent", "Unable to invoke stopForeground", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
// Should not happen.
|
||||
Log.e("SUTAgent", "Unable to invoke stopForeground", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Fall back on the old API. Note to cancel BEFORE changing the
|
||||
// foreground state, since we could be killed at that point.
|
||||
mNM.cancel(id);
|
||||
if (mSetForeground != null) {
|
||||
try {
|
||||
mSetForegroundArgs[0] = Boolean.FALSE;
|
||||
mSetForeground.invoke(this, mSetForegroundArgs);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e("SUTAgent", "Unable to invoke setForeground", e);
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.e("SUTAgent", "Unable to invoke setForeground", e);
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
Log.e("SUTAgent", "Unable to invoke setForeground", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.util.Timer;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
|
||||
class AlertLooperThread extends Thread
|
||||
{
|
||||
public Handler mHandler;
|
||||
private Looper looper = null;
|
||||
private DoAlert da = null;
|
||||
private Timer alertTimer = null;
|
||||
private ContextWrapper contextWrapper = null;
|
||||
|
||||
AlertLooperThread(ContextWrapper ctxW)
|
||||
{
|
||||
this.contextWrapper = ctxW;
|
||||
}
|
||||
|
||||
public Timer getAlertTimer()
|
||||
{
|
||||
return alertTimer;
|
||||
}
|
||||
|
||||
public void term()
|
||||
{
|
||||
if (da != null)
|
||||
da.term();
|
||||
}
|
||||
|
||||
public void quit()
|
||||
{
|
||||
if (looper != null)
|
||||
looper.quit();
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
Looper.prepare();
|
||||
|
||||
looper = Looper.myLooper();
|
||||
|
||||
mHandler = new Handler()
|
||||
{
|
||||
public void handleMessage(Message msg)
|
||||
{
|
||||
// process incoming messages here
|
||||
}
|
||||
};
|
||||
|
||||
alertTimer = new Timer();
|
||||
da = new DoAlert(contextWrapper);
|
||||
alertTimer.scheduleAtFixedRate(da, 0, 5000);
|
||||
Looper.loop();
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mozilla.SUTAgentAndroid"
|
||||
android:versionCode="1" android:versionName="1.01">
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
|
||||
<activity android:name=".SUTAgentAndroid"
|
||||
android:screenOrientation="nosensor"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name=".service.ASMozStub">
|
||||
<intent-filter>
|
||||
<action android:name="com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="8"/>
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
<uses-permission android:name="android.permission.REBOOT"></uses-permission>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.RESTART_PACKAGES"></uses-permission>
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS"></uses-permission>
|
||||
<uses-permission android:name="android.permission.DEVICE_POWER"></uses-permission>
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"></uses-permission>
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"></uses-permission>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>
|
||||
<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission>
|
||||
<uses-permission android:name="android.permission.STATUS_BAR"></uses-permission>
|
||||
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.SET_TIME"></uses-permission>
|
||||
<uses-permission android:name="android.permission.SET_TIME_ZONE"></uses-permission>
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"></uses-permission>
|
||||
<uses-permission android:name="android.permission.GET_TASKS"></uses-permission>
|
||||
|
||||
</manifest>
|
|
@ -1,181 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
// import com.mozilla.SUTAgentAndroid.DoCommand;
|
||||
|
||||
public class CmdWorkerThread extends Thread
|
||||
{
|
||||
private RunCmdThread theParent = null;
|
||||
private Socket socket = null;
|
||||
private String prompt = null;
|
||||
boolean bListening = true;
|
||||
|
||||
public CmdWorkerThread(RunCmdThread theParent, Socket workerSocket)
|
||||
{
|
||||
super("CmdWorkerThread");
|
||||
this.theParent = theParent;
|
||||
this.socket = workerSocket;
|
||||
byte pr [] = new byte [3];
|
||||
pr[0] = '$';
|
||||
pr[1] = '>';
|
||||
pr[2] = 0;
|
||||
prompt = new String(pr,0,3);
|
||||
}
|
||||
|
||||
public void StopListening()
|
||||
{
|
||||
bListening = false;
|
||||
}
|
||||
|
||||
private String readLine(BufferedInputStream in)
|
||||
{
|
||||
String sRet = "";
|
||||
int nByte = 0;
|
||||
char cChar = 0;
|
||||
|
||||
try
|
||||
{
|
||||
nByte = in.read();
|
||||
while (nByte != -1)
|
||||
{
|
||||
cChar = ((char)(nByte & 0xFF));
|
||||
if ((cChar != '\r') && (cChar != '\n'))
|
||||
sRet += cChar;
|
||||
else
|
||||
break;
|
||||
nByte = in.read();
|
||||
}
|
||||
|
||||
if ((in.available() > 0) && (cChar != '\n'))
|
||||
{
|
||||
in.mark(1024);
|
||||
nByte = in.read();
|
||||
|
||||
if (nByte != -1)
|
||||
{
|
||||
cChar = ((char)(nByte & 0xFF));
|
||||
if (cChar != '\n')
|
||||
{
|
||||
in.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (sRet.length() == 0)
|
||||
sRet = null;
|
||||
|
||||
return(sRet);
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
try {
|
||||
OutputStream cmdOut = socket.getOutputStream();
|
||||
InputStream cmdIn = socket.getInputStream();
|
||||
PrintWriter out = new PrintWriter(cmdOut, true);
|
||||
BufferedInputStream in = new BufferedInputStream(cmdIn);
|
||||
String inputLine, outputLine;
|
||||
DoCommand dc = new DoCommand(theParent.svc);
|
||||
|
||||
SUTAgentAndroid.log(dc, "CmdWorkerThread starts: "+getId());
|
||||
|
||||
int nAvail = cmdIn.available();
|
||||
cmdIn.skip(nAvail);
|
||||
|
||||
out.print(prompt);
|
||||
out.flush();
|
||||
|
||||
while (bListening)
|
||||
{
|
||||
if (!(in.available() > 0))
|
||||
{
|
||||
socket.setSoTimeout(500);
|
||||
try {
|
||||
int nRead = cmdIn.read();
|
||||
if (nRead == -1)
|
||||
{
|
||||
bListening = false;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
inputLine = ((char)nRead) + "";
|
||||
socket.setSoTimeout(120000);
|
||||
}
|
||||
}
|
||||
catch(SocketTimeoutException toe)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
inputLine = "";
|
||||
|
||||
if ((inputLine += readLine(in)) != null)
|
||||
{
|
||||
String message = String.format("%s : %s",
|
||||
socket.getInetAddress().getHostAddress(), inputLine);
|
||||
SUTAgentAndroid.log(dc, message);
|
||||
|
||||
outputLine = dc.processCommand(inputLine, out, in, cmdOut);
|
||||
if (outputLine == null)
|
||||
{
|
||||
outputLine = "";
|
||||
}
|
||||
if (outputLine.length() > 0)
|
||||
{
|
||||
out.print(outputLine + "\n" + prompt);
|
||||
}
|
||||
else
|
||||
out.print(prompt);
|
||||
out.flush();
|
||||
if (outputLine.equals("exit"))
|
||||
{
|
||||
theParent.StopListening();
|
||||
bListening = false;
|
||||
}
|
||||
if (outputLine.equals("quit"))
|
||||
{
|
||||
bListening = false;
|
||||
}
|
||||
outputLine = null;
|
||||
System.gc();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
out.close();
|
||||
out = null;
|
||||
in.close();
|
||||
in = null;
|
||||
socket.close();
|
||||
SUTAgentAndroid.log(dc, "CmdWorkerThread ends: "+getId());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
|
||||
// import com.mozilla.SUTAgentAndroid.DoCommand;
|
||||
import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
|
||||
|
||||
public class DataWorkerThread extends Thread
|
||||
{
|
||||
private RunDataThread theParent = null;
|
||||
private Socket socket = null;
|
||||
boolean bListening = true;
|
||||
PrintWriter out = null;
|
||||
SimpleDateFormat sdf = null;
|
||||
|
||||
public DataWorkerThread(RunDataThread theParent, Socket workerSocket)
|
||||
{
|
||||
super("DataWorkerThread");
|
||||
this.theParent = theParent;
|
||||
this.socket = workerSocket;
|
||||
this.sdf = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
|
||||
}
|
||||
|
||||
public void StopListening()
|
||||
{
|
||||
bListening = false;
|
||||
}
|
||||
|
||||
public void SendString(String strToSend)
|
||||
{
|
||||
if (this.out != null)
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
String strOut = sdf.format(cal.getTime());
|
||||
strOut += " " + strToSend + "\r\n";
|
||||
|
||||
out.write(strOut);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
private String readLine(BufferedInputStream in)
|
||||
{
|
||||
String sRet = "";
|
||||
int nByte = 0;
|
||||
char cChar = 0;
|
||||
|
||||
try
|
||||
{
|
||||
nByte = in.read();
|
||||
while (nByte != -1)
|
||||
{
|
||||
cChar = ((char)(nByte & 0xFF));
|
||||
if ((cChar != '\r') && (cChar != '\n'))
|
||||
sRet += cChar;
|
||||
else
|
||||
break;
|
||||
nByte = in.read();
|
||||
}
|
||||
|
||||
if (in.available() > 0)
|
||||
{
|
||||
in.mark(1024);
|
||||
nByte = in.read();
|
||||
|
||||
while (nByte != -1)
|
||||
{
|
||||
cChar = ((char)(nByte & 0xFF));
|
||||
if ((cChar == '\r') || (cChar == '\n'))
|
||||
{
|
||||
if (in.available() > 0)
|
||||
{
|
||||
in.mark(1024);
|
||||
nByte = in.read();
|
||||
}
|
||||
else
|
||||
nByte = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
in.reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (sRet.length() == 0)
|
||||
sRet = null;
|
||||
|
||||
return(sRet);
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
String sRet = "";
|
||||
long lEndTime = System.currentTimeMillis() + 60000;
|
||||
|
||||
try {
|
||||
while(bListening)
|
||||
{
|
||||
OutputStream cmdOut = socket.getOutputStream();
|
||||
InputStream cmdIn = socket.getInputStream();
|
||||
this.out = new PrintWriter(cmdOut, true);
|
||||
BufferedInputStream in = new BufferedInputStream(cmdIn);
|
||||
String inputLine, outputLine;
|
||||
DoCommand dc = new DoCommand(theParent.svc);
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
sRet = sdf.format(cal.getTime());
|
||||
sRet += " trace output";
|
||||
|
||||
out.println(sRet);
|
||||
out.flush();
|
||||
int nAvail = cmdIn.available();
|
||||
cmdIn.skip(nAvail);
|
||||
|
||||
while (bListening)
|
||||
{
|
||||
if (System.currentTimeMillis() > lEndTime)
|
||||
{
|
||||
cal = Calendar.getInstance();
|
||||
sRet = sdf.format(cal.getTime());
|
||||
sRet += " Thump thump - " + SUTAgentAndroid.sUniqueID + "\r\n";
|
||||
|
||||
out.write(sRet);
|
||||
out.flush();
|
||||
|
||||
lEndTime = System.currentTimeMillis() + 60000;
|
||||
}
|
||||
|
||||
if (!(in.available() > 0))
|
||||
{
|
||||
socket.setSoTimeout(500);
|
||||
try {
|
||||
int nRead = cmdIn.read();
|
||||
if (nRead == -1)
|
||||
{
|
||||
bListening = false;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
inputLine = (char)nRead + "";
|
||||
}
|
||||
catch(SocketTimeoutException toe)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
inputLine = "";
|
||||
|
||||
if ((inputLine += readLine(in)) != null)
|
||||
{
|
||||
outputLine = dc.processCommand(inputLine, out, in, cmdOut);
|
||||
if (outputLine == null)
|
||||
{
|
||||
outputLine = "";
|
||||
}
|
||||
out.print(outputLine + "\n");
|
||||
out.flush();
|
||||
if (outputLine.equals("exit"))
|
||||
{
|
||||
theParent.StopListening();
|
||||
bListening = false;
|
||||
}
|
||||
if (outputLine.equals("quit"))
|
||||
{
|
||||
bListening = false;
|
||||
}
|
||||
outputLine = null;
|
||||
System.gc();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
out.close();
|
||||
out = null;
|
||||
in.close();
|
||||
in = null;
|
||||
socket.close();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.util.TimerTask;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.media.Ringtone;
|
||||
import android.media.RingtoneManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
class DoAlert extends TimerTask
|
||||
{
|
||||
int lcv = 0;
|
||||
Toast toast = null;
|
||||
Ringtone rt = null;
|
||||
|
||||
DoAlert(ContextWrapper contextWrapper)
|
||||
{
|
||||
Context ctx = contextWrapper.getApplicationContext();
|
||||
this.toast = Toast.makeText(ctx, "Help me!", Toast.LENGTH_LONG);
|
||||
rt = RingtoneManager.getRingtone(ctx, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
|
||||
}
|
||||
|
||||
public void term()
|
||||
{
|
||||
if (rt != null)
|
||||
{
|
||||
if (rt.isPlaying())
|
||||
rt.stop();
|
||||
}
|
||||
|
||||
if (toast != null)
|
||||
toast.cancel();
|
||||
}
|
||||
|
||||
public void run ()
|
||||
{
|
||||
String sText =(((lcv++ % 2) == 0) ? "Help me!" : "I've fallen down!" );
|
||||
toast.setText(sText);
|
||||
toast.show();
|
||||
if (rt != null)
|
||||
rt.play();
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ContextWrapper;
|
||||
|
||||
public class FindProcThread extends Thread {
|
||||
ContextWrapper contextWrapper = null;
|
||||
String sProcNameToFind = "";
|
||||
boolean bFoundIt = false;
|
||||
boolean bStillRunning = true;
|
||||
|
||||
public FindProcThread(ContextWrapper ctx, String sProcessName) {
|
||||
super("FindProcThread");
|
||||
this.contextWrapper = ctx;
|
||||
this.sProcNameToFind = sProcessName;
|
||||
this.bFoundIt = false;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
|
||||
List <ActivityManager.RunningAppProcessInfo> lProcesses;
|
||||
int lcv = 0;
|
||||
int nNumLoops = 0;
|
||||
String strProcName = "";
|
||||
int nPID = 0;
|
||||
|
||||
if (aMgr == null)
|
||||
return;
|
||||
|
||||
|
||||
// While we are still looping looking for the process in the list and we haven't found it
|
||||
while (bStillRunning && !bFoundIt) {
|
||||
lProcesses = aMgr.getRunningAppProcesses();
|
||||
if (lProcesses != null) {
|
||||
for (lcv = 0; lcv < lProcesses.size(); lcv++) {
|
||||
if (lProcesses.get(lcv).processName.contains(sProcNameToFind)) {
|
||||
strProcName = lProcesses.get(lcv).processName;
|
||||
nPID = lProcesses.get(lcv).pid;
|
||||
bFoundIt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bFoundIt) // This saves you half a second of wait time if we've found it in the list
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(500); // Sleep half a second
|
||||
if (++nNumLoops > 10) { // loop up to 10 times
|
||||
bStillRunning = false;
|
||||
}
|
||||
lProcesses = null;
|
||||
System.gc();
|
||||
Thread.yield();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
bStillRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
JAVAFILES = \
|
||||
AlertLooperThread.java \
|
||||
ASMozStub.java \
|
||||
CmdWorkerThread.java \
|
||||
DataWorkerThread.java \
|
||||
DoAlert.java \
|
||||
DoCommand.java \
|
||||
FindProcThread.java \
|
||||
Power.java \
|
||||
RedirOutputThread.java \
|
||||
RunCmdThread.java \
|
||||
RunDataThread.java \
|
||||
SUTAgentAndroid.java \
|
||||
WifiConfiguration.java \
|
||||
$(NULL)
|
||||
|
||||
ANDROID_EXTRA_JARS = \
|
||||
$(srcdir)/network-libs/commons-net-2.0.jar \
|
||||
$(srcdir)/network-libs/jmdns.jar \
|
||||
$(NULL)
|
||||
|
||||
tools:: $(ANDROID_APK_NAME).apk
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Class that provides access to some of the power management functions.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public class Power
|
||||
{
|
||||
// can't instantiate this class
|
||||
private Power()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Wake lock that ensures that the CPU is running. The screen might
|
||||
* not be on.
|
||||
*/
|
||||
public static final int PARTIAL_WAKE_LOCK = 1;
|
||||
|
||||
/**
|
||||
* Wake lock that ensures that the screen is on.
|
||||
*/
|
||||
public static final int FULL_WAKE_LOCK = 2;
|
||||
|
||||
public static native void acquireWakeLock(int lock, String id);
|
||||
public static native void releaseWakeLock(String id);
|
||||
|
||||
/**
|
||||
* Brightness value for fully off
|
||||
*/
|
||||
public static final int BRIGHTNESS_OFF = 0;
|
||||
|
||||
/**
|
||||
* Brightness value for dim backlight
|
||||
*/
|
||||
public static final int BRIGHTNESS_DIM = 20;
|
||||
|
||||
/**
|
||||
* Brightness value for fully on
|
||||
*/
|
||||
public static final int BRIGHTNESS_ON = 255;
|
||||
|
||||
/**
|
||||
* Brightness value to use when battery is low
|
||||
*/
|
||||
public static final int BRIGHTNESS_LOW_BATTERY = 10;
|
||||
|
||||
/**
|
||||
* Threshold for BRIGHTNESS_LOW_BATTERY (percentage)
|
||||
* Screen will stay dim if battery level is <= LOW_BATTERY_THRESHOLD
|
||||
*/
|
||||
public static final int LOW_BATTERY_THRESHOLD = 10;
|
||||
|
||||
/**
|
||||
* Turn the screen on or off
|
||||
*
|
||||
* @param on Whether you want the screen on or off
|
||||
*/
|
||||
public static native int setScreenState(boolean on);
|
||||
|
||||
public static native int setLastUserActivityTimeout(long ms);
|
||||
|
||||
/**
|
||||
* Turn the device off.
|
||||
*
|
||||
* This method is considered deprecated in favor of
|
||||
* {@link android.policy.ShutdownThread.shutdownAfterDisablingRadio()}.
|
||||
*
|
||||
* @deprecated
|
||||
* @hide
|
||||
*/
|
||||
@Deprecated
|
||||
public static native void shutdown();
|
||||
|
||||
/**
|
||||
* Reboot the device.
|
||||
* @param reason code to pass to the kernel (e.g. "recovery"), or null.
|
||||
*
|
||||
* @throws IOException if reboot fails for some reason (eg, lack of
|
||||
* permission)
|
||||
*/
|
||||
public static native void reboot(String reason) throws IOException;
|
||||
}
|
|
@ -1,197 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class RedirOutputThread extends Thread
|
||||
{
|
||||
OutputStream out;
|
||||
InputStream sutErr;
|
||||
InputStream sutOut;
|
||||
Process pProc;
|
||||
String strOutput;
|
||||
int nExitCode = -1;
|
||||
private volatile boolean stopRedirRequested = false;
|
||||
private volatile boolean redirStopped = false;
|
||||
|
||||
public RedirOutputThread(Process pProc, OutputStream out)
|
||||
{
|
||||
super("RedirOutputThread");
|
||||
if (pProc != null)
|
||||
{
|
||||
this.pProc = pProc;
|
||||
sutErr = pProc.getErrorStream(); // Stderr
|
||||
sutOut = pProc.getInputStream(); // Stdout
|
||||
}
|
||||
if (out != null)
|
||||
this.out = out;
|
||||
|
||||
strOutput = "";
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
boolean bStillRunning = true;
|
||||
int nBytesOut = 0;
|
||||
int nBytesErr = 0;
|
||||
int nBytesRead = 0;
|
||||
PrintWriter pOut = null;
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
if (out != null)
|
||||
pOut = new PrintWriter(out);
|
||||
else
|
||||
bStillRunning = true;
|
||||
|
||||
while (bStillRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If there's no output to collect, sleep for a while
|
||||
// rather than checking again immediately, to avoid
|
||||
// using up cpu capacity in a tight loop.
|
||||
if (sutOut.available() == 0 && sutErr.available() == 0)
|
||||
{
|
||||
Thread.sleep(50);
|
||||
}
|
||||
if ((nBytesOut = sutOut.available()) > 0)
|
||||
{
|
||||
if (nBytesOut > buffer.length)
|
||||
{
|
||||
buffer = null;
|
||||
System.gc();
|
||||
buffer = new byte[nBytesOut];
|
||||
}
|
||||
nBytesRead = sutOut.read(buffer, 0, nBytesOut);
|
||||
if (nBytesRead == -1)
|
||||
bStillRunning = false;
|
||||
else
|
||||
{
|
||||
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
|
||||
if (pOut != null)
|
||||
{
|
||||
pOut.print(sRep);
|
||||
pOut.flush();
|
||||
}
|
||||
else
|
||||
strOutput += sRep;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nBytesErr = sutErr.available()) > 0)
|
||||
{
|
||||
if (nBytesErr > buffer.length)
|
||||
{
|
||||
buffer = null;
|
||||
System.gc();
|
||||
buffer = new byte[nBytesErr];
|
||||
}
|
||||
nBytesRead = sutErr.read(buffer, 0, nBytesErr);
|
||||
if (nBytesRead == -1)
|
||||
bStillRunning = false;
|
||||
else
|
||||
{
|
||||
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
|
||||
if (pOut != null)
|
||||
{
|
||||
pOut.print(sRep);
|
||||
pOut.flush();
|
||||
}
|
||||
else
|
||||
strOutput += sRep;
|
||||
}
|
||||
}
|
||||
|
||||
bStillRunning = (stopRedirRequested == false) &&
|
||||
(IsProcRunning(pProc) || (sutOut.available() > 0) || (sutErr.available() > 0));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (java.lang.IllegalArgumentException e)
|
||||
{
|
||||
// Bug 743766: InputStream.available() unexpectedly throws this sometimes
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// notify stopRedirect that redirection has stopped
|
||||
redirStopped = true;
|
||||
if (stopRedirRequested)
|
||||
{
|
||||
synchronized(this)
|
||||
{
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
// wait for process to end; if it has not already ended, then destroy it
|
||||
try
|
||||
{
|
||||
pProc.waitFor();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
pProc.destroy();
|
||||
}
|
||||
buffer = null;
|
||||
System.gc();
|
||||
}
|
||||
|
||||
private boolean IsProcRunning(Process pProc)
|
||||
{
|
||||
boolean bRet = false;
|
||||
|
||||
try
|
||||
{
|
||||
nExitCode = pProc.exitValue();
|
||||
}
|
||||
catch (IllegalThreadStateException z)
|
||||
{
|
||||
nExitCode = -1;
|
||||
bRet = true;
|
||||
}
|
||||
|
||||
return(bRet);
|
||||
}
|
||||
|
||||
public synchronized void stopRedirect()
|
||||
{
|
||||
stopRedirRequested = true;
|
||||
// wait for notification that redirection has stopped
|
||||
if (!redirStopped)
|
||||
{
|
||||
try
|
||||
{
|
||||
// max wait time is somewhat arbitrary and provided "just in case";
|
||||
// we expect to be notified as soon as run() completes its current
|
||||
// sleep and checks the stopRedirRequested flag
|
||||
wait(500);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void joinAndStopRedirect(long millis) throws InterruptedException
|
||||
{
|
||||
super.join(millis);
|
||||
if (out != null)
|
||||
stopRedirect();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,278 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mozilla.SUTAgentAndroid.R;
|
||||
import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
|
||||
public class RunCmdThread extends Thread
|
||||
{
|
||||
private ServerSocket SvrSocket = null;
|
||||
private Socket socket = null;
|
||||
private Handler handler = null;
|
||||
boolean bListening = true;
|
||||
boolean bNetError = false;
|
||||
List<CmdWorkerThread> theWorkers = new ArrayList<CmdWorkerThread>();
|
||||
android.app.Service svc = null;
|
||||
|
||||
public RunCmdThread(ServerSocket socket, android.app.Service service, Handler handler)
|
||||
{
|
||||
super("RunCmdThread");
|
||||
this.SvrSocket = socket;
|
||||
this.svc = service;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public void StopListening()
|
||||
{
|
||||
bListening = false;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
SvrSocket.setSoTimeout(5000);
|
||||
while (bListening)
|
||||
{
|
||||
try
|
||||
{
|
||||
socket = SvrSocket.accept();
|
||||
CmdWorkerThread theWorker = new CmdWorkerThread(this, socket);
|
||||
theWorker.start();
|
||||
theWorkers.add(theWorker);
|
||||
}
|
||||
catch (SocketTimeoutException toe)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int nNumWorkers = theWorkers.size();
|
||||
for (int lcv = 0; lcv < nNumWorkers; lcv++)
|
||||
{
|
||||
if (theWorkers.get(lcv).isAlive())
|
||||
{
|
||||
theWorkers.get(lcv).StopListening();
|
||||
while(theWorkers.get(lcv).isAlive())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
theWorkers.clear();
|
||||
|
||||
SvrSocket.close();
|
||||
|
||||
svc.stopSelf();
|
||||
|
||||
// SUTAgentAndroid.me.finish();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private String SendPing(String sIPAddr)
|
||||
{
|
||||
Process pProc;
|
||||
String sRet = "";
|
||||
String [] theArgs = new String [4];
|
||||
boolean bStillRunning = true;
|
||||
int nBytesOut = 0;
|
||||
int nBytesErr = 0;
|
||||
int nBytesRead = 0;
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
theArgs[0] = "ping";
|
||||
theArgs[1] = "-c";
|
||||
theArgs[2] = "3";
|
||||
theArgs[3] = sIPAddr;
|
||||
|
||||
try
|
||||
{
|
||||
pProc = Runtime.getRuntime().exec(theArgs);
|
||||
|
||||
InputStream sutOut = pProc.getInputStream();
|
||||
InputStream sutErr = pProc.getErrorStream();
|
||||
|
||||
while (bStillRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((nBytesOut = sutOut.available()) > 0)
|
||||
{
|
||||
if (nBytesOut > buffer.length)
|
||||
{
|
||||
buffer = null;
|
||||
System.gc();
|
||||
buffer = new byte[nBytesOut];
|
||||
}
|
||||
nBytesRead = sutOut.read(buffer, 0, nBytesOut);
|
||||
if (nBytesRead == -1)
|
||||
bStillRunning = false;
|
||||
else
|
||||
{
|
||||
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
|
||||
sRet += sRep;
|
||||
sRep = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nBytesErr = sutErr.available()) > 0)
|
||||
{
|
||||
if (nBytesErr > buffer.length)
|
||||
{
|
||||
buffer = null;
|
||||
System.gc();
|
||||
buffer = new byte[nBytesErr];
|
||||
}
|
||||
nBytesRead = sutErr.read(buffer, 0, nBytesErr);
|
||||
if (nBytesRead == -1)
|
||||
bStillRunning = false;
|
||||
else
|
||||
{
|
||||
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
|
||||
sRet += sRep;
|
||||
sRep = null;
|
||||
}
|
||||
}
|
||||
|
||||
bStillRunning = (IsProcRunning(pProc) || (sutOut.available() > 0) || (sutErr.available() > 0));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if ((bStillRunning == true) && (nBytesErr == 0) && (nBytesOut == 0))
|
||||
{
|
||||
try {
|
||||
sleep(2000);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pProc.destroy();
|
||||
pProc = null;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
sRet = e.getMessage();
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return (sRet);
|
||||
}
|
||||
|
||||
private boolean IsProcRunning(Process pProc)
|
||||
{
|
||||
boolean bRet = false;
|
||||
@SuppressWarnings("unused")
|
||||
int nExitCode = 0;
|
||||
|
||||
try
|
||||
{
|
||||
nExitCode = pProc.exitValue();
|
||||
}
|
||||
catch (IllegalThreadStateException z)
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return(bRet);
|
||||
}
|
||||
|
||||
private void SendNotification(String tickerText, String expandedText)
|
||||
{
|
||||
NotificationManager notificationManager = (NotificationManager)svc.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
// int icon = android.R.drawable.stat_notify_more;
|
||||
// int icon = R.drawable.ic_stat_first;
|
||||
// int icon = R.drawable.ic_stat_second;
|
||||
// int icon = R.drawable.ic_stat_neterror;
|
||||
int icon = R.drawable.ateamlogo;
|
||||
long when = System.currentTimeMillis();
|
||||
|
||||
Context context = svc.getApplicationContext();
|
||||
|
||||
// Intent to launch an activity when the extended text is clicked
|
||||
Intent intent2 = new Intent(svc, SUTAgentAndroid.class);
|
||||
PendingIntent launchIntent = PendingIntent.getActivity(context, 0, intent2, 0);
|
||||
|
||||
|
||||
Notification notification = new Notification.Builder(context)
|
||||
.setSmallIcon(icon)
|
||||
.setContentTitle(tickerText)
|
||||
.setContentText(expandedText)
|
||||
.setContentIntent(launchIntent)
|
||||
.setWhen(when)
|
||||
.build();
|
||||
|
||||
notification.flags |= (Notification.FLAG_INSISTENT | Notification.FLAG_AUTO_CANCEL);
|
||||
notification.defaults |= Notification.DEFAULT_SOUND;
|
||||
notification.defaults |= Notification.DEFAULT_VIBRATE;
|
||||
notification.defaults |= Notification.DEFAULT_LIGHTS;
|
||||
|
||||
notificationManager.notify(1959, notification);
|
||||
}
|
||||
|
||||
private void CancelNotification()
|
||||
{
|
||||
NotificationManager notificationManager = (NotificationManager)svc.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.cancel(1959);
|
||||
}
|
||||
|
||||
class doCancelNotification implements Runnable
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
CancelNotification();
|
||||
}
|
||||
};
|
||||
|
||||
class doSendNotification implements Runnable
|
||||
{
|
||||
private String sTitle = "";
|
||||
private String sBText = "";
|
||||
|
||||
doSendNotification(String sTitle, String sBodyText)
|
||||
{
|
||||
this.sTitle = sTitle;
|
||||
this.sBText = sBodyText;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
SendNotification(sTitle, sBText);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
|
||||
public class RunDataThread extends Thread
|
||||
{
|
||||
Timer heartBeatTimer;
|
||||
|
||||
private ServerSocket SvrSocket = null;
|
||||
private Socket socket = null;
|
||||
boolean bListening = true;
|
||||
List<DataWorkerThread> theWorkers = new ArrayList<DataWorkerThread>();
|
||||
android.app.Service svc = null;
|
||||
|
||||
public RunDataThread(ServerSocket socket, android.app.Service service)
|
||||
{
|
||||
super("RunDataThread");
|
||||
this.SvrSocket = socket;
|
||||
this.svc = service;
|
||||
}
|
||||
|
||||
public void StopListening()
|
||||
{
|
||||
bListening = false;
|
||||
}
|
||||
|
||||
public void SendToDataChannel(String strToSend)
|
||||
{
|
||||
int nNumWorkers = theWorkers.size();
|
||||
for (int lcv = 0; lcv < nNumWorkers; lcv++)
|
||||
{
|
||||
if (theWorkers.get(lcv).isAlive())
|
||||
{
|
||||
theWorkers.get(lcv).SendString(strToSend);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
SvrSocket.setSoTimeout(5000);
|
||||
while (bListening)
|
||||
{
|
||||
try
|
||||
{
|
||||
socket = SvrSocket.accept();
|
||||
DataWorkerThread theWorker = new DataWorkerThread(this, socket);
|
||||
theWorker.start();
|
||||
theWorkers.add(theWorker);
|
||||
}
|
||||
catch (SocketTimeoutException toe)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int nNumWorkers = theWorkers.size();
|
||||
for (int lcv = 0; lcv < nNumWorkers; lcv++)
|
||||
{
|
||||
if (theWorkers.get(lcv).isAlive())
|
||||
{
|
||||
theWorkers.get(lcv).StopListening();
|
||||
while(theWorkers.get(lcv).isAlive())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
theWorkers.clear();
|
||||
|
||||
SvrSocket.close();
|
||||
|
||||
svc.stopSelf();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Toast.makeText(SUTAgentAndroid.me.getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -1,903 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.SUTAgentAndroid;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Formatter;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Timer;
|
||||
|
||||
import com.mozilla.SUTAgentAndroid.service.ASMozStub;
|
||||
import com.mozilla.SUTAgentAndroid.service.DoCommand;
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.SupplicantState;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.WifiManager.WifiLock;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Build;
|
||||
import android.os.Build.VERSION;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class SUTAgentAndroid extends Activity
|
||||
{
|
||||
final Handler mHandler = new Handler();
|
||||
|
||||
private static final Pattern IPV4_PATTERN = Pattern.compile("^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");
|
||||
|
||||
public static final int START_PRG = 1959;
|
||||
MenuItem mExitMenuItem;
|
||||
Timer timer = null;
|
||||
|
||||
public static String sUniqueID = null;
|
||||
public static String sLocalIPAddr = null;
|
||||
public static String sACStatus = null;
|
||||
public static String sPowerStatus = null;
|
||||
public static int nChargeLevel = 0;
|
||||
public static int nBatteryTemp = 0;
|
||||
public static long nCreateTimeMillis = System.currentTimeMillis();
|
||||
public static String sTestRoot = "";
|
||||
|
||||
String lineSep = System.getProperty("line.separator");
|
||||
public PrintWriter dataOut = null;
|
||||
|
||||
private static boolean bNetworkingStarted = false;
|
||||
private static String RegSvrIPAddr = "";
|
||||
private static String RegSvrIPPort = "";
|
||||
private static String HardwareID = "";
|
||||
private static String Pool = "";
|
||||
private static String Abi = "";
|
||||
private static String sRegString = "";
|
||||
private static boolean LogCommands = false;
|
||||
|
||||
private WifiLock wl = null;
|
||||
|
||||
private BroadcastReceiver battReceiver = null;
|
||||
|
||||
private TextView tv = null;
|
||||
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
mExitMenuItem = menu.add("Exit");
|
||||
mExitMenuItem.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item)
|
||||
{
|
||||
if (item == mExitMenuItem)
|
||||
{
|
||||
finish();
|
||||
}
|
||||
return super.onMenuItemSelected(featureId, item);
|
||||
}
|
||||
|
||||
public static String getRegSvrIPAddr()
|
||||
{
|
||||
return(RegSvrIPAddr);
|
||||
}
|
||||
|
||||
public void pruneCommandLog(String datestamp, String testroot)
|
||||
{
|
||||
|
||||
String today = "";
|
||||
String yesterday = "";
|
||||
|
||||
// test root can be null (if getTestRoot fails), handle that:
|
||||
if (testroot == null) {
|
||||
testroot = "";
|
||||
}
|
||||
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
|
||||
Date dateObj = sdf.parse(datestamp);
|
||||
SimpleDateFormat sdf_file = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
today = sdf_file.format(dateObj);
|
||||
yesterday = sdf_file.format(new Date(dateObj.getTime() - 1000*60*60*24));
|
||||
} catch (ParseException pe) {}
|
||||
|
||||
File dir = new File(testroot);
|
||||
|
||||
if (!dir.isDirectory())
|
||||
return;
|
||||
|
||||
File [] files = dir.listFiles();
|
||||
if (files == null)
|
||||
return;
|
||||
|
||||
for (int iter = 0; iter < files.length; iter++) {
|
||||
String fName = files[iter].getName();
|
||||
if (fName.endsWith("sutcommands.txt")) {
|
||||
if (fName.endsWith(today + "-sutcommands.txt") || fName.endsWith(yesterday + "-sutcommands.txt"))
|
||||
continue;
|
||||
|
||||
if (files[iter].delete())
|
||||
Log.i("SUTAgentAndroid", "Deleted old command logfile: " + files[iter]);
|
||||
else
|
||||
Log.e("SUTAgentAndroid", "Unable to delete old command logfile: " + files[iter]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.main);
|
||||
|
||||
fixScreenOrientation();
|
||||
|
||||
DoCommand dc = new DoCommand(getApplication());
|
||||
|
||||
Log.i("SUTAgentAndroid", dc.prgVersion);
|
||||
dc.FixDataLocalPermissions();
|
||||
|
||||
// Get configuration settings from "ini" file
|
||||
File dir = getFilesDir();
|
||||
File iniFile = new File(dir, "SUTAgent.ini");
|
||||
String sIniFile = iniFile.getAbsolutePath();
|
||||
|
||||
String lc = dc.GetIniData("General", "LogCommands", sIniFile);
|
||||
if (lc != "" && Integer.parseInt(lc) == 1) {
|
||||
SUTAgentAndroid.LogCommands = true;
|
||||
}
|
||||
SUTAgentAndroid.RegSvrIPAddr = dc.GetIniData("Registration Server", "IPAddr", sIniFile);
|
||||
SUTAgentAndroid.RegSvrIPPort = dc.GetIniData("Registration Server", "PORT", sIniFile);
|
||||
SUTAgentAndroid.HardwareID = dc.GetIniData("Registration Server", "HARDWARE", sIniFile);
|
||||
SUTAgentAndroid.Pool = dc.GetIniData("Registration Server", "POOL", sIniFile);
|
||||
SUTAgentAndroid.sTestRoot = dc.GetIniData("Device", "TestRoot", sIniFile);
|
||||
SUTAgentAndroid.Abi = android.os.Build.CPU_ABI;
|
||||
log(dc, "onCreate");
|
||||
|
||||
dc.SetTestRoot(SUTAgentAndroid.sTestRoot);
|
||||
|
||||
Log.i("SUTAgentAndroid", "Test Root: " + SUTAgentAndroid.sTestRoot);
|
||||
|
||||
tv = (TextView) this.findViewById(R.id.Textview01);
|
||||
|
||||
if (getLocalIpAddress() == null)
|
||||
setUpNetwork(sIniFile);
|
||||
|
||||
String macAddress = "Unknown";
|
||||
if (android.os.Build.VERSION.SDK_INT > 8) {
|
||||
try {
|
||||
NetworkInterface iface = NetworkInterface.getByInetAddress(InetAddress.getAllByName(getLocalIpAddress())[0]);
|
||||
if (iface != null)
|
||||
{
|
||||
byte[] mac = iface.getHardwareAddress();
|
||||
if (mac != null)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Formatter f = new Formatter(sb);
|
||||
for (int i = 0; i < mac.length; i++)
|
||||
{
|
||||
f.format("%02x%s", mac[i], (i < mac.length - 1) ? ":" : "");
|
||||
}
|
||||
macAddress = sUniqueID = sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (UnknownHostException ex) {}
|
||||
catch (SocketException ex) {}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fall back to getting info from wifiman on older versions of Android,
|
||||
// which don't support the NetworkInterface interface
|
||||
WifiManager wifiMan = (WifiManager)getSystemService(Context.WIFI_SERVICE);
|
||||
if (wifiMan != null)
|
||||
{
|
||||
WifiInfo wifi = wifiMan.getConnectionInfo();
|
||||
if (wifi != null)
|
||||
macAddress = wifi.getMacAddress();
|
||||
if (macAddress != null)
|
||||
sUniqueID = macAddress;
|
||||
}
|
||||
}
|
||||
|
||||
if (sUniqueID == null)
|
||||
{
|
||||
BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
|
||||
if ((ba != null) && (ba.isEnabled() != true))
|
||||
{
|
||||
ba.enable();
|
||||
while(ba.getState() != BluetoothAdapter.STATE_ON)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
sUniqueID = ba.getAddress();
|
||||
|
||||
ba.disable();
|
||||
while(ba.getState() != BluetoothAdapter.STATE_OFF)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ba != null)
|
||||
{
|
||||
sUniqueID = ba.getAddress().toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sUniqueID == null)
|
||||
{
|
||||
TelephonyManager mTelephonyMgr = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
|
||||
if (mTelephonyMgr != null)
|
||||
{
|
||||
sUniqueID = mTelephonyMgr.getDeviceId();
|
||||
if (sUniqueID == null)
|
||||
{
|
||||
sUniqueID = "0011223344556677";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String hwid = getHWID(this);
|
||||
|
||||
sLocalIPAddr = getLocalIpAddress();
|
||||
Toast.makeText(getApplication().getApplicationContext(), "SUTAgent [" + sLocalIPAddr + "] ...", Toast.LENGTH_LONG).show();
|
||||
|
||||
String sConfig = dc.prgVersion + lineSep;
|
||||
sConfig += "Test Root: " + sTestRoot + lineSep;
|
||||
sConfig += "Unique ID: " + sUniqueID + lineSep;
|
||||
sConfig += "HWID: " + hwid + lineSep;
|
||||
sConfig += "ABI: " + Abi + lineSep;
|
||||
sConfig += "OS Info" + lineSep;
|
||||
sConfig += "\t" + dc.GetOSInfo() + lineSep;
|
||||
sConfig += "Screen Info" + lineSep;
|
||||
int [] xy = dc.GetScreenXY();
|
||||
sConfig += "\t Width: " + xy[0] + lineSep;
|
||||
sConfig += "\t Height: " + xy[1] + lineSep;
|
||||
sConfig += "Memory Info" + lineSep;
|
||||
sConfig += "\t" + dc.GetMemoryInfo() + lineSep;
|
||||
sConfig += "Network Info" + lineSep;
|
||||
sConfig += "\tMac Address: " + macAddress + lineSep;
|
||||
sConfig += "\tIP Address: " + sLocalIPAddr + lineSep;
|
||||
|
||||
displayStatus(sConfig);
|
||||
|
||||
sRegString = "NAME=" + sUniqueID;
|
||||
sRegString += "&IPADDR=" + sLocalIPAddr;
|
||||
sRegString += "&CMDPORT=" + 20701;
|
||||
sRegString += "&DATAPORT=" + 20700;
|
||||
sRegString += "&OS=Android-" + dc.GetOSInfo();
|
||||
sRegString += "&SCRNWIDTH=" + xy[0];
|
||||
sRegString += "&SCRNHEIGHT=" + xy[1];
|
||||
sRegString += "&BPP=8";
|
||||
sRegString += "&MEMORY=" + dc.GetMemoryConfig();
|
||||
sRegString += "&HARDWARE=" + HardwareID;
|
||||
sRegString += "&POOL=" + Pool;
|
||||
sRegString += "&ABI=" + Abi;
|
||||
|
||||
String sTemp = Uri.encode(sRegString,"=&");
|
||||
sRegString = "register " + sTemp;
|
||||
|
||||
pruneCommandLog(dc.GetSystemTime(), dc.GetTestRoot());
|
||||
|
||||
if (!bNetworkingStarted)
|
||||
{
|
||||
Thread thread = new Thread(null, doStartService, "StartServiceBkgnd");
|
||||
thread.start();
|
||||
bNetworkingStarted = true;
|
||||
|
||||
Thread thread2 = new Thread(null, doRegisterDevice, "RegisterDeviceBkgnd");
|
||||
thread2.start();
|
||||
}
|
||||
|
||||
monitorBatteryState();
|
||||
|
||||
// If we are returning from an update let'em know we're back
|
||||
Thread thread3 = new Thread(null, doUpdateCallback, "UpdateCallbackBkgnd");
|
||||
thread3.start();
|
||||
|
||||
final Button goButton = (Button) findViewById(R.id.Button01);
|
||||
goButton.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class UpdateStatus implements Runnable {
|
||||
public String sText = "";
|
||||
|
||||
UpdateStatus(String sStatus) {
|
||||
sText = sStatus;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
displayStatus(sText);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void displayStatus(String sStatus) {
|
||||
String sTVText = (String) tv.getText();
|
||||
sTVText += sStatus;
|
||||
tv.setText(sTVText);
|
||||
}
|
||||
|
||||
public void fixScreenOrientation()
|
||||
{
|
||||
setRequestedOrientation((getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) ?
|
||||
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
}
|
||||
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (requestCode == START_PRG)
|
||||
{
|
||||
Toast.makeText(getApplication().getApplicationContext(), "SUTAgent startprg finished ...", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
DoCommand dc = new DoCommand(getApplication());
|
||||
super.onDestroy();
|
||||
if (isFinishing())
|
||||
{
|
||||
log(dc, "onDestroy - finishing");
|
||||
Intent listenerSvc = new Intent(this, ASMozStub.class);
|
||||
listenerSvc.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
|
||||
stopService(listenerSvc);
|
||||
bNetworkingStarted = false;
|
||||
|
||||
unregisterReceiver(battReceiver);
|
||||
|
||||
if (wl != null)
|
||||
wl.release();
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
log(dc, "onDestroy - not finishing");
|
||||
}
|
||||
}
|
||||
|
||||
private void logMemory(String caller)
|
||||
{
|
||||
DoCommand dc = new DoCommand(getApplication());
|
||||
if (dc != null)
|
||||
{
|
||||
log(dc, caller);
|
||||
log(dc, dc.GetMemoryInfo());
|
||||
String procInfo = dc.GetProcessInfo();
|
||||
if (procInfo != null)
|
||||
{
|
||||
String lines[] = procInfo.split("\n");
|
||||
for (String line : lines)
|
||||
{
|
||||
if (line.contains("mozilla"))
|
||||
{
|
||||
log(dc, line);
|
||||
String words[] = line.split("\t");
|
||||
if ((words != null) && (words.length > 1))
|
||||
{
|
||||
log(dc, dc.StatProcess(words[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.e("SUTAgentAndroid", "logMemory: unable to log to file!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory()
|
||||
{
|
||||
System.gc();
|
||||
logMemory("onLowMemory");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTrimMemory(int level)
|
||||
{
|
||||
System.gc();
|
||||
logMemory("onTrimMemory"+level);
|
||||
}
|
||||
|
||||
private void monitorBatteryState()
|
||||
{
|
||||
battReceiver = new BroadcastReceiver()
|
||||
{
|
||||
public void onReceive(Context context, Intent intent)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int rawlevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); // charge level from 0 to scale inclusive
|
||||
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); // Max value for charge level
|
||||
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
|
||||
int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1);
|
||||
boolean present = intent.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false);
|
||||
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); //0 if the device is not plugged in; 1 if plugged into an AC power adapter; 2 if plugged in via USB.
|
||||
// int voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1); // voltage in millivolts
|
||||
nBatteryTemp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1); // current battery temperature in tenths of a degree Centigrade
|
||||
// String technology = intent.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY);
|
||||
|
||||
nChargeLevel = -1; // percentage, or -1 for unknown
|
||||
if (rawlevel >= 0 && scale > 0)
|
||||
{
|
||||
nChargeLevel = (rawlevel * 100) / scale;
|
||||
}
|
||||
|
||||
if (plugged > 0)
|
||||
sACStatus = "ONLINE";
|
||||
else
|
||||
sACStatus = "OFFLINE";
|
||||
|
||||
if (present == false)
|
||||
sb.append("NO BATTERY");
|
||||
else
|
||||
{
|
||||
if (nChargeLevel < 10)
|
||||
sb.append("Critical");
|
||||
else if (nChargeLevel < 33)
|
||||
sb.append("LOW");
|
||||
else if (nChargeLevel > 80)
|
||||
sb.append("HIGH");
|
||||
}
|
||||
|
||||
if (BatteryManager.BATTERY_HEALTH_OVERHEAT == health)
|
||||
{
|
||||
sb.append("Overheated ");
|
||||
sb.append((((float)(nBatteryTemp))/10));
|
||||
sb.append("(C)");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
case BatteryManager.BATTERY_STATUS_UNKNOWN:
|
||||
// old emulator; maybe also when plugged in with no battery
|
||||
if (present == true)
|
||||
sb.append(" UNKNOWN");
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_CHARGING:
|
||||
sb.append(" CHARGING");
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_DISCHARGING:
|
||||
sb.append(" DISCHARGING");
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
|
||||
sb.append(" NOTCHARGING");
|
||||
break;
|
||||
case BatteryManager.BATTERY_STATUS_FULL:
|
||||
sb.append(" FULL");
|
||||
break;
|
||||
default:
|
||||
if (present == true)
|
||||
sb.append("Unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sPowerStatus = sb.toString();
|
||||
}
|
||||
};
|
||||
|
||||
IntentFilter battFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
|
||||
registerReceiver(battReceiver, battFilter);
|
||||
}
|
||||
|
||||
public boolean setUpNetwork(String sIniFile)
|
||||
{
|
||||
boolean bRet = false;
|
||||
int lcv = 0;
|
||||
int lcv2 = 0;
|
||||
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
|
||||
WifiConfiguration wc = new WifiConfiguration();
|
||||
DoCommand tmpdc = new DoCommand(getApplication());
|
||||
|
||||
String ssid = tmpdc.GetIniData("Network Settings", "SSID", sIniFile);
|
||||
String auth = tmpdc.GetIniData("Network Settings", "AUTH", sIniFile);
|
||||
String encr = tmpdc.GetIniData("Network Settings", "ENCR", sIniFile);
|
||||
String key = tmpdc.GetIniData("Network Settings", "KEY", sIniFile);
|
||||
String eap = tmpdc.GetIniData("Network Settings", "EAP", sIniFile);
|
||||
String adhoc = tmpdc.GetIniData("Network Settings", "ADHOC", sIniFile);
|
||||
|
||||
Toast.makeText(getApplication().getApplicationContext(), "Starting and configuring network", Toast.LENGTH_LONG).show();
|
||||
/*
|
||||
ContentResolver cr = getContentResolver();
|
||||
int nRet;
|
||||
try {
|
||||
nRet = Settings.System.getInt(cr, Settings.System.WIFI_USE_STATIC_IP);
|
||||
String foo2 = "" + nRet;
|
||||
} catch (SettingNotFoundException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
*/
|
||||
/*
|
||||
wc.SSID = "\"Mozilla-Build\"";
|
||||
wc.preSharedKey = "\"MozillaBuildQA500\"";
|
||||
wc.hiddenSSID = true;
|
||||
wc.status = WifiConfiguration.Status.ENABLED;
|
||||
wc.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
|
||||
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
|
||||
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
|
||||
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
|
||||
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
|
||||
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
|
||||
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
|
||||
*/
|
||||
wc.SSID = "\"" + ssid + "\"";
|
||||
// wc.SSID = "\"Mozilla-G\"";
|
||||
// wc.SSID = "\"Mozilla\"";
|
||||
|
||||
if (auth.contentEquals("wpa2"))
|
||||
{
|
||||
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
|
||||
wc.preSharedKey = null;
|
||||
}
|
||||
|
||||
if (encr.contentEquals("aes"))
|
||||
{
|
||||
wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
|
||||
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
|
||||
}
|
||||
|
||||
if (eap.contentEquals("peap"))
|
||||
{
|
||||
wc.eap.setValue("PEAP");
|
||||
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
|
||||
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
|
||||
}
|
||||
|
||||
wc.status = WifiConfiguration.Status.ENABLED;
|
||||
|
||||
if (!wifi.isWifiEnabled())
|
||||
wifi.setWifiEnabled(true);
|
||||
|
||||
while(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLED)
|
||||
{
|
||||
Thread.yield();
|
||||
if (++lcv > 10000)
|
||||
return(bRet);
|
||||
}
|
||||
|
||||
wl = wifi.createWifiLock(WifiManager.WIFI_MODE_FULL, "SUTAgent");
|
||||
if (wl != null)
|
||||
wl.acquire();
|
||||
|
||||
WifiConfiguration foo = null;
|
||||
int nNetworkID = -1;
|
||||
|
||||
List<WifiConfiguration> connsLst = wifi.getConfiguredNetworks();
|
||||
int nConns = connsLst.size();
|
||||
for (int i = 0; i < nConns; i++)
|
||||
{
|
||||
|
||||
foo = connsLst.get(i);
|
||||
if (foo.SSID.equalsIgnoreCase(wc.SSID))
|
||||
{
|
||||
nNetworkID = foo.networkId;
|
||||
wc.networkId = foo.networkId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int res;
|
||||
|
||||
if (nNetworkID != -1)
|
||||
{
|
||||
res = wifi.updateNetwork(wc);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = wifi.addNetwork(wc);
|
||||
}
|
||||
|
||||
Log.d("WifiPreference", "add Network returned " + res );
|
||||
|
||||
boolean b = wifi.enableNetwork(res, true);
|
||||
Log.d("WifiPreference", "enableNetwork returned " + b );
|
||||
|
||||
wifi.saveConfiguration();
|
||||
|
||||
WifiInfo wi = wifi.getConnectionInfo();
|
||||
SupplicantState ss = wi.getSupplicantState();
|
||||
|
||||
lcv = 0;
|
||||
lcv2 = 0;
|
||||
|
||||
while (ss.compareTo(SupplicantState.COMPLETED) != 0)
|
||||
{
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (wi != null)
|
||||
wi = null;
|
||||
if (ss != null)
|
||||
ss = null;
|
||||
wi = wifi.getConnectionInfo();
|
||||
ss = wi.getSupplicantState();
|
||||
if (++lcv > 60)
|
||||
{
|
||||
if (++lcv2 > 5)
|
||||
{
|
||||
Toast.makeText(getApplication().getApplicationContext(), "Unable to start and configure network", Toast.LENGTH_LONG).show();
|
||||
return(bRet);
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(getApplication().getApplicationContext(), "Resetting wifi interface", Toast.LENGTH_LONG).show();
|
||||
if (wl != null)
|
||||
wl.release();
|
||||
wifi.setWifiEnabled(false);
|
||||
while(wifi.getWifiState() != WifiManager.WIFI_STATE_DISABLED)
|
||||
{
|
||||
Thread.yield();
|
||||
}
|
||||
|
||||
wifi.setWifiEnabled(true);
|
||||
while(wifi.getWifiState() != WifiManager.WIFI_STATE_ENABLED)
|
||||
{
|
||||
Thread.yield();
|
||||
}
|
||||
b = wifi.enableNetwork(res, true);
|
||||
Log.d("WifiPreference", "enableNetwork returned " + b );
|
||||
if (wl != null)
|
||||
wl.acquire();
|
||||
lcv = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lcv = 0;
|
||||
while(getLocalIpAddress() == null)
|
||||
{
|
||||
if (++lcv > 10000)
|
||||
return(bRet);
|
||||
}
|
||||
|
||||
Toast.makeText(getApplication().getApplicationContext(), "Network started and configured", Toast.LENGTH_LONG).show();
|
||||
bRet = true;
|
||||
|
||||
return(bRet);
|
||||
}
|
||||
|
||||
// If there is an update.info file callback the server and send the status
|
||||
private Runnable doUpdateCallback = new Runnable() {
|
||||
public void run() {
|
||||
DoCommand dc = new DoCommand(getApplication());
|
||||
String sRet = dc.UpdateCallBack("update.info");
|
||||
if (sRet.length() > 0) {
|
||||
if (sRet.contains("ok")) {
|
||||
sRet = "Callback Server contacted successfully" + lineSep;
|
||||
} else if (sRet.contains("Nothing to do")) {
|
||||
sRet = "";
|
||||
} else {
|
||||
sRet = "Callback Server NOT contacted successfully" + lineSep;
|
||||
}
|
||||
}
|
||||
if (sRet.length() > 0)
|
||||
mHandler.post(new UpdateStatus(sRet));
|
||||
dc = null;
|
||||
}
|
||||
};
|
||||
|
||||
// registers with the reg server defined in the SUTAgent.ini file
|
||||
private Runnable doRegisterDevice = new Runnable() {
|
||||
public void run() {
|
||||
DoCommand dc = new DoCommand(getApplication());
|
||||
String sRet = "";
|
||||
if (RegSvrIPAddr.length() > 0) {
|
||||
String sRegRet = dc.RegisterTheDevice(RegSvrIPAddr, RegSvrIPPort, sRegString);
|
||||
if (sRegRet.contains("ok")) {
|
||||
sRet += "Registered with testserver" + lineSep;
|
||||
sRet += "\tIPAddress: " + RegSvrIPAddr + lineSep;
|
||||
if (RegSvrIPPort.length() > 0)
|
||||
sRet += "\tPort: " + RegSvrIPPort + lineSep;
|
||||
} else {
|
||||
sRet += "Not registered with testserver" + lineSep;
|
||||
}
|
||||
} else {
|
||||
sRet += "Not registered with testserver" + lineSep;
|
||||
}
|
||||
|
||||
if (sRet.length() > 0)
|
||||
mHandler.post(new UpdateStatus(sRet));
|
||||
dc = null;
|
||||
}
|
||||
};
|
||||
|
||||
// this starts the listener service for the command and data channels
|
||||
private Runnable doStartService = new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
Intent listenerService = new Intent();
|
||||
listenerService.setAction("com.mozilla.SUTAgentAndroid.service.LISTENER_SERVICE");
|
||||
startService(listenerService);
|
||||
}
|
||||
};
|
||||
|
||||
static String sHWID = null;
|
||||
public static String getHWID(Context cx) {
|
||||
if (sHWID != null)
|
||||
return sHWID;
|
||||
|
||||
// If we're on SDK version > 8, use Build.SERIAL
|
||||
if (android.os.Build.VERSION.SDK_INT > 8) {
|
||||
sHWID = android.os.Build.SERIAL;
|
||||
}
|
||||
|
||||
if (sHWID != null)
|
||||
return sHWID;
|
||||
|
||||
// Otherwise, try from the telephony manager
|
||||
TelephonyManager mTelephonyMgr = (TelephonyManager) cx.getSystemService(TELEPHONY_SERVICE);
|
||||
if (mTelephonyMgr != null) {
|
||||
sHWID = mTelephonyMgr.getDeviceId();
|
||||
}
|
||||
|
||||
if (sHWID != null)
|
||||
return sHWID;
|
||||
|
||||
// Otherwise, try WIFI_SERVICE and use the wifi manager
|
||||
WifiManager wifiMan = (WifiManager) cx.getSystemService(Context.WIFI_SERVICE);
|
||||
if (wifiMan != null) {
|
||||
WifiInfo wifi = wifiMan.getConnectionInfo();
|
||||
if (wifi != null) {
|
||||
sHWID = "wifimac" + wifi.getMacAddress();
|
||||
}
|
||||
}
|
||||
|
||||
if (sHWID != null)
|
||||
return sHWID;
|
||||
|
||||
sHWID = "0011223344556677";
|
||||
|
||||
return sHWID;
|
||||
}
|
||||
|
||||
public static boolean isIPv4Address(final String input) {
|
||||
return IPV4_PATTERN.matcher(input).matches();
|
||||
}
|
||||
|
||||
public static InetAddress getLocalInetAddress() throws SocketException
|
||||
{
|
||||
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
|
||||
{
|
||||
NetworkInterface intf = en.nextElement();
|
||||
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
|
||||
{
|
||||
InetAddress inetAddress = enumIpAddr.nextElement();
|
||||
if (!inetAddress.isLoopbackAddress() && isIPv4Address(inetAddress.getHostAddress()))
|
||||
{
|
||||
return inetAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getLocalIpAddress()
|
||||
{
|
||||
try {
|
||||
InetAddress inetAddress = getLocalInetAddress();
|
||||
if (inetAddress != null)
|
||||
return inetAddress.getHostAddress().toString();
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
Toast.makeText(getApplication().getApplicationContext(), ex.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void log(DoCommand dc, String message)
|
||||
{
|
||||
Log.i("SUTAgentAndroid", message);
|
||||
|
||||
if (SUTAgentAndroid.LogCommands == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
Log.e("SUTAgentAndroid", "bad arguments in log()!");
|
||||
return;
|
||||
}
|
||||
String fileDateStr = "00";
|
||||
String testRoot = dc.GetTestRoot();
|
||||
String datestamp = dc.GetSystemTime();
|
||||
if (testRoot == null || datestamp == null)
|
||||
{
|
||||
Log.e("SUTAgentAndroid", "Unable to get testRoot or datestamp in log!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
|
||||
Date dateStr = sdf.parse(datestamp);
|
||||
SimpleDateFormat sdf_file = new SimpleDateFormat("yyyy-MM-dd");
|
||||
fileDateStr = sdf_file.format(dateStr);
|
||||
}
|
||||
catch (ParseException pe) {}
|
||||
String logFile = testRoot + "/" + fileDateStr + "-sutcommands.txt";
|
||||
PrintWriter pw = null;
|
||||
try
|
||||
{
|
||||
pw = new PrintWriter(new FileWriter(logFile, true));
|
||||
pw.println(datestamp + " : " + message);
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
Log.e("SUTAgentAndroid", "exception with file writer on: " + logFile);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (pw != null)
|
||||
{
|
||||
pw.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,480 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net.wifi;
|
||||
|
||||
import android.os.Parcelable;
|
||||
import android.os.Parcel;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
/**
|
||||
* A class representing a configured Wi-Fi network, including the
|
||||
* security configuration. Android will not necessarily support
|
||||
* all of these security schemes initially.
|
||||
*/
|
||||
public class WifiConfiguration implements Parcelable {
|
||||
|
||||
/** {@hide} */
|
||||
public static final String ssidVarName = "ssid";
|
||||
/** {@hide} */
|
||||
public static final String bssidVarName = "bssid";
|
||||
/** {@hide} */
|
||||
public static final String pskVarName = "psk";
|
||||
/** {@hide} */
|
||||
public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" };
|
||||
/** {@hide} */
|
||||
public static final String wepTxKeyIdxVarName = "wep_tx_keyidx";
|
||||
/** {@hide} */
|
||||
public static final String priorityVarName = "priority";
|
||||
/** {@hide} */
|
||||
public static final String hiddenSSIDVarName = "scan_ssid";
|
||||
|
||||
public class EnterpriseField {
|
||||
private String varName;
|
||||
private String value;
|
||||
|
||||
private EnterpriseField(String varName) {
|
||||
this.varName = varName;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String varName() {
|
||||
return varName;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public EnterpriseField eap = new EnterpriseField("eap");
|
||||
public EnterpriseField phase2 = new EnterpriseField("phase2");
|
||||
public EnterpriseField identity = new EnterpriseField("identity");
|
||||
public EnterpriseField anonymous_identity = new EnterpriseField("anonymous_identity");
|
||||
public EnterpriseField password = new EnterpriseField("password");
|
||||
public EnterpriseField client_cert = new EnterpriseField("client_cert");
|
||||
public EnterpriseField private_key = new EnterpriseField("private_key");
|
||||
public EnterpriseField ca_cert = new EnterpriseField("ca_cert");
|
||||
|
||||
public EnterpriseField[] enterpriseFields = {
|
||||
eap, phase2, identity, anonymous_identity, password, client_cert,
|
||||
private_key, ca_cert };
|
||||
|
||||
/**
|
||||
* Recognized key management schemes.
|
||||
*/
|
||||
public static class KeyMgmt {
|
||||
private KeyMgmt() { }
|
||||
|
||||
/** WPA is not used; plaintext or static WEP could be used. */
|
||||
public static final int NONE = 0;
|
||||
/** WPA pre-shared key (requires {@code preSharedKey} to be specified). */
|
||||
public static final int WPA_PSK = 1;
|
||||
/** WPA using EAP authentication. Generally used with an external authentication server. */
|
||||
public static final int WPA_EAP = 2;
|
||||
/** IEEE 802.1X using EAP authentication and (optionally) dynamically
|
||||
* generated WEP keys. */
|
||||
public static final int IEEE8021X = 3;
|
||||
|
||||
public static final String varName = "key_mgmt";
|
||||
|
||||
public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Recognized security protocols.
|
||||
*/
|
||||
public static class Protocol {
|
||||
private Protocol() { }
|
||||
|
||||
/** WPA/IEEE 802.11i/D3.0 */
|
||||
public static final int WPA = 0;
|
||||
/** WPA2/IEEE 802.11i */
|
||||
public static final int RSN = 1;
|
||||
|
||||
public static final String varName = "proto";
|
||||
|
||||
public static final String[] strings = { "WPA", "RSN" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Recognized IEEE 802.11 authentication algorithms.
|
||||
*/
|
||||
public static class AuthAlgorithm {
|
||||
private AuthAlgorithm() { }
|
||||
|
||||
/** Open System authentication (required for WPA/WPA2) */
|
||||
public static final int OPEN = 0;
|
||||
/** Shared Key authentication (requires static WEP keys) */
|
||||
public static final int SHARED = 1;
|
||||
/** LEAP/Network EAP (only used with LEAP) */
|
||||
public static final int LEAP = 2;
|
||||
|
||||
public static final String varName = "auth_alg";
|
||||
|
||||
public static final String[] strings = { "OPEN", "SHARED", "LEAP" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Recognized pairwise ciphers for WPA.
|
||||
*/
|
||||
public static class PairwiseCipher {
|
||||
private PairwiseCipher() { }
|
||||
|
||||
/** Use only Group keys (deprecated) */
|
||||
public static final int NONE = 0;
|
||||
/** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
|
||||
public static final int TKIP = 1;
|
||||
/** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
|
||||
public static final int CCMP = 2;
|
||||
|
||||
public static final String varName = "pairwise";
|
||||
|
||||
public static final String[] strings = { "NONE", "TKIP", "CCMP" };
|
||||
}
|
||||
|
||||
/**
|
||||
* Recognized group ciphers.
|
||||
* <pre>
|
||||
* CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
|
||||
* TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
|
||||
* WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
|
||||
* WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
|
||||
* </pre>
|
||||
*/
|
||||
public static class GroupCipher {
|
||||
private GroupCipher() { }
|
||||
|
||||
/** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) */
|
||||
public static final int WEP40 = 0;
|
||||
/** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key */
|
||||
public static final int WEP104 = 1;
|
||||
/** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
|
||||
public static final int TKIP = 2;
|
||||
/** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
|
||||
public static final int CCMP = 3;
|
||||
|
||||
public static final String varName = "group";
|
||||
|
||||
public static final String[] strings = { "WEP40", "WEP104", "TKIP", "CCMP" };
|
||||
}
|
||||
|
||||
/** Possible status of a network configuration. */
|
||||
public static class Status {
|
||||
private Status() { }
|
||||
|
||||
/** this is the network we are currently connected to */
|
||||
public static final int CURRENT = 0;
|
||||
/** supplicant will not attempt to use this network */
|
||||
public static final int DISABLED = 1;
|
||||
/** supplicant will consider this network available for association */
|
||||
public static final int ENABLED = 2;
|
||||
|
||||
public static final String[] strings = { "current", "disabled", "enabled" };
|
||||
}
|
||||
|
||||
/**
|
||||
* The ID number that the supplicant uses to identify this
|
||||
* network configuration entry. This must be passed as an argument
|
||||
* to most calls into the supplicant.
|
||||
*/
|
||||
public int networkId;
|
||||
|
||||
/**
|
||||
* The current status of this network configuration entry.
|
||||
* @see Status
|
||||
*/
|
||||
public int status;
|
||||
/**
|
||||
* The network's SSID. Can either be an ASCII string,
|
||||
* which must be enclosed in double quotation marks
|
||||
* (e.g., {@code "MyNetwork"}, or a string of
|
||||
* hex digits,which are not enclosed in quotes
|
||||
* (e.g., {@code 01a243f405}).
|
||||
*/
|
||||
public String SSID;
|
||||
/**
|
||||
* When set, this network configuration entry should only be used when
|
||||
* associating with the AP having the specified BSSID. The value is
|
||||
* a string in the format of an Ethernet MAC address, e.g.,
|
||||
* <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
|
||||
*/
|
||||
public String BSSID;
|
||||
|
||||
/**
|
||||
* Pre-shared key for use with WPA-PSK.
|
||||
* <p/>
|
||||
* When the value of this key is read, the actual key is
|
||||
* not returned, just a "*" if the key has a value, or the null
|
||||
* string otherwise.
|
||||
*/
|
||||
public String preSharedKey;
|
||||
/**
|
||||
* Up to four WEP keys. Either an ASCII string enclosed in double
|
||||
* quotation marks (e.g., {@code "abcdef"} or a string
|
||||
* of hex digits (e.g., {@code 0102030405}).
|
||||
* <p/>
|
||||
* When the value of one of these keys is read, the actual key is
|
||||
* not returned, just a "*" if the key has a value, or the null
|
||||
* string otherwise.
|
||||
*/
|
||||
public String[] wepKeys;
|
||||
|
||||
/** Default WEP key index, ranging from 0 to 3. */
|
||||
public int wepTxKeyIndex;
|
||||
|
||||
/**
|
||||
* Priority determines the preference given to a network by {@code wpa_supplicant}
|
||||
* when choosing an access point with which to associate.
|
||||
*/
|
||||
public int priority;
|
||||
|
||||
/**
|
||||
* This is a network that does not broadcast its SSID, so an
|
||||
* SSID-specific probe request must be used for scans.
|
||||
*/
|
||||
public boolean hiddenSSID;
|
||||
|
||||
/**
|
||||
* The set of key management protocols supported by this configuration.
|
||||
* See {@link KeyMgmt} for descriptions of the values.
|
||||
* Defaults to WPA-PSK WPA-EAP.
|
||||
*/
|
||||
public BitSet allowedKeyManagement;
|
||||
/**
|
||||
* The set of security protocols supported by this configuration.
|
||||
* See {@link Protocol} for descriptions of the values.
|
||||
* Defaults to WPA RSN.
|
||||
*/
|
||||
public BitSet allowedProtocols;
|
||||
/**
|
||||
* The set of authentication protocols supported by this configuration.
|
||||
* See {@link AuthAlgorithm} for descriptions of the values.
|
||||
* Defaults to automatic selection.
|
||||
*/
|
||||
public BitSet allowedAuthAlgorithms;
|
||||
/**
|
||||
* The set of pairwise ciphers for WPA supported by this configuration.
|
||||
* See {@link PairwiseCipher} for descriptions of the values.
|
||||
* Defaults to CCMP TKIP.
|
||||
*/
|
||||
public BitSet allowedPairwiseCiphers;
|
||||
/**
|
||||
* The set of group ciphers supported by this configuration.
|
||||
* See {@link GroupCipher} for descriptions of the values.
|
||||
* Defaults to CCMP TKIP WEP104 WEP40.
|
||||
*/
|
||||
public BitSet allowedGroupCiphers;
|
||||
|
||||
|
||||
public WifiConfiguration() {
|
||||
networkId = -1;
|
||||
SSID = null;
|
||||
BSSID = null;
|
||||
priority = 0;
|
||||
hiddenSSID = false;
|
||||
allowedKeyManagement = new BitSet();
|
||||
allowedProtocols = new BitSet();
|
||||
allowedAuthAlgorithms = new BitSet();
|
||||
allowedPairwiseCiphers = new BitSet();
|
||||
allowedGroupCiphers = new BitSet();
|
||||
wepKeys = new String[4];
|
||||
for (int i = 0; i < wepKeys.length; i++)
|
||||
wepKeys[i] = null;
|
||||
for (EnterpriseField field : enterpriseFields) {
|
||||
field.setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
if (this.status == WifiConfiguration.Status.CURRENT) {
|
||||
sbuf.append("* ");
|
||||
} else if (this.status == WifiConfiguration.Status.DISABLED) {
|
||||
sbuf.append("- ");
|
||||
}
|
||||
sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).
|
||||
append(" BSSID: ").append(this.BSSID).append(" PRIO: ").append(this.priority).
|
||||
append('\n');
|
||||
sbuf.append(" KeyMgmt:");
|
||||
for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
|
||||
if (this.allowedKeyManagement.get(k)) {
|
||||
sbuf.append(" ");
|
||||
if (k < KeyMgmt.strings.length) {
|
||||
sbuf.append(KeyMgmt.strings[k]);
|
||||
} else {
|
||||
sbuf.append("??");
|
||||
}
|
||||
}
|
||||
}
|
||||
sbuf.append(" Protocols:");
|
||||
for (int p = 0; p < this.allowedProtocols.size(); p++) {
|
||||
if (this.allowedProtocols.get(p)) {
|
||||
sbuf.append(" ");
|
||||
if (p < Protocol.strings.length) {
|
||||
sbuf.append(Protocol.strings[p]);
|
||||
} else {
|
||||
sbuf.append("??");
|
||||
}
|
||||
}
|
||||
}
|
||||
sbuf.append('\n');
|
||||
sbuf.append(" AuthAlgorithms:");
|
||||
for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) {
|
||||
if (this.allowedAuthAlgorithms.get(a)) {
|
||||
sbuf.append(" ");
|
||||
if (a < AuthAlgorithm.strings.length) {
|
||||
sbuf.append(AuthAlgorithm.strings[a]);
|
||||
} else {
|
||||
sbuf.append("??");
|
||||
}
|
||||
}
|
||||
}
|
||||
sbuf.append('\n');
|
||||
sbuf.append(" PairwiseCiphers:");
|
||||
for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) {
|
||||
if (this.allowedPairwiseCiphers.get(pc)) {
|
||||
sbuf.append(" ");
|
||||
if (pc < PairwiseCipher.strings.length) {
|
||||
sbuf.append(PairwiseCipher.strings[pc]);
|
||||
} else {
|
||||
sbuf.append("??");
|
||||
}
|
||||
}
|
||||
}
|
||||
sbuf.append('\n');
|
||||
sbuf.append(" GroupCiphers:");
|
||||
for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) {
|
||||
if (this.allowedGroupCiphers.get(gc)) {
|
||||
sbuf.append(" ");
|
||||
if (gc < GroupCipher.strings.length) {
|
||||
sbuf.append(GroupCipher.strings[gc]);
|
||||
} else {
|
||||
sbuf.append("??");
|
||||
}
|
||||
}
|
||||
}
|
||||
sbuf.append('\n').append(" PSK: ");
|
||||
if (this.preSharedKey != null) {
|
||||
sbuf.append('*');
|
||||
}
|
||||
|
||||
for (EnterpriseField field : enterpriseFields) {
|
||||
sbuf.append('\n').append(" " + field.varName() + ": ");
|
||||
String value = field.value();
|
||||
if (value != null) sbuf.append(value);
|
||||
}
|
||||
sbuf.append('\n');
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a WifiConfiguration from a scanned network
|
||||
* @param scannedAP the scan result used to construct the config entry
|
||||
* TODO: figure out whether this is a useful way to construct a new entry.
|
||||
*
|
||||
public WifiConfiguration(ScanResult scannedAP) {
|
||||
networkId = -1;
|
||||
SSID = scannedAP.SSID;
|
||||
BSSID = scannedAP.BSSID;
|
||||
}
|
||||
*/
|
||||
|
||||
private static BitSet readBitSet(Parcel src) {
|
||||
int cardinality = src.readInt();
|
||||
|
||||
BitSet set = new BitSet();
|
||||
for (int i = 0; i < cardinality; i++)
|
||||
set.set(src.readInt());
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
private static void writeBitSet(Parcel dest, BitSet set) {
|
||||
int nextSetBit = -1;
|
||||
|
||||
dest.writeInt(set.cardinality());
|
||||
|
||||
while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1)
|
||||
dest.writeInt(nextSetBit);
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface {@hide} */
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface {@hide} */
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(networkId);
|
||||
dest.writeInt(status);
|
||||
dest.writeString(SSID);
|
||||
dest.writeString(BSSID);
|
||||
dest.writeString(preSharedKey);
|
||||
for (String wepKey : wepKeys)
|
||||
dest.writeString(wepKey);
|
||||
dest.writeInt(wepTxKeyIndex);
|
||||
dest.writeInt(priority);
|
||||
dest.writeInt(hiddenSSID ? 1 : 0);
|
||||
|
||||
writeBitSet(dest, allowedKeyManagement);
|
||||
writeBitSet(dest, allowedProtocols);
|
||||
writeBitSet(dest, allowedAuthAlgorithms);
|
||||
writeBitSet(dest, allowedPairwiseCiphers);
|
||||
writeBitSet(dest, allowedGroupCiphers);
|
||||
|
||||
for (EnterpriseField field : enterpriseFields) {
|
||||
dest.writeString(field.value());
|
||||
}
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface {@hide} */
|
||||
public static final Creator<WifiConfiguration> CREATOR =
|
||||
new Creator<WifiConfiguration>() {
|
||||
public WifiConfiguration createFromParcel(Parcel in) {
|
||||
WifiConfiguration config = new WifiConfiguration();
|
||||
config.networkId = in.readInt();
|
||||
config.status = in.readInt();
|
||||
config.SSID = in.readString();
|
||||
config.BSSID = in.readString();
|
||||
config.preSharedKey = in.readString();
|
||||
for (int i = 0; i < config.wepKeys.length; i++)
|
||||
config.wepKeys[i] = in.readString();
|
||||
config.wepTxKeyIndex = in.readInt();
|
||||
config.priority = in.readInt();
|
||||
config.hiddenSSID = in.readInt() != 0;
|
||||
config.allowedKeyManagement = readBitSet(in);
|
||||
config.allowedProtocols = readBitSet(in);
|
||||
config.allowedAuthAlgorithms = readBitSet(in);
|
||||
config.allowedPairwiseCiphers = readBitSet(in);
|
||||
config.allowedGroupCiphers = readBitSet(in);
|
||||
|
||||
for (EnterpriseField field : config.enterpriseFields) {
|
||||
field.setValue(in.readString());
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
public WifiConfiguration[] newArray(int size) {
|
||||
return new WifiConfiguration[size];
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Indicates whether an apk should be generated for each density.
|
||||
split.density=false
|
||||
# Project target.
|
||||
target=android-5
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.fencp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" android:sharedUserId="org.mozilla.fennec.sharedID">
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
|
||||
<activity android:label="@string/app_name" android:name="FenCP">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider android:name="FenCPFP"
|
||||
android:enabled="true"
|
||||
android:authorities="org.mozilla.fencp"
|
||||
android:exported="true">
|
||||
</provider>
|
||||
</application>
|
||||
<uses-sdk android:minSdkVersion="6" />
|
||||
|
||||
</manifest>
|
|
@ -1,175 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.fencp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.database.MatrixCursor;
|
||||
|
||||
public class DirCursor extends MatrixCursor {
|
||||
public static final String _ID = "_id";
|
||||
public static final String ISDIR = "isdir";
|
||||
public static final String FILENAME = "filename";
|
||||
public static final String LENGTH = "length";
|
||||
public static final String TIMESTAMP = "ts";
|
||||
public static final String WRITABLE = "writable";
|
||||
static final String[] DEFCOLUMNS = new String[] {
|
||||
_ID,
|
||||
ISDIR,
|
||||
FILENAME,
|
||||
LENGTH,
|
||||
TIMESTAMP,
|
||||
WRITABLE
|
||||
};
|
||||
private String dirPath = null;
|
||||
private String [] theColumns = null;
|
||||
|
||||
public DirCursor(String[] columnNames, String sPath) {
|
||||
super((columnNames == null ? DEFCOLUMNS : columnNames));
|
||||
theColumns = (columnNames == null ? DEFCOLUMNS : columnNames);
|
||||
dirPath = sPath;
|
||||
doLoadCursor(dirPath);
|
||||
}
|
||||
|
||||
public DirCursor(String[] columnNames, int initialCapacity, String sPath) {
|
||||
super((columnNames == null ? DEFCOLUMNS : columnNames), initialCapacity);
|
||||
theColumns = (columnNames == null ? DEFCOLUMNS : columnNames);
|
||||
dirPath = sPath;
|
||||
doLoadCursor(dirPath);
|
||||
}
|
||||
|
||||
private void doLoadCursor(String sDir) {
|
||||
File dir = new File(sDir);
|
||||
int nFiles = 0;
|
||||
int nCols = theColumns.length;
|
||||
int lcvFiles = 0;
|
||||
int nCIndex = 0;
|
||||
Object [] vals = new Object[nCols];
|
||||
|
||||
if (dir.isDirectory()) {
|
||||
try {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = -1;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 1;
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
try {
|
||||
vals[nCIndex] = dir.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
vals[nCIndex] = dir.getName();
|
||||
}
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(TIMESTAMP);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(WRITABLE);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = (dir.canWrite() ? 1 : 0);
|
||||
|
||||
addRow(vals);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
|
||||
File [] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
if ((nFiles = files.length) > 0) {
|
||||
for (lcvFiles = 0; lcvFiles < nFiles; lcvFiles++) {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = lcvFiles;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = (files[lcvFiles].isDirectory() ? 1 : 0);
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = files[lcvFiles].getName();
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = (files[lcvFiles].isDirectory() ? -1 : files[lcvFiles].length());
|
||||
|
||||
try {
|
||||
addRow(vals);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dir.isFile()) {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = -1;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = dir.getName();
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = dir.length();
|
||||
|
||||
nCIndex = getColumnIndex(TIMESTAMP);
|
||||
if (nCIndex > -1) {
|
||||
vals[nCIndex] = dir.lastModified();
|
||||
}
|
||||
|
||||
try {
|
||||
addRow(vals);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = -1;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = null;
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(TIMESTAMP);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
addRow(vals);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.fencp;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class FenCP extends Activity {
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.fencp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
public class FenCPFP extends ContentProvider {
|
||||
public static final String PROVIDER_NAME = "org.mozilla.fencp";
|
||||
public static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/file");
|
||||
|
||||
public static final String _ID = "_id";
|
||||
public static final String ISDIR = "isdir";
|
||||
public static final String FILENAME = "filename";
|
||||
public static final String LENGTH = "length";
|
||||
public static final String CHUNK = "chunk";
|
||||
static String[] dircolumns = new String[] {
|
||||
_ID,
|
||||
ISDIR,
|
||||
FILENAME,
|
||||
LENGTH
|
||||
};
|
||||
|
||||
static String[] filecolumns = new String[] {
|
||||
_ID,
|
||||
CHUNK
|
||||
};
|
||||
|
||||
private static final int DIR = 1;
|
||||
private static final int FILE_NAME = 2;
|
||||
|
||||
private static final UriMatcher uriMatcher;
|
||||
static {
|
||||
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
uriMatcher.addURI(PROVIDER_NAME, "dir", DIR);
|
||||
uriMatcher.addURI(PROVIDER_NAME, "file", FILE_NAME);
|
||||
}
|
||||
|
||||
public int PruneDir(String sTmpDir) {
|
||||
int nRet = 0;
|
||||
int nFiles = 0;
|
||||
String sSubDir = null;
|
||||
|
||||
File dir = new File(sTmpDir);
|
||||
|
||||
if (dir.isDirectory()) {
|
||||
File [] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
if ((nFiles = files.length) > 0) {
|
||||
for (int lcv = 0; lcv < nFiles; lcv++) {
|
||||
if (files[lcv].isDirectory()) {
|
||||
sSubDir = files[lcv].getAbsolutePath();
|
||||
nRet += PruneDir(sSubDir);
|
||||
}
|
||||
else {
|
||||
if (files[lcv].delete()) {
|
||||
nRet++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dir.delete()) {
|
||||
nRet++;
|
||||
}
|
||||
if ((nFiles + 1) > nRet) {
|
||||
nRet = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return(nRet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||
int nFiles = 0;
|
||||
switch (uriMatcher.match(uri)) {
|
||||
case FILE_NAME:
|
||||
File f = new File(selection);
|
||||
if (f.delete())
|
||||
nFiles = 1;
|
||||
break;
|
||||
|
||||
case DIR:
|
||||
nFiles = PruneDir(selection);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri)
|
||||
{
|
||||
switch (uriMatcher.match(uri))
|
||||
{
|
||||
//---get directory---
|
||||
case DIR:
|
||||
return "vnd.android.cursor.dir/vnd.mozilla.dir ";
|
||||
//---get a particular file---
|
||||
case FILE_NAME:
|
||||
return "vnd.android.cursor.item/vnd.mozilla.file ";
|
||||
//---Unknown---
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported URI: " + uri);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues values) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
Cursor retCursor = null;
|
||||
|
||||
switch(uriMatcher.match(uri)) {
|
||||
case DIR:
|
||||
retCursor = new DirCursor(projection, selection);
|
||||
break;
|
||||
|
||||
case FILE_NAME:
|
||||
retCursor = new FileCursor(projection, selection, selectionArgs);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (retCursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||
int nRet = 0;
|
||||
FileOutputStream dstFile = null;
|
||||
|
||||
switch(uriMatcher.match(uri)) {
|
||||
case DIR:
|
||||
File dir = new File(selection);
|
||||
if (dir.mkdirs())
|
||||
nRet = 1;
|
||||
break;
|
||||
|
||||
case FILE_NAME:
|
||||
try {
|
||||
long lOffset = values.getAsLong("offset");
|
||||
byte [] buf = values.getAsByteArray(CHUNK);
|
||||
int nLength = values.getAsInteger(LENGTH);
|
||||
if ((buf != null) && (nLength > 0)) {
|
||||
File f = new File(selection);
|
||||
dstFile = new FileOutputStream(f, (lOffset == 0 ? false : true));
|
||||
dstFile.write(buf,0, nLength);
|
||||
dstFile.flush();
|
||||
dstFile.close();
|
||||
nRet = nLength;
|
||||
}
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
fnfe.printStackTrace();
|
||||
} catch (IOException ioe) {
|
||||
try {
|
||||
dstFile.flush();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
try {
|
||||
dstFile.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.fencp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import android.database.AbstractWindowedCursor;
|
||||
import android.database.CursorWindow;
|
||||
|
||||
public class FileCursor extends AbstractWindowedCursor {
|
||||
public static final String _ID = "_id";
|
||||
public static final String CHUNK = "chunk";
|
||||
public static final String LENGTH = "length";
|
||||
static final String[] DEFCOLUMNS = new String[] {
|
||||
_ID,
|
||||
CHUNK,
|
||||
LENGTH
|
||||
};
|
||||
private String filePath = null;
|
||||
private String [] theColumns = null;
|
||||
|
||||
private static final int BUFSIZE = 4096;
|
||||
private long lFileSize = 0;
|
||||
private int nCount = 0;
|
||||
private File theFile = null;
|
||||
private byte [] theBuffer = null;
|
||||
private long lOffset = 0;
|
||||
private long lLength = -1;
|
||||
|
||||
public FileCursor(String[] columnNames, String sFilePath, String [] selectionArgs) {
|
||||
super();
|
||||
theColumns = (columnNames == null ? DEFCOLUMNS : columnNames);
|
||||
filePath = sFilePath;
|
||||
nCount = -1;
|
||||
|
||||
if ((selectionArgs != null) && (selectionArgs.length > 0)) {
|
||||
lOffset = Long.parseLong(selectionArgs[0]);
|
||||
lLength = Long.parseLong(selectionArgs[1]);
|
||||
}
|
||||
|
||||
if (filePath.length() > 0) {
|
||||
theFile = new File(filePath);
|
||||
if (theFile.exists() && theFile.canRead()) {
|
||||
lFileSize = theFile.length();
|
||||
|
||||
// lLength == -1 return everything between lOffset and eof
|
||||
// lLength == 0 return file length
|
||||
// lLength > 0 return lLength bytes
|
||||
if (lLength == -1) {
|
||||
lFileSize = lFileSize - lOffset;
|
||||
} else if (lLength == 0) {
|
||||
// just return the file length
|
||||
} else {
|
||||
lFileSize = ((lLength <= (lFileSize - lOffset)) ? lLength : (lFileSize - lOffset));
|
||||
}
|
||||
|
||||
if (lLength != 0) {
|
||||
nCount = (int) (lFileSize / BUFSIZE);
|
||||
if ((lFileSize % BUFSIZE) > 0)
|
||||
nCount++;
|
||||
} else {
|
||||
nCount = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getColumnName (int columnIndex) {
|
||||
return theColumns[columnIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getColumnNames() {
|
||||
return theColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return nCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(int oldPosition, int newPosition) {
|
||||
boolean bRet = true;
|
||||
|
||||
// get rid of old data
|
||||
mWindow.clear();
|
||||
bRet = mWindow.setNumColumns(theColumns.length);
|
||||
fillWindow(newPosition, mWindow);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillWindow (int pos, CursorWindow window) {
|
||||
int nNumRows = window.getNumRows();
|
||||
int nCIndex = 0;
|
||||
window.setStartPosition(0);
|
||||
|
||||
if (pos > -1) {
|
||||
if (nNumRows == 0) {
|
||||
window.allocRow();
|
||||
nNumRows = window.getNumRows();
|
||||
}
|
||||
|
||||
if (nNumRows == 1) {
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1) {
|
||||
window.putLong(lFileSize, 0, nCIndex);
|
||||
}
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1) {
|
||||
window.putLong((long)pos, 0, nCIndex);
|
||||
}
|
||||
nCIndex = getColumnIndex(CHUNK);
|
||||
if (nCIndex > -1) {
|
||||
if (lLength != 0) {
|
||||
byte[] value = getABlob (pos, 1);
|
||||
window.putBlob(value, 0, nCIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
window.setStartPosition(pos);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public byte[] getABlob (int row, int column) {
|
||||
int nRead = 0;
|
||||
int nOffset = 0;
|
||||
int nBufSize = 0;
|
||||
|
||||
if ((column == 1) && (theFile != null)) {
|
||||
try {
|
||||
FileInputStream fin = new FileInputStream(theFile);
|
||||
nOffset = row * BUFSIZE;
|
||||
if (row < (nCount - 1)) {
|
||||
nBufSize = BUFSIZE;
|
||||
} else {
|
||||
nBufSize = (int) (lFileSize - nOffset);
|
||||
}
|
||||
theBuffer = new byte[nBufSize];
|
||||
|
||||
if (theBuffer != null) {
|
||||
if (fin.skip(nOffset + lOffset) == (nOffset + lOffset)) {
|
||||
if ((nRead = fin.read(theBuffer, 0, nBufSize)) != -1) {
|
||||
if (nRead != nBufSize) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fin.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return theBuffer;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
JAVAFILES = \
|
||||
DirCursor.java \
|
||||
FenCP.java \
|
||||
FenCPFP.java \
|
||||
FileCursor.java \
|
||||
$(NULL)
|
||||
|
||||
tools:: $(ANDROID_APK_NAME).apk
|
|
@ -1,15 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-6
|
|
@ -1,8 +0,0 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
ANDROID_APK_NAME = 'FenCP'
|
||||
ANDROID_APK_PACKAGE = 'org.mozilla.fencp'
|
Двоичные данные
build/mobile/sutagent/android/fencp/res/drawable-hdpi/icon.png
До Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
build/mobile/sutagent/android/fencp/res/drawable-ldpi/icon.png
До Ширина: | Высота: | Размер: 1.7 KiB |
Двоичные данные
build/mobile/sutagent/android/fencp/res/drawable-mdpi/icon.png
До Ширина: | Высота: | Размер: 2.5 KiB |
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello"
|
||||
/>
|
||||
</LinearLayout>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<resources>
|
||||
<string name="hello">Hello World, FennecCP!</string>
|
||||
<string name="app_name">FennecCP</string>
|
||||
</resources>
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.mozilla.ffxcp"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" android:sharedUserId="org.mozilla.firefox.sharedID">
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true">
|
||||
<activity android:label="@string/app_name" android:name="ffxcp">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider android:name="FfxCPFP"
|
||||
android:enabled="true"
|
||||
android:authorities="org.mozilla.ffxcp"
|
||||
android:exported="true">
|
||||
</provider>
|
||||
</application>
|
||||
<uses-sdk android:minSdkVersion="6" />
|
||||
|
||||
</manifest>
|
|
@ -1,175 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.ffxcp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.database.MatrixCursor;
|
||||
|
||||
public class DirCursor extends MatrixCursor {
|
||||
public static final String _ID = "_id";
|
||||
public static final String ISDIR = "isdir";
|
||||
public static final String FILENAME = "filename";
|
||||
public static final String LENGTH = "length";
|
||||
public static final String TIMESTAMP = "ts";
|
||||
public static final String WRITABLE = "writable";
|
||||
static final String[] DEFCOLUMNS = new String[] {
|
||||
_ID,
|
||||
ISDIR,
|
||||
FILENAME,
|
||||
LENGTH,
|
||||
TIMESTAMP,
|
||||
WRITABLE
|
||||
};
|
||||
private String dirPath = null;
|
||||
private String [] theColumns = null;
|
||||
|
||||
public DirCursor(String[] columnNames, String sPath) {
|
||||
super((columnNames == null ? DEFCOLUMNS : columnNames));
|
||||
theColumns = (columnNames == null ? DEFCOLUMNS : columnNames);
|
||||
dirPath = sPath;
|
||||
doLoadCursor(dirPath);
|
||||
}
|
||||
|
||||
public DirCursor(String[] columnNames, int initialCapacity, String sPath) {
|
||||
super((columnNames == null ? DEFCOLUMNS : columnNames), initialCapacity);
|
||||
theColumns = (columnNames == null ? DEFCOLUMNS : columnNames);
|
||||
dirPath = sPath;
|
||||
doLoadCursor(dirPath);
|
||||
}
|
||||
|
||||
private void doLoadCursor(String sDir) {
|
||||
File dir = new File(sDir);
|
||||
int nFiles = 0;
|
||||
int nCols = theColumns.length;
|
||||
int lcvFiles = 0;
|
||||
int nCIndex = 0;
|
||||
Object [] vals = new Object[nCols];
|
||||
|
||||
if (dir.isDirectory()) {
|
||||
try {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = -1;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 1;
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
try {
|
||||
vals[nCIndex] = dir.getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
vals[nCIndex] = dir.getName();
|
||||
}
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(TIMESTAMP);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(WRITABLE);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = (dir.canWrite() ? 1 : 0);
|
||||
|
||||
addRow(vals);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
|
||||
File [] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
if ((nFiles = files.length) > 0) {
|
||||
for (lcvFiles = 0; lcvFiles < nFiles; lcvFiles++) {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = lcvFiles;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = (files[lcvFiles].isDirectory() ? 1 : 0);
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = files[lcvFiles].getName();
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = (files[lcvFiles].isDirectory() ? -1 : files[lcvFiles].length());
|
||||
|
||||
try {
|
||||
addRow(vals);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dir.isFile()) {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = -1;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = dir.getName();
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = dir.length();
|
||||
|
||||
nCIndex = getColumnIndex(TIMESTAMP);
|
||||
if (nCIndex > -1) {
|
||||
vals[nCIndex] = dir.lastModified();
|
||||
}
|
||||
|
||||
try {
|
||||
addRow(vals);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = -1;
|
||||
|
||||
nCIndex = getColumnIndex(ISDIR);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(FILENAME);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = null;
|
||||
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
nCIndex = getColumnIndex(TIMESTAMP);
|
||||
if (nCIndex > -1)
|
||||
vals[nCIndex] = 0;
|
||||
|
||||
addRow(vals);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
iae.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.ffxcp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
|
||||
public class FfxCPFP extends ContentProvider {
|
||||
public static final String PROVIDER_NAME = "org.mozilla.ffxcp";
|
||||
public static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/file");
|
||||
|
||||
public static final String _ID = "_id";
|
||||
public static final String ISDIR = "isdir";
|
||||
public static final String FILENAME = "filename";
|
||||
public static final String LENGTH = "length";
|
||||
public static final String CHUNK = "chunk";
|
||||
static String[] dircolumns = new String[] {
|
||||
_ID,
|
||||
ISDIR,
|
||||
FILENAME,
|
||||
LENGTH
|
||||
};
|
||||
|
||||
static String[] filecolumns = new String[] {
|
||||
_ID,
|
||||
CHUNK
|
||||
};
|
||||
|
||||
private static final int DIR = 1;
|
||||
private static final int FILE_NAME = 2;
|
||||
|
||||
private static final UriMatcher uriMatcher;
|
||||
static {
|
||||
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
uriMatcher.addURI(PROVIDER_NAME, "dir", DIR);
|
||||
uriMatcher.addURI(PROVIDER_NAME, "file", FILE_NAME);
|
||||
}
|
||||
|
||||
public int PruneDir(String sTmpDir) {
|
||||
int nRet = 0;
|
||||
int nFiles = 0;
|
||||
String sSubDir = null;
|
||||
|
||||
File dir = new File(sTmpDir);
|
||||
|
||||
if (dir.isDirectory()) {
|
||||
File [] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
if ((nFiles = files.length) > 0) {
|
||||
for (int lcv = 0; lcv < nFiles; lcv++) {
|
||||
if (files[lcv].isDirectory()) {
|
||||
sSubDir = files[lcv].getAbsolutePath();
|
||||
nRet += PruneDir(sSubDir);
|
||||
}
|
||||
else {
|
||||
if (files[lcv].delete()) {
|
||||
nRet++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dir.delete()) {
|
||||
nRet++;
|
||||
}
|
||||
if ((nFiles + 1) > nRet) {
|
||||
nRet = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return(nRet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||
int nFiles = 0;
|
||||
switch (uriMatcher.match(uri)) {
|
||||
case FILE_NAME:
|
||||
File f = new File(selection);
|
||||
if (f.delete())
|
||||
nFiles = 1;
|
||||
break;
|
||||
|
||||
case DIR:
|
||||
nFiles = PruneDir(selection);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nFiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri)
|
||||
{
|
||||
switch (uriMatcher.match(uri))
|
||||
{
|
||||
//---get directory---
|
||||
case DIR:
|
||||
return "vnd.android.cursor.dir/vnd.mozilla.dir ";
|
||||
//---get a particular file---
|
||||
case FILE_NAME:
|
||||
return "vnd.android.cursor.item/vnd.mozilla.file ";
|
||||
//---Unknown---
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported URI: " + uri);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues values) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
Cursor retCursor = null;
|
||||
|
||||
switch(uriMatcher.match(uri)) {
|
||||
case DIR:
|
||||
retCursor = new DirCursor(projection, selection);
|
||||
break;
|
||||
|
||||
case FILE_NAME:
|
||||
retCursor = new FileCursor(projection, selection, selectionArgs);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (retCursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||
int nRet = 0;
|
||||
FileOutputStream dstFile = null;
|
||||
|
||||
switch(uriMatcher.match(uri)) {
|
||||
case DIR:
|
||||
File dir = new File(selection);
|
||||
if (dir.mkdirs())
|
||||
nRet = 1;
|
||||
break;
|
||||
|
||||
case FILE_NAME:
|
||||
try {
|
||||
long lOffset = values.getAsLong("offset");
|
||||
byte [] buf = values.getAsByteArray(CHUNK);
|
||||
int nLength = values.getAsInteger(LENGTH);
|
||||
if ((buf != null) && (nLength > 0)) {
|
||||
File f = new File(selection);
|
||||
dstFile = new FileOutputStream(f, (lOffset == 0 ? false : true));
|
||||
dstFile.write(buf,0, nLength);
|
||||
dstFile.flush();
|
||||
dstFile.close();
|
||||
nRet = nLength;
|
||||
}
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
fnfe.printStackTrace();
|
||||
} catch (IOException ioe) {
|
||||
try {
|
||||
dstFile.flush();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
try {
|
||||
dstFile.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
}
|
|
@ -1,169 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.ffxcp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import android.database.AbstractWindowedCursor;
|
||||
import android.database.CursorWindow;
|
||||
|
||||
public class FileCursor extends AbstractWindowedCursor {
|
||||
public static final String _ID = "_id";
|
||||
public static final String CHUNK = "chunk";
|
||||
public static final String LENGTH = "length";
|
||||
static final String[] DEFCOLUMNS = new String[] {
|
||||
_ID,
|
||||
CHUNK,
|
||||
LENGTH
|
||||
};
|
||||
private String filePath = null;
|
||||
private String [] theColumns = null;
|
||||
|
||||
private static final int BUFSIZE = 4096;
|
||||
private long lFileSize = 0;
|
||||
private int nCount = 0;
|
||||
private File theFile = null;
|
||||
private byte [] theBuffer = null;
|
||||
private long lOffset = 0;
|
||||
private long lLength = -1;
|
||||
|
||||
public FileCursor(String[] columnNames, String sFilePath, String [] selectionArgs) {
|
||||
super();
|
||||
theColumns = (columnNames == null ? DEFCOLUMNS : columnNames);
|
||||
filePath = sFilePath;
|
||||
nCount = -1;
|
||||
|
||||
if ((selectionArgs != null) && (selectionArgs.length > 0)) {
|
||||
lOffset = Long.parseLong(selectionArgs[0]);
|
||||
lLength = Long.parseLong(selectionArgs[1]);
|
||||
}
|
||||
|
||||
if (filePath.length() > 0) {
|
||||
theFile = new File(filePath);
|
||||
if (theFile.exists() && theFile.canRead()) {
|
||||
lFileSize = theFile.length();
|
||||
|
||||
// lLength == -1 return everything between lOffset and eof
|
||||
// lLength == 0 return file length
|
||||
// lLength > 0 return lLength bytes
|
||||
if (lLength == -1) {
|
||||
lFileSize = lFileSize - lOffset;
|
||||
} else if (lLength == 0) {
|
||||
// just return the file length
|
||||
} else {
|
||||
lFileSize = ((lLength <= (lFileSize - lOffset)) ? lLength : (lFileSize - lOffset));
|
||||
}
|
||||
|
||||
if (lLength != 0) {
|
||||
nCount = (int) (lFileSize / BUFSIZE);
|
||||
if ((lFileSize % BUFSIZE) > 0)
|
||||
nCount++;
|
||||
} else {
|
||||
nCount = 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getColumnName (int columnIndex) {
|
||||
return theColumns[columnIndex];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getColumnNames() {
|
||||
return theColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return nCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(int oldPosition, int newPosition) {
|
||||
boolean bRet = true;
|
||||
|
||||
// get rid of old data
|
||||
mWindow.clear();
|
||||
bRet = mWindow.setNumColumns(theColumns.length);
|
||||
fillWindow(newPosition, mWindow);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillWindow (int pos, CursorWindow window) {
|
||||
int nNumRows = window.getNumRows();
|
||||
int nCIndex = 0;
|
||||
window.setStartPosition(0);
|
||||
|
||||
if (pos > -1) {
|
||||
if (nNumRows == 0) {
|
||||
window.allocRow();
|
||||
nNumRows = window.getNumRows();
|
||||
}
|
||||
|
||||
if (nNumRows == 1) {
|
||||
nCIndex = getColumnIndex(LENGTH);
|
||||
if (nCIndex > -1) {
|
||||
window.putLong(lFileSize, 0, nCIndex);
|
||||
}
|
||||
nCIndex = getColumnIndex(_ID);
|
||||
if (nCIndex > -1) {
|
||||
window.putLong((long)pos, 0, nCIndex);
|
||||
}
|
||||
nCIndex = getColumnIndex(CHUNK);
|
||||
if (nCIndex > -1) {
|
||||
if (lLength != 0) {
|
||||
byte[] value = getABlob (pos, 1);
|
||||
window.putBlob(value, 0, nCIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
window.setStartPosition(pos);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public byte[] getABlob (int row, int column) {
|
||||
int nRead = 0;
|
||||
int nOffset = 0;
|
||||
int nBufSize = 0;
|
||||
|
||||
if ((column == 1) && (theFile != null)) {
|
||||
try {
|
||||
FileInputStream fin = new FileInputStream(theFile);
|
||||
nOffset = row * BUFSIZE;
|
||||
if (row < (nCount - 1)) {
|
||||
nBufSize = BUFSIZE;
|
||||
} else {
|
||||
nBufSize = (int) (lFileSize - nOffset);
|
||||
}
|
||||
theBuffer = new byte[nBufSize];
|
||||
|
||||
if (theBuffer != null) {
|
||||
if (fin.skip(nOffset + lOffset) == (nOffset + lOffset)) {
|
||||
if ((nRead = fin.read(theBuffer, 0, nBufSize)) != -1) {
|
||||
if (nRead != nBufSize) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fin.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return theBuffer;
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
JAVAFILES = \
|
||||
DirCursor.java \
|
||||
ffxcp.java \
|
||||
FfxCPFP.java \
|
||||
FileCursor.java \
|
||||
$(NULL)
|
||||
|
||||
tools:: $(ANDROID_APK_NAME).apk
|
|
@ -1,15 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-6
|
|
@ -1,16 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.ffxcp;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class ffxcp extends Activity {
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
ANDROID_APK_NAME = 'FfxCP'
|
||||
ANDROID_APK_PACKAGE = 'org.mozilla.ffxcp'
|
Двоичные данные
build/mobile/sutagent/android/ffxcp/res/drawable-hdpi/icon.png
До Ширина: | Высота: | Размер: 4.0 KiB |
Двоичные данные
build/mobile/sutagent/android/ffxcp/res/drawable-ldpi/icon.png
До Ширина: | Высота: | Размер: 1.7 KiB |
Двоичные данные
build/mobile/sutagent/android/ffxcp/res/drawable-mdpi/icon.png
До Ширина: | Высота: | Размер: 2.5 KiB |
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello"
|
||||
/>
|
||||
</LinearLayout>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<resources>
|
||||
<string name="hello">Hello World, firefoxcp!</string>
|
||||
<string name="app_name">FirefoxCP</string>
|
||||
</resources>
|
|
@ -1,8 +0,0 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
ANDROID_APK_NAME = 'sutAgentAndroid'
|
||||
ANDROID_APK_PACKAGE = 'com.mozilla.SUTAgentAndroid'
|
Двоичные данные
build/mobile/sutagent/android/network-libs/commons-net-2.0.jar
Двоичные данные
build/mobile/sutagent/android/network-libs/jmdns.jar
Двоичные данные
build/mobile/sutagent/android/res/drawable/ateamlogo.png
До Ширина: | Высота: | Размер: 1.5 KiB |
Двоичные данные
build/mobile/sutagent/android/res/drawable/ic_stat_first.png
До Ширина: | Высота: | Размер: 1.6 KiB |
Двоичные данные
build/mobile/sutagent/android/res/drawable/ic_stat_neterror.png
До Ширина: | Высота: | Размер: 777 B |
Двоичные данные
build/mobile/sutagent/android/res/drawable/ic_stat_second.png
До Ширина: | Высота: | Размер: 1.2 KiB |
Двоичные данные
build/mobile/sutagent/android/res/drawable/ic_stat_warning.png
До Ширина: | Высота: | Размер: 651 B |
Двоичные данные
build/mobile/sutagent/android/res/drawable/icon.png
До Ширина: | Высота: | Размер: 2.5 KiB |
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/Textview01"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="true" android:text="Exit"></Button>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<resources>
|
||||
|
||||
<string name="hello">Hello World, SUTAgentAndroid!</string>
|
||||
<string name="app_name">SUTAgentAndroid</string>
|
||||
|
||||
|
||||
<string name="foreground_service_started">Foreground Service Started (ASMozStub)</string>
|
||||
|
||||
</resources>
|
|
@ -1,44 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.mozilla.watcher"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"></uses-permission>
|
||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||
<activity android:name=".WatcherMain"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<receiver android:name=".WatcherReceiver">
|
||||
<intent-filter>
|
||||
<action android:value="android.intent.action.BOOT_COMPLETED" android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
<category android:value="android.intent.category.HOME" android:name="android.intent.category.HOME"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<service android:name="WatcherService">
|
||||
<intent-filter>
|
||||
<action android:name="com.mozilla.watcher.LISTENER_SERVICE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
</application>
|
||||
<uses-sdk android:minSdkVersion="5" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
|
||||
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"></uses-permission>
|
||||
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
|
||||
|
||||
<uses-permission android:name="android.permission.VIBRATE"></uses-permission>
|
||||
|
||||
</manifest>
|
|
@ -1,108 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/*
|
||||
* This file is auto-generated. DO NOT MODIFY.
|
||||
* Original file: C:\\Users\\Bob\\workspace\\Watcher\\src\\com\\mozilla\\watcher\\IWatcherService.aidl
|
||||
*/
|
||||
package com.mozilla.watcher;
|
||||
public interface IWatcherService extends android.os.IInterface
|
||||
{
|
||||
/** Local-side IPC implementation stub class. */
|
||||
public static abstract class Stub extends android.os.Binder implements com.mozilla.watcher.IWatcherService
|
||||
{
|
||||
private static final java.lang.String DESCRIPTOR = "com.mozilla.watcher.IWatcherService";
|
||||
/** Construct the stub at attach it to the interface. */
|
||||
public Stub()
|
||||
{
|
||||
this.attachInterface(this, DESCRIPTOR);
|
||||
}
|
||||
/**
|
||||
* Cast an IBinder object into an com.mozilla.watcher.IWatcherService interface,
|
||||
* generating a proxy if needed.
|
||||
*/
|
||||
public static com.mozilla.watcher.IWatcherService asInterface(android.os.IBinder obj)
|
||||
{
|
||||
if ((obj==null)) {
|
||||
return null;
|
||||
}
|
||||
android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
|
||||
if (((iin!=null)&&(iin instanceof com.mozilla.watcher.IWatcherService))) {
|
||||
return ((com.mozilla.watcher.IWatcherService)iin);
|
||||
}
|
||||
return new com.mozilla.watcher.IWatcherService.Stub.Proxy(obj);
|
||||
}
|
||||
public android.os.IBinder asBinder()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case INTERFACE_TRANSACTION:
|
||||
{
|
||||
reply.writeString(DESCRIPTOR);
|
||||
return true;
|
||||
}
|
||||
case TRANSACTION_UpdateApplication:
|
||||
{
|
||||
data.enforceInterface(DESCRIPTOR);
|
||||
java.lang.String _arg0;
|
||||
_arg0 = data.readString();
|
||||
java.lang.String _arg1;
|
||||
_arg1 = data.readString();
|
||||
java.lang.String _arg2;
|
||||
_arg2 = data.readString();
|
||||
int _arg3;
|
||||
_arg3 = data.readInt();
|
||||
int _result = this.UpdateApplication(_arg0, _arg1, _arg2, _arg3);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(_result);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
}
|
||||
private static class Proxy implements com.mozilla.watcher.IWatcherService
|
||||
{
|
||||
private android.os.IBinder mRemote;
|
||||
Proxy(android.os.IBinder remote)
|
||||
{
|
||||
mRemote = remote;
|
||||
}
|
||||
public android.os.IBinder asBinder()
|
||||
{
|
||||
return mRemote;
|
||||
}
|
||||
public java.lang.String getInterfaceDescriptor()
|
||||
{
|
||||
return DESCRIPTOR;
|
||||
}
|
||||
public int UpdateApplication(java.lang.String sPkgName, java.lang.String sPkgFileName, java.lang.String sOutFile, int bReboot) throws android.os.RemoteException
|
||||
{
|
||||
android.os.Parcel _data = android.os.Parcel.obtain();
|
||||
android.os.Parcel _reply = android.os.Parcel.obtain();
|
||||
int _result;
|
||||
try {
|
||||
_data.writeInterfaceToken(DESCRIPTOR);
|
||||
_data.writeString(sPkgName);
|
||||
_data.writeString(sPkgFileName);
|
||||
_data.writeString(sOutFile);
|
||||
_data.writeInt(bReboot);
|
||||
mRemote.transact(Stub.TRANSACTION_UpdateApplication, _data, _reply, 0);
|
||||
_reply.readException();
|
||||
_result = _reply.readInt();
|
||||
}
|
||||
finally {
|
||||
_reply.recycle();
|
||||
_data.recycle();
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
}
|
||||
static final int TRANSACTION_UpdateApplication = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
|
||||
}
|
||||
public int UpdateApplication(java.lang.String sPkgName, java.lang.String sPkgFileName, java.lang.String sOutFile, int bReboot) throws android.os.RemoteException;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
JAVAFILES = \
|
||||
IWatcherService.java \
|
||||
RedirOutputThread.java \
|
||||
WatcherMain.java \
|
||||
WatcherReceiver.java \
|
||||
WatcherService.java \
|
||||
$(NULL)
|
||||
|
||||
tools:: $(ANDROID_APK_NAME).apk
|
|
@ -1,130 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package com.mozilla.watcher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class RedirOutputThread extends Thread
|
||||
{
|
||||
OutputStream out;
|
||||
InputStream sutErr;
|
||||
InputStream sutOut;
|
||||
Process pProc;
|
||||
String strOutput;
|
||||
|
||||
public RedirOutputThread(Process pProc, OutputStream out)
|
||||
{
|
||||
if (pProc != null)
|
||||
{
|
||||
this.pProc = pProc;
|
||||
sutErr = pProc.getErrorStream(); // Stderr
|
||||
sutOut = pProc.getInputStream(); // Stdout
|
||||
}
|
||||
if (out != null)
|
||||
this.out = out;
|
||||
|
||||
strOutput = "";
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
boolean bStillRunning = true;
|
||||
int nBytesOut = 0;
|
||||
int nBytesErr = 0;
|
||||
int nBytesRead = 0;
|
||||
PrintWriter pOut = null;
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
if (out != null)
|
||||
pOut = new PrintWriter(out);
|
||||
else
|
||||
bStillRunning = true;
|
||||
|
||||
while (bStillRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((nBytesOut = sutOut.available()) > 0)
|
||||
{
|
||||
if (nBytesOut > buffer.length)
|
||||
{
|
||||
buffer = null;
|
||||
System.gc();
|
||||
buffer = new byte[nBytesOut];
|
||||
}
|
||||
nBytesRead = sutOut.read(buffer, 0, nBytesOut);
|
||||
if (nBytesRead == -1)
|
||||
bStillRunning = false;
|
||||
else
|
||||
{
|
||||
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
|
||||
if (pOut != null)
|
||||
{
|
||||
pOut.print(sRep);
|
||||
pOut.flush();
|
||||
}
|
||||
else
|
||||
strOutput += sRep;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nBytesErr = sutErr.available()) > 0)
|
||||
{
|
||||
if (nBytesErr > buffer.length)
|
||||
{
|
||||
buffer = null;
|
||||
System.gc();
|
||||
buffer = new byte[nBytesErr];
|
||||
}
|
||||
nBytesRead = sutErr.read(buffer, 0, nBytesErr);
|
||||
if (nBytesRead == -1)
|
||||
bStillRunning = false;
|
||||
else
|
||||
{
|
||||
String sRep = new String(buffer,0,nBytesRead).replace("\n", "\r\n");
|
||||
if (pOut != null)
|
||||
{
|
||||
pOut.print(sRep);
|
||||
pOut.flush();
|
||||
}
|
||||
else
|
||||
strOutput += sRep;
|
||||
}
|
||||
}
|
||||
|
||||
bStillRunning = (IsProcRunning(pProc) || (sutOut.available() > 0) || (sutErr.available() > 0));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
pProc.destroy();
|
||||
buffer = null;
|
||||
System.gc();
|
||||
}
|
||||
|
||||
private boolean IsProcRunning(Process pProc)
|
||||
{
|
||||
boolean bRet = false;
|
||||
@SuppressWarnings("unused")
|
||||
int nExitCode = 0;
|
||||
|
||||
try
|
||||
{
|
||||
nExitCode = pProc.exitValue();
|
||||
}
|
||||
catch (IllegalThreadStateException z)
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
|
||||
return(bRet);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package com.mozilla.watcher;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class WatcherMain extends Activity {
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package com.mozilla.watcher;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
// import android.os.Debug;
|
||||
|
||||
public class WatcherReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// Debug.waitForDebugger();
|
||||
Intent serviceIntent = new Intent();
|
||||
serviceIntent.putExtra("command", "start");
|
||||
serviceIntent.setAction("com.mozilla.watcher.LISTENER_SERVICE");
|
||||
context.startService(serviceIntent);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system use,
|
||||
# "build.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
|
||||
# Project target.
|
||||
target=android-5
|
|
@ -1,8 +0,0 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
ANDROID_APK_NAME = 'Watcher'
|
||||
ANDROID_APK_PACKAGE = 'com.mozilla.watcher'
|
До Ширина: | Высота: | Размер: 1.5 KiB |
Двоичные данные
build/mobile/sutagent/android/watcher/res/drawable-hdpi/icon.png
До Ширина: | Высота: | Размер: 4.0 KiB |
До Ширина: | Высота: | Размер: 1.5 KiB |
Двоичные данные
build/mobile/sutagent/android/watcher/res/drawable-ldpi/icon.png
До Ширина: | Высота: | Размер: 1.7 KiB |
До Ширина: | Высота: | Размер: 1.5 KiB |
Двоичные данные
build/mobile/sutagent/android/watcher/res/drawable-mdpi/icon.png
До Ширина: | Высота: | Размер: 2.5 KiB |
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/hello"
|
||||
/>
|
||||
</LinearLayout>
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<resources>
|
||||
<string name="hello">Hello World, WatcherMain!</string>
|
||||
<string name="app_name">watcher</string>
|
||||
<string name="foreground_service_started">Foreground Service Started</string>
|
||||
|
||||
</resources>
|
|
@ -22,12 +22,6 @@ if CONFIG['OS_TARGET'] == 'Android' and CONFIG['MOZ_ANDROID_CXX_STL'] == 'mozstl
|
|||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||
DIRS += ['annotationProcessors']
|
||||
TEST_DIRS += [
|
||||
'mobile/sutagent/android',
|
||||
'mobile/sutagent/android/watcher',
|
||||
'mobile/sutagent/android/ffxcp',
|
||||
'mobile/sutagent/android/fencp',
|
||||
]
|
||||
|
||||
for var in ('GRE_MILESTONE', 'MOZ_APP_VERSION', 'MOZ_APP_BASENAME',
|
||||
'MOZ_APP_VENDOR', 'MOZ_APP_ID', 'MAR_CHANNEL_ID',
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Templates implementing some generic checks.
|
||||
|
||||
# Helper to display "checking" messages
|
||||
# @checking('for foo')
|
||||
# def foo():
|
||||
# return 'foo'
|
||||
# is equivalent to:
|
||||
# def foo():
|
||||
# sys.stdout.write('checking for foo... ')
|
||||
# ret = foo
|
||||
# sys.stdout.write(ret + '\n')
|
||||
# return ret
|
||||
# This can be combined with e.g. @depends:
|
||||
# @depends(some_option)
|
||||
# @checking('for something')
|
||||
# def check(value):
|
||||
# ...
|
||||
@template
|
||||
def checking(what):
|
||||
def decorator(func):
|
||||
@advanced
|
||||
def wrapped(*args, **kwargs):
|
||||
import sys
|
||||
print('checking', what, end='... ')
|
||||
sys.stdout.flush()
|
||||
ret = func(*args, **kwargs)
|
||||
if ret is True:
|
||||
print('yes')
|
||||
elif ret is False:
|
||||
print('no')
|
||||
else:
|
||||
print(ret)
|
||||
sys.stdout.flush()
|
||||
return ret
|
||||
return wrapped
|
||||
return decorator
|
||||
|
||||
|
||||
# Template to check for programs in $PATH.
|
||||
# check('PROG', ('a', 'b'))
|
||||
# will look for 'a' or 'b' in $PATH, and set_config PROG to the one
|
||||
# it can find. If PROG is already set from the environment or command line,
|
||||
# use that value instead.
|
||||
@template
|
||||
def check_prog(var, progs, allow_missing=False):
|
||||
option(env=var, nargs=1, help=var)
|
||||
|
||||
not_found = 'not found'
|
||||
progs = list(progs)
|
||||
|
||||
@depends(var)
|
||||
@checking('for %s' % var.lower())
|
||||
def check(value):
|
||||
if value:
|
||||
progs[:] = value
|
||||
for prog in progs:
|
||||
result = find_program(prog)
|
||||
if result:
|
||||
return result
|
||||
return not_found
|
||||
|
||||
@depends(check)
|
||||
@advanced
|
||||
def postcheck(value):
|
||||
set_config(var, ':' if value is not_found else value)
|
||||
if not value and not allow_missing:
|
||||
from mozbuild.shellutil import quote
|
||||
error('Cannot find %s (tried: %s)'
|
||||
% (var.lower(), ', '.join(quote(p) for p in progs)))
|
||||
|
||||
return check
|
|
@ -222,8 +222,52 @@ def command_line_helper():
|
|||
return depends.__self__._helper
|
||||
|
||||
|
||||
@depends(mozconfig)
|
||||
def mozconfig_options(mozconfig):
|
||||
# All options defined above this point can't be injected in mozconfig_options
|
||||
# below, so collect them.
|
||||
@template
|
||||
@advanced
|
||||
def early_options():
|
||||
@depends('--help')
|
||||
def early_options(help):
|
||||
return set(
|
||||
option.env
|
||||
for option in depends.__self__._options.itervalues()
|
||||
if option.env
|
||||
)
|
||||
return early_options
|
||||
|
||||
early_options = early_options()
|
||||
|
||||
# At the moment, moz.configure doesn't have complete knowledge of all the
|
||||
# supported options in mozconfig because of all that is still in old.configure.
|
||||
# But we don't know all the options that moz.configure knows about until all
|
||||
# moz.configure files are executed, so we keep a manual list here, that is
|
||||
# checked in old.configure (we'll assume it's the last moz.configure file
|
||||
# processed). This is tedious but necessary for now.
|
||||
@depends('--help')
|
||||
def wanted_mozconfig_variables(help):
|
||||
return set([
|
||||
'AUTOCONF',
|
||||
'AWK',
|
||||
'DISABLE_EXPORT_JS',
|
||||
'DISABLE_SHARED_JS',
|
||||
'DOXYGEN',
|
||||
'DSYMUTIL',
|
||||
'EXTERNAL_SOURCE_DIR',
|
||||
'GENISOIMAGE',
|
||||
'MOZILLABUILD',
|
||||
'MOZ_ARTIFACT_BUILDS',
|
||||
'MOZ_BUILD_APP',
|
||||
'PERL',
|
||||
'RPMBUILD',
|
||||
'UNZIP',
|
||||
'XARGS',
|
||||
'ZIP',
|
||||
])
|
||||
|
||||
|
||||
@depends(mozconfig, wanted_mozconfig_variables)
|
||||
def mozconfig_options(mozconfig, wanted_mozconfig_variables):
|
||||
if mozconfig['path']:
|
||||
helper = command_line_helper()
|
||||
warn('Adding configure options from %s' % mozconfig['path'])
|
||||
|
@ -234,11 +278,22 @@ def mozconfig_options(mozconfig):
|
|||
# emulation that mozconfig provides.
|
||||
helper.add(arg, origin='mozconfig', args=helper._args)
|
||||
|
||||
# Ideally we'd handle mozconfig['env'] and mozconfig['vars'] here,
|
||||
# but at the moment, moz.configure has no knowledge of the options
|
||||
# that may appear there. We'll opt-in when we move things from
|
||||
# old-configure.in, which will be tedious but necessary until we
|
||||
# can discriminate what old-configure.in supports.
|
||||
def add(key, value):
|
||||
# See comment above wanted_mozconfig_variables
|
||||
if key in wanted_mozconfig_variables:
|
||||
arg = '%s=%s' % (key, value)
|
||||
warn(' %s' % arg)
|
||||
helper.add(arg, origin='mozconfig', args=helper._args)
|
||||
|
||||
for key, value in mozconfig['env']['added'].iteritems():
|
||||
add(key, value)
|
||||
for key, (_, value) in mozconfig['env']['modified'].iteritems():
|
||||
add(key, value)
|
||||
for key, value in mozconfig['vars']['added'].iteritems():
|
||||
add(key, value)
|
||||
for key, (_, value) in mozconfig['vars']['modified'].iteritems():
|
||||
add(key, value)
|
||||
|
||||
|
||||
del command_line_helper
|
||||
|
||||
|
|
|
@ -60,6 +60,26 @@ def autoconf(mozconfig, autoconf):
|
|||
return autoconf
|
||||
|
||||
|
||||
# See comment in mozconfig_options() from build/moz.configure/init.configure
|
||||
@template
|
||||
@advanced
|
||||
def check_mozconfig_variables():
|
||||
# This escapes the sandbox. Don't copy this. This is only here because it
|
||||
# is a one off until old-configure is gone.
|
||||
all_options = depends.__self__._options.itervalues()
|
||||
|
||||
@depends(early_options, wanted_mozconfig_variables)
|
||||
def check_mozconfig_variables(early_options, wanted_mozconfig_variables):
|
||||
for option in all_options:
|
||||
if (option.env and option.env not in early_options and
|
||||
option.env not in wanted_mozconfig_variables):
|
||||
error(
|
||||
'You need to add `%s` to the `wanted_mozconfig_variables` '
|
||||
'list in build/moz.configure/init.configure.' % option.env)
|
||||
|
||||
check_mozconfig_variables()
|
||||
|
||||
|
||||
@depends('OLD_CONFIGURE', mozconfig, autoconf, check_build_environment, shell,
|
||||
old_configure_assignments)
|
||||
@advanced
|
||||
|
@ -271,7 +291,6 @@ def old_configure_options(*options):
|
|||
'--enable-webspeech',
|
||||
'--enable-webspeechtestbackend',
|
||||
'--enable-wmf',
|
||||
'--enable-xterm-updates',
|
||||
'--enable-xul',
|
||||
'--enable-zipwriter',
|
||||
'--no-create',
|
||||
|
|