From: Marius Gavrilescu
Date: Tue, 5 Mar 2013 19:12:17 +0000 (+0200)
Subject: Initial commit
X-Git-Tag: 0.000_001~62
X-Git-Url: http://git.ieval.ro/?a=commitdiff_plain;h=8dfb76c9431dbf8401412cb92c7512e7dc3081a2;p=fonbot.git
Initial commit
---
8dfb76c9431dbf8401412cb92c7512e7dc3081a2
diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..2735db2
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7792e06
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+bin/
+gen/
diff --git a/.pmd b/.pmd
new file mode 100644
index 0000000..5d5f745
--- /dev/null
+++ b/.pmd
@@ -0,0 +1,849 @@
+
+
+ false
+ .ruleset
+
+
+ LooseCoupling
+ Type Resolution Rules
+
+
+ CloneMethodMustImplementCloneable
+ Type Resolution Rules
+
+
+ SignatureDeclareThrowsException
+ Type Resolution Rules
+
+
+ UseSingleton
+ Design Rules
+
+
+ SimplifyBooleanReturns
+ Design Rules
+
+
+ SimplifyBooleanExpressions
+ Design Rules
+
+
+ AvoidDeeplyNestedIfStmts
+ Design Rules
+
+
+ AvoidReassigningParameters
+ Design Rules
+
+
+ SwitchDensity
+ Design Rules
+
+
+ ConstructorCallsOverridableMethod
+ Design Rules
+
+
+ AccessorClassGeneration
+ Design Rules
+
+
+ FinalFieldCouldBeStatic
+ Design Rules
+
+
+ CloseResource
+ Design Rules
+
+
+ NonStaticInitializer
+ Design Rules
+
+
+ DefaultLabelNotLastInSwitchStmt
+ Design Rules
+
+
+ NonCaseLabelInSwitchStatement
+ Design Rules
+
+
+ OptimizableToArrayCall
+ Design Rules
+
+
+ BadComparison
+ Design Rules
+
+
+ EqualsNull
+ Design Rules
+
+
+ ConfusingTernary
+ Design Rules
+
+
+ InstantiationToGetClass
+ Design Rules
+
+
+ IdempotentOperations
+ Design Rules
+
+
+ SimpleDateFormatNeedsLocale
+ Design Rules
+
+
+ ImmutableField
+ Design Rules
+
+
+ UseLocaleWithCaseConversions
+ Design Rules
+
+
+ AvoidProtectedFieldInFinalClass
+ Design Rules
+
+
+ AssignmentToNonFinalStatic
+ Design Rules
+
+
+ MissingStaticMethodInNonInstantiatableClass
+ Design Rules
+
+
+ AvoidSynchronizedAtMethodLevel
+ Design Rules
+
+
+ MissingBreakInSwitch
+ Design Rules
+
+
+ UseNotifyAllInsteadOfNotify
+ Design Rules
+
+
+ AvoidInstanceofChecksInCatchClause
+ Design Rules
+
+
+ AbstractClassWithoutAbstractMethod
+ Design Rules
+
+
+ SimplifyConditional
+ Design Rules
+
+
+ CompareObjectsWithEquals
+ Design Rules
+
+
+ PositionLiteralsFirstInComparisons
+ Design Rules
+
+
+ UnnecessaryLocalBeforeReturn
+ Design Rules
+
+
+ NonThreadSafeSingleton
+ Design Rules
+
+
+ UncommentedEmptyMethod
+ Design Rules
+
+
+ UncommentedEmptyConstructor
+ Design Rules
+
+
+ AvoidConstantsInterface
+ Design Rules
+
+
+ UnsynchronizedStaticDateFormatter
+ Design Rules
+
+
+ PreserveStackTrace
+ Design Rules
+
+
+ UseCollectionIsEmpty
+ Design Rules
+
+
+ ClassWithOnlyPrivateConstructorsShouldBeFinal
+ Design Rules
+
+
+ EmptyMethodInAbstractClassShouldBeAbstract
+ Design Rules
+
+
+ SingularField
+ Design Rules
+
+
+ ReturnEmptyArrayRatherThanNull
+ Design Rules
+
+
+ AbstractClassWithoutAnyMethod
+ Design Rules
+
+
+ AvoidCatchingThrowable
+ Strict Exception Rules
+
+
+ SignatureDeclareThrowsException
+ Type Resolution Rules
+
+
+ ExceptionAsFlowControl
+ Strict Exception Rules
+
+
+ AvoidCatchingNPE
+ Strict Exception Rules
+
+
+ AvoidThrowingRawExceptionTypes
+ Strict Exception Rules
+
+
+ AvoidThrowingNullPointerException
+ Strict Exception Rules
+
+
+ AvoidRethrowingException
+ Strict Exception Rules
+
+
+ DoNotExtendJavaLangError
+ Strict Exception Rules
+
+
+ DoNotThrowExceptionInFinally
+ Strict Exception Rules
+
+
+ AvoidThrowingNewInstanceOfSameException
+ Strict Exception Rules
+
+
+ UnusedPrivateField
+ Unused Code Rules
+
+
+ UnusedLocalVariable
+ Unused Code Rules
+
+
+ UnusedPrivateMethod
+ Unused Code Rules
+
+
+ UnusedFormalParameter
+ Unused Code Rules
+
+
+ MoreThanOneLogger
+ Java Logging Rules
+
+
+ LoggerIsNotStaticFinal
+ Java Logging Rules
+
+
+ SystemPrintln
+ Java Logging Rules
+
+
+ AvoidPrintStackTrace
+ Java Logging Rules
+
+
+ AvoidDuplicateLiterals
+ String and StringBuffer Rules
+
+
+ StringInstantiation
+ String and StringBuffer Rules
+
+
+ StringToString
+ String and StringBuffer Rules
+
+
+ InefficientStringBuffering
+ String and StringBuffer Rules
+
+
+ UnnecessaryCaseChange
+ String and StringBuffer Rules
+
+
+ UseStringBufferLength
+ String and StringBuffer Rules
+
+
+ AppendCharacterWithChar
+ String and StringBuffer Rules
+
+
+ ConsecutiveLiteralAppends
+ String and StringBuffer Rules
+
+
+ UseIndexOfChar
+ String and StringBuffer Rules
+
+
+ InefficientEmptyStringCheck
+ String and StringBuffer Rules
+
+
+ InsufficientStringBufferDeclaration
+ String and StringBuffer Rules
+
+
+ UselessStringValueOf
+ String and StringBuffer Rules
+
+
+ StringBufferInstantiationWithChar
+ String and StringBuffer Rules
+
+
+ UseEqualsToCompareStrings
+ String and StringBuffer Rules
+
+
+ AvoidStringBufferField
+ String and StringBuffer Rules
+
+
+ ReplaceVectorWithList
+ Migration Rules
+
+
+ ReplaceHashtableWithMap
+ Migration Rules
+
+
+ ReplaceEnumerationWithIterator
+ Migration Rules
+
+
+ AvoidEnumAsIdentifier
+ Migration Rules
+
+
+ AvoidAssertAsIdentifier
+ Migration Rules
+
+
+ IntegerInstantiation
+ Migration Rules
+
+
+ ByteInstantiation
+ Migration Rules
+
+
+ ShortInstantiation
+ Migration Rules
+
+
+ LongInstantiation
+ Migration Rules
+
+
+ JUnit4TestShouldUseBeforeAnnotation
+ Migration Rules
+
+
+ JUnit4TestShouldUseAfterAnnotation
+ Migration Rules
+
+
+ JUnit4TestShouldUseTestAnnotation
+ Migration Rules
+
+
+ JUnit4SuitesShouldUseSuiteAnnotation
+ Migration Rules
+
+
+ JUnitUseExpected
+ Migration Rules
+
+
+ LocalVariableCouldBeFinal
+ Optimization Rules
+
+
+ MethodArgumentCouldBeFinal
+ Optimization Rules
+
+
+ AvoidInstantiatingObjectsInLoops
+ Optimization Rules
+
+
+ UseArrayListInsteadOfVector
+ Optimization Rules
+
+
+ SimplifyStartsWith
+ Optimization Rules
+
+
+ UseStringBufferForStringAppends
+ Optimization Rules
+
+
+ UseArraysAsList
+ Optimization Rules
+
+
+ AvoidArrayLoops
+ Optimization Rules
+
+
+ UnnecessaryWrapperObjectCreation
+ Optimization Rules
+
+
+ AddEmptyString
+ Optimization Rules
+
+
+ EmptyCatchBlock
+ Basic Rules
+
+
+ EmptyIfStmt
+ Basic Rules
+
+
+ EmptyWhileStmt
+ Basic Rules
+
+
+ EmptyTryBlock
+ Basic Rules
+
+
+ EmptyFinallyBlock
+ Basic Rules
+
+
+ EmptySwitchStatements
+ Basic Rules
+
+
+ JumbledIncrementer
+ Basic Rules
+
+
+ ForLoopShouldBeWhileLoop
+ Basic Rules
+
+
+ UnnecessaryConversionTemporary
+ Basic Rules
+
+
+ OverrideBothEqualsAndHashcode
+ Basic Rules
+
+
+ DoubleCheckedLocking
+ Basic Rules
+
+
+ ReturnFromFinallyBlock
+ Basic Rules
+
+
+ EmptySynchronizedBlock
+ Basic Rules
+
+
+ UnnecessaryReturn
+ Basic Rules
+
+
+ EmptyStaticInitializer
+ Basic Rules
+
+
+ UnconditionalIfStatement
+ Basic Rules
+
+
+ EmptyStatementNotInLoop
+ Basic Rules
+
+
+ BooleanInstantiation
+ Basic Rules
+
+
+ UnnecessaryFinalModifier
+ Basic Rules
+
+
+ CollapsibleIfStatements
+ Basic Rules
+
+
+ UselessOverridingMethod
+ Basic Rules
+
+
+ ClassCastExceptionWithToArray
+ Basic Rules
+
+
+ AvoidDecimalLiteralsInBigDecimalConstructor
+ Basic Rules
+
+
+ UselessOperationOnImmutable
+ Basic Rules
+
+
+ MisplacedNullCheck
+ Basic Rules
+
+
+ UnusedNullCheckInEquals
+ Basic Rules
+
+
+ AvoidThreadGroup
+ Basic Rules
+
+
+ BrokenNullCheck
+ Basic Rules
+
+
+ BigIntegerInstantiation
+ Basic Rules
+
+
+ AvoidUsingOctalValues
+ Basic Rules
+
+
+ AvoidUsingHardCodedIP
+ Basic Rules
+
+
+ CheckResultSet
+ Basic Rules
+
+
+ AvoidMultipleUnaryOperators
+ Basic Rules
+
+
+ EmptyInitializer
+ Basic Rules
+
+
+ MethodReturnsInternalArray
+ Security Code Guidelines
+
+
+ ArrayIsStoredDirectly
+ Security Code Guidelines
+
+
+ CouplingBetweenObjects
+ Coupling Rules
+
+
+ ExcessiveImports
+ Coupling Rules
+
+
+ LooseCoupling
+ Type Resolution Rules
+
+
+ DuplicateImports
+ Import Statement Rules
+
+
+ DontImportJavaLang
+ Import Statement Rules
+
+
+ ImportFromSamePackage
+ Import Statement Rules
+
+
+ TooManyStaticImports
+ Import Statement Rules
+
+
+ JUnitStaticSuite
+ JUnit Rules
+
+
+ JUnitSpelling
+ JUnit Rules
+
+
+ JUnitAssertionsShouldIncludeMessage
+ JUnit Rules
+
+
+ JUnitTestsShouldIncludeAssert
+ JUnit Rules
+
+
+ TestClassWithoutTestCases
+ JUnit Rules
+
+
+ UnnecessaryBooleanAssertion
+ JUnit Rules
+
+
+ UseAssertEqualsInsteadOfAssertTrue
+ JUnit Rules
+
+
+ UseAssertSameInsteadOfAssertTrue
+ JUnit Rules
+
+
+ UseAssertNullInsteadOfAssertTrue
+ JUnit Rules
+
+
+ SimplifyBooleanAssertion
+ JUnit Rules
+
+
+ UnnecessaryConstructor
+ Controversial Rules
+
+
+ NullAssignment
+ Controversial Rules
+
+
+ UnusedModifier
+ Controversial Rules
+
+
+ AssignmentInOperand
+ Controversial Rules
+
+
+ AtLeastOneConstructor
+ Controversial Rules
+
+
+ DontImportSun
+ Controversial Rules
+
+
+ SuspiciousOctalEscape
+ Controversial Rules
+
+
+ CallSuperInConstructor
+ Controversial Rules
+
+
+ UnnecessaryParentheses
+ Controversial Rules
+
+
+ DefaultPackage
+ Controversial Rules
+
+
+ BooleanInversion
+ Controversial Rules
+
+
+ AvoidUsingShortType
+ Controversial Rules
+
+
+ AvoidUsingVolatile
+ Controversial Rules
+
+
+ AvoidUsingNativeCode
+ Controversial Rules
+
+
+ AvoidAccessibilityAlteration
+ Controversial Rules
+
+
+ DoNotCallGarbageCollectionExplicitly
+ Controversial Rules
+
+
+ ShortMethodName
+ Naming Rules
+
+
+ VariableNamingConventions
+ Naming Rules
+
+
+ MethodNamingConventions
+ Naming Rules
+
+
+ ClassNamingConventions
+ Naming Rules
+
+
+ AbstractNaming
+ Naming Rules
+
+
+ AvoidDollarSigns
+ Naming Rules
+
+
+ MethodWithSameNameAsEnclosingClass
+ Naming Rules
+
+
+ SuspiciousHashcodeMethodName
+ Naming Rules
+
+
+ SuspiciousConstantFieldName
+ Naming Rules
+
+
+ SuspiciousEqualsMethodName
+ Naming Rules
+
+
+ AvoidFieldNameMatchingTypeName
+ Naming Rules
+
+
+ AvoidFieldNameMatchingMethodName
+ Naming Rules
+
+
+ NoPackage
+ Naming Rules
+
+
+ PackageCase
+ Naming Rules
+
+
+ MisleadingVariableName
+ Naming Rules
+
+
+ BooleanGetMethodName
+ Naming Rules
+
+
+ ExcessiveMethodLength
+ Code Size Rules
+
+
+ ExcessiveParameterList
+ Code Size Rules
+
+
+ ExcessiveClassLength
+ Code Size Rules
+
+
+ ExcessivePublicCount
+ Code Size Rules
+
+
+ NcssMethodCount
+ Code Size Rules
+
+
+ NcssTypeCount
+ Code Size Rules
+
+
+ NcssConstructorCount
+ Code Size Rules
+
+
+ EmptyFinalizer
+ Finalizer Rules
+
+
+ FinalizeOnlyCallsSuperFinalize
+ Finalizer Rules
+
+
+ FinalizeOverloaded
+ Finalizer Rules
+
+
+ FinalizeDoesNotCallSuperFinalize
+ Finalizer Rules
+
+
+ FinalizeShouldBeProtected
+ Finalizer Rules
+
+
+ AvoidCallingFinalize
+ Finalizer Rules
+
+
+ UseCorrectExceptionLogging
+ Jakarta Commons Logging Rules
+
+
+ ProperLogger
+ Jakarta Commons Logging Rules
+
+
+ MissingSerialVersionUID
+ JavaBean Rules
+
+
+ ProperCloneImplementation
+ Clone Implementation Rules
+
+
+ CloneThrowsCloneNotSupportedException
+ Clone Implementation Rules
+
+
+ CloneMethodMustImplementCloneable
+ Type Resolution Rules
+
+
+ false
+ true
+
diff --git a/.project b/.project
new file mode 100644
index 0000000..799c0bc
--- /dev/null
+++ b/.project
@@ -0,0 +1,33 @@
+
+
+ FonBot
+
+
+
+
+
+ com.android.ide.eclipse.adt.ResourceManagerBuilder
+
+
+
+
+ com.android.ide.eclipse.adt.PreCompilerBuilder
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ com.android.ide.eclipse.adt.ApkBuilder
+
+
+
+
+
+ com.android.ide.eclipse.adt.AndroidNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..8000cd6
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..f9e15c2
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,200 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/lib/android/support/v4/app/NotificationCompat.java b/lib/android/support/v4/app/NotificationCompat.java
new file mode 100644
index 0000000..03881b0
--- /dev/null
+++ b/lib/android/support/v4/app/NotificationCompat.java
@@ -0,0 +1,823 @@
+/*
+ * Copyright (C) 2012 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.support.v4.app;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Build;
+import android.widget.RemoteViews;
+import java.util.ArrayList;
+
+/**
+ * Helper for accessing features in {@link android.app.Notification}
+ * introduced after API level 4 in a backwards compatible fashion.
+ */
+public class NotificationCompat {
+ /**
+ * Obsolete flag indicating high-priority notifications; use the priority field instead.
+ *
+ * @deprecated Use {@link NotificationCompat.Builder#setPriority(int)} with a positive value.
+ */
+ @Deprecated
+ public static final int FLAG_HIGH_PRIORITY = 0x00000080;
+
+ /**
+ * Default notification priority for {@link NotificationCompat.Builder#setPriority(int)}.
+ * If your application does not prioritize its own notifications,
+ * use this value for all notifications.
+ */
+ public static final int PRIORITY_DEFAULT = 0;
+
+ /**
+ * Lower notification priority for {@link NotificationCompat.Builder#setPriority(int)},
+ * for items that are less important. The UI may choose to show
+ * these items smaller, or at a different position in the list,
+ * compared with your app's {@link #PRIORITY_DEFAULT} items.
+ */
+ public static final int PRIORITY_LOW = -1;
+
+ /**
+ * Lowest notification priority for {@link NotificationCompat.Builder#setPriority(int)};
+ * these items might not be shown to the user except under
+ * special circumstances, such as detailed notification logs.
+ */
+ public static final int PRIORITY_MIN = -2;
+
+ /**
+ * Higher notification priority for {@link NotificationCompat.Builder#setPriority(int)},
+ * for more important notifications or alerts. The UI may choose
+ * to show these items larger, or at a different position in
+ * notification lists, compared with your app's {@link #PRIORITY_DEFAULT} items.
+ */
+ public static final int PRIORITY_HIGH = 1;
+
+ /**
+ * Highest notification priority for {@link NotificationCompat.Builder#setPriority(int)},
+ * for your application's most important items that require the user's
+ * prompt attention or input.
+ */
+ public static final int PRIORITY_MAX = 2;
+
+ private static final NotificationCompatImpl IMPL;
+
+ interface NotificationCompatImpl {
+ public Notification build(Builder b);
+ }
+
+ static class NotificationCompatImplBase implements NotificationCompatImpl {
+ @SuppressWarnings("deprecation")
+ @Override
+ public Notification build(Builder b) {
+ Notification result = b.mNotification;
+ result.setLatestEventInfo(b.mContext, b.mContentTitle,
+ b.mContentText, b.mContentIntent);
+ // translate high priority requests into legacy flag
+ if (b.mPriority > PRIORITY_DEFAULT) {
+ result.flags |= FLAG_HIGH_PRIORITY;
+ }
+ return result;
+ }
+ }
+
+ static class NotificationCompatImplHoneycomb implements NotificationCompatImpl {
+ @Override
+ public Notification build(Builder b) {
+ return NotificationCompatHoneycomb.add(b.mContext, b.mNotification,
+ b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView,
+ b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon);
+ }
+ }
+
+ static class NotificationCompatImplIceCreamSandwich implements NotificationCompatImpl {
+ @Override
+ public Notification build(Builder b) {
+ return NotificationCompatIceCreamSandwich.add(b.mContext, b.mNotification,
+ b.mContentTitle, b.mContentText, b.mContentInfo, b.mTickerView,
+ b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
+ b.mProgressMax, b.mProgress, b.mProgressIndeterminate);
+ }
+ }
+
+ static class NotificationCompatImplJellybean implements NotificationCompatImpl {
+ @Override
+ public Notification build(Builder b) {
+ NotificationCompatJellybean jbBuilder = new NotificationCompatJellybean(
+ b.mContext, b.mNotification, b.mContentTitle, b.mContentText, b.mContentInfo,
+ b.mTickerView, b.mNumber, b.mContentIntent, b.mFullScreenIntent, b.mLargeIcon,
+ b.mProgressMax, b.mProgress, b.mProgressIndeterminate,
+ b.mUseChronometer, b.mPriority, b.mSubText);
+ for (Action action: b.mActions) {
+ jbBuilder.addAction(action.icon, action.title, action.actionIntent);
+ }
+ if (b.mStyle != null) {
+ if (b.mStyle instanceof BigTextStyle) {
+ BigTextStyle style = (BigTextStyle) b.mStyle;
+ jbBuilder.addBigTextStyle(style.mBigContentTitle,
+ style.mSummaryTextSet,
+ style.mSummaryText,
+ style.mBigText);
+ } else if (b.mStyle instanceof InboxStyle) {
+ InboxStyle style = (InboxStyle) b.mStyle;
+ jbBuilder.addInboxStyle(style.mBigContentTitle,
+ style.mSummaryTextSet,
+ style.mSummaryText,
+ style.mTexts);
+ } else if (b.mStyle instanceof BigPictureStyle) {
+ BigPictureStyle style = (BigPictureStyle) b.mStyle;
+ jbBuilder.addBigPictureStyle(style.mBigContentTitle,
+ style.mSummaryTextSet,
+ style.mSummaryText,
+ style.mPicture);
+ }
+ }
+ return(jbBuilder.build());
+ }
+ }
+
+ static {
+ if (Build.VERSION.SDK_INT >= 16) {
+ IMPL = new NotificationCompatImplJellybean();
+ } else if (Build.VERSION.SDK_INT >= 14) {
+ IMPL = new NotificationCompatImplIceCreamSandwich();
+ } else if (Build.VERSION.SDK_INT >= 11) {
+ IMPL = new NotificationCompatImplHoneycomb();
+ } else {
+ IMPL = new NotificationCompatImplBase();
+ }
+ }
+
+ /**
+ * Builder class for {@link NotificationCompat} objects. Allows easier control over
+ * all the flags, as well as help constructing the typical notification layouts.
+ *
+ * On platform versions that don't offer expanded notifications, methods that depend on
+ * expanded notifications have no effect.
+ *
+ *
+ * For example, action buttons won't appear on platforms prior to Android 4.1. Action
+ * buttons depend on expanded notifications, which are only available in Android 4.1
+ * and later.
+ *
+ * For this reason, you should always ensure that UI controls in a notification are also
+ * available in an {@link android.app.Activity} in your app, and you should always start that
+ * {@link android.app.Activity} when users click the notification. To do this, use the
+ * {@link NotificationCompat.Builder#setContentIntent setContentIntent()}
+ * method.
+ *
+ *
+ */
+ public static class Builder {
+ Context mContext;
+
+ CharSequence mContentTitle;
+ CharSequence mContentText;
+ PendingIntent mContentIntent;
+ PendingIntent mFullScreenIntent;
+ RemoteViews mTickerView;
+ Bitmap mLargeIcon;
+ CharSequence mContentInfo;
+ int mNumber;
+ int mPriority;
+ boolean mUseChronometer;
+ Style mStyle;
+ CharSequence mSubText;
+ int mProgressMax;
+ int mProgress;
+ boolean mProgressIndeterminate;
+ ArrayList mActions = new ArrayList();
+
+ Notification mNotification = new Notification();
+
+ /**
+ * Constructor.
+ *
+ * Automatically sets the when field to {@link System#currentTimeMillis()
+ * System.currentTimeMillis()} and the audio stream to the
+ * {@link Notification#STREAM_DEFAULT}.
+ *
+ * @param context A {@link Context} that will be used to construct the
+ * RemoteViews. The Context will not be held past the lifetime of this
+ * Builder object.
+ */
+ public Builder(Context context) {
+ mContext = context;
+
+ // Set defaults to match the defaults of a Notification
+ mNotification.when = System.currentTimeMillis();
+ mNotification.audioStreamType = Notification.STREAM_DEFAULT;
+ mPriority = PRIORITY_DEFAULT;
+ }
+
+ /**
+ * Set the time that the event occurred. Notifications in the panel are
+ * sorted by this time.
+ */
+ public Builder setWhen(long when) {
+ mNotification.when = when;
+ return this;
+ }
+
+ /**
+ * Show the {@link Notification#when} field as a stopwatch.
+ *
+ * Instead of presenting when as a timestamp, the notification will show an
+ * automatically updating display of the minutes and seconds since when.
+ *
+ * Useful when showing an elapsed time (like an ongoing phone call).
+ *
+ * @see android.widget.Chronometer
+ * @see Notification#when
+ */
+ public Builder setUsesChronometer(boolean b) {
+ mUseChronometer = b;
+ return this;
+ }
+
+ /**
+ * Set the small icon to use in the notification layouts. Different classes of devices
+ * may return different sizes. See the UX guidelines for more information on how to
+ * design these icons.
+ *
+ * @param icon A resource ID in the application's package of the drawble to use.
+ */
+ public Builder setSmallIcon(int icon) {
+ mNotification.icon = icon;
+ return this;
+ }
+
+ /**
+ * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
+ * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
+ * LevelListDrawable}.
+ *
+ * @param icon A resource ID in the application's package of the drawble to use.
+ * @param level The level to use for the icon.
+ *
+ * @see android.graphics.drawable.LevelListDrawable
+ */
+ public Builder setSmallIcon(int icon, int level) {
+ mNotification.icon = icon;
+ mNotification.iconLevel = level;
+ return this;
+ }
+
+ /**
+ * Set the title (first row) of the notification, in a standard notification.
+ */
+ public Builder setContentTitle(CharSequence title) {
+ mContentTitle = title;
+ return this;
+ }
+
+ /**
+ * Set the text (second row) of the notification, in a standard notification.
+ */
+ public Builder setContentText(CharSequence text) {
+ mContentText = text;
+ return this;
+ }
+
+ /**
+ * Set the third line of text in the platform notification template.
+ * Don't use if you're also using {@link #setProgress(int, int, boolean)};
+ * they occupy the same location in the standard template.
+ *
+ * If the platform does not provide large-format notifications, this method has no effect.
+ * The third line of text only appears in expanded view.
+ *
+ */
+ public Builder setSubText(CharSequence text) {
+ mSubText = text;
+ return this;
+ }
+
+ /**
+ * Set the large number at the right-hand side of the notification. This is
+ * equivalent to setContentInfo, although it might show the number in a different
+ * font size for readability.
+ */
+ public Builder setNumber(int number) {
+ mNumber = number;
+ return this;
+ }
+
+ /**
+ * Set the large text at the right-hand side of the notification.
+ */
+ public Builder setContentInfo(CharSequence info) {
+ mContentInfo = info;
+ return this;
+ }
+
+ /**
+ * Set the progress this notification represents, which may be
+ * represented as a {@link android.widget.ProgressBar}.
+ */
+ public Builder setProgress(int max, int progress, boolean indeterminate) {
+ mProgressMax = max;
+ mProgress = progress;
+ mProgressIndeterminate = indeterminate;
+ return this;
+ }
+
+ /**
+ * Supply a custom RemoteViews to use instead of the standard one.
+ */
+ public Builder setContent(RemoteViews views) {
+ mNotification.contentView = views;
+ return this;
+ }
+
+ /**
+ * Supply a {@link PendingIntent} to send when the notification is clicked.
+ * If you do not supply an intent, you can now add PendingIntents to individual
+ * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
+ * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to
+ * read {@link Notification#contentIntent Notification.contentIntent} for
+ * how to correctly use this.
+ */
+ public Builder setContentIntent(PendingIntent intent) {
+ mContentIntent = intent;
+ return this;
+ }
+
+ /**
+ * Supply a {@link PendingIntent} to send when the notification is cleared by the user
+ * directly from the notification panel. For example, this intent is sent when the user
+ * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
+ * intent is not sent when the application calls {@link NotificationManager#cancel
+ * NotificationManager.cancel(int)}.
+ */
+ public Builder setDeleteIntent(PendingIntent intent) {
+ mNotification.deleteIntent = intent;
+ return this;
+ }
+
+ /**
+ * An intent to launch instead of posting the notification to the status bar.
+ * Only for use with extremely high-priority notifications demanding the user's
+ * immediate attention, such as an incoming phone call or
+ * alarm clock that the user has explicitly set to a particular time.
+ * If this facility is used for something else, please give the user an option
+ * to turn it off and use a normal notification, as this can be extremely
+ * disruptive.
+ *
+ * @param intent The pending intent to launch.
+ * @param highPriority Passing true will cause this notification to be sent
+ * even if other notifications are suppressed.
+ */
+ public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
+ mFullScreenIntent = intent;
+ setFlag(FLAG_HIGH_PRIORITY, highPriority);
+ return this;
+ }
+
+ /**
+ * Set the text that is displayed in the status bar when the notification first
+ * arrives.
+ */
+ public Builder setTicker(CharSequence tickerText) {
+ mNotification.tickerText = tickerText;
+ return this;
+ }
+
+ /**
+ * Set the text that is displayed in the status bar when the notification first
+ * arrives, and also a RemoteViews object that may be displayed instead on some
+ * devices.
+ */
+ public Builder setTicker(CharSequence tickerText, RemoteViews views) {
+ mNotification.tickerText = tickerText;
+ mTickerView = views;
+ return this;
+ }
+
+ /**
+ * Set the large icon that is shown in the ticker and notification.
+ */
+ public Builder setLargeIcon(Bitmap icon) {
+ mLargeIcon = icon;
+ return this;
+ }
+
+ /**
+ * Set the sound to play. It will play on the default stream.
+ */
+ public Builder setSound(Uri sound) {
+ mNotification.sound = sound;
+ mNotification.audioStreamType = Notification.STREAM_DEFAULT;
+ return this;
+ }
+
+ /**
+ * Set the sound to play. It will play on the stream you supply.
+ *
+ * @see #STREAM_DEFAULT
+ * @see AudioManager for the STREAM_ constants.
+ */
+ public Builder setSound(Uri sound, int streamType) {
+ mNotification.sound = sound;
+ mNotification.audioStreamType = streamType;
+ return this;
+ }
+
+ /**
+ * Set the vibration pattern to use.
+ *
+ * @see android.os.Vibrator for a discussion of the pattern
+ * parameter.
+ */
+ public Builder setVibrate(long[] pattern) {
+ mNotification.vibrate = pattern;
+ return this;
+ }
+
+ /**
+ * Set the argb value that you would like the LED on the device to blnk, as well as the
+ * rate. The rate is specified in terms of the number of milliseconds to be on
+ * and then the number of milliseconds to be off.
+ */
+ public Builder setLights(int argb, int onMs, int offMs) {
+ mNotification.ledARGB = argb;
+ mNotification.ledOnMS = onMs;
+ mNotification.ledOffMS = offMs;
+ boolean showLights = mNotification.ledOnMS != 0 && mNotification.ledOffMS != 0;
+ mNotification.flags = (mNotification.flags & ~Notification.FLAG_SHOW_LIGHTS) |
+ (showLights ? Notification.FLAG_SHOW_LIGHTS : 0);
+ return this;
+ }
+
+ /**
+ * Set whether this is an ongoing notification.
+ *
+ *
Ongoing notifications differ from regular notifications in the following ways:
+ *
+ *
Ongoing notifications are sorted above the regular notifications in the
+ * notification panel.
+ *
Ongoing notifications do not have an 'X' close button, and are not affected
+ * by the "Clear all" button.
+ *
+ */
+ public Builder setOngoing(boolean ongoing) {
+ setFlag(Notification.FLAG_ONGOING_EVENT, ongoing);
+ return this;
+ }
+
+ /**
+ * Set this flag if you would only like the sound, vibrate
+ * and ticker to be played if the notification is not already showing.
+ */
+ public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
+ setFlag(Notification.FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
+ return this;
+ }
+
+ /**
+ * Setting this flag will make it so the notification is automatically
+ * canceled when the user clicks it in the panel. The PendingIntent
+ * set with {@link #setDeleteIntent} will be broadcast when the notification
+ * is canceled.
+ */
+ public Builder setAutoCancel(boolean autoCancel) {
+ setFlag(Notification.FLAG_AUTO_CANCEL, autoCancel);
+ return this;
+ }
+
+ /**
+ * Set the default notification options that will be used.
+ *
+ * The value should be one or more of the following fields combined with
+ * bitwise-or:
+ * {@link Notification#DEFAULT_SOUND}, {@link Notification#DEFAULT_VIBRATE},
+ * {@link Notification#DEFAULT_LIGHTS}.
+ *
+ * For all default values, use {@link Notification#DEFAULT_ALL}.
+ */
+ public Builder setDefaults(int defaults) {
+ mNotification.defaults = defaults;
+ if ((defaults & Notification.DEFAULT_LIGHTS) != 0) {
+ mNotification.flags |= Notification.FLAG_SHOW_LIGHTS;
+ }
+ return this;
+ }
+
+ private void setFlag(int mask, boolean value) {
+ if (value) {
+ mNotification.flags |= mask;
+ } else {
+ mNotification.flags &= ~mask;
+ }
+ }
+
+ /**
+ * Set the relative priority for this notification.
+ *
+ * Priority is an indication of how much of the user's
+ * valuable attention should be consumed by this
+ * notification. Low-priority notifications may be hidden from
+ * the user in certain situations, while the user might be
+ * interrupted for a higher-priority notification.
+ * The system sets a notification's priority based on various factors including the
+ * setPriority value. The effect may differ slightly on different platforms.
+ */
+ public Builder setPriority(int pri) {
+ mPriority = pri;
+ return this;
+ }
+
+ /**
+ * Add an action to this notification. Actions are typically displayed by
+ * the system as a button adjacent to the notification content.
+ *
+ * Action buttons won't appear on platforms prior to Android 4.1. Action
+ * buttons depend on expanded notifications, which are only available in Android 4.1
+ * and later. To ensure that an action button's functionality is always available, first
+ * implement the functionality in the {@link android.app.Activity} that starts when a user
+ * clicks the notification (see {@link #setContentIntent setContentIntent()}), and then
+ * enhance the notification by implementing the same functionality with
+ * {@link #addAction addAction()}.
+ *
+ * @param icon Resource ID of a drawable that represents the action.
+ * @param title Text describing the action.
+ * @param intent {@link android.app.PendingIntent} to be fired when the action is invoked.
+ */
+ public Builder addAction(int icon, CharSequence title, PendingIntent intent) {
+ mActions.add(new Action(icon, title, intent));
+ return this;
+ }
+
+ /**
+ * Add a rich notification style to be applied at build time.
+ *
+ * If the platform does not provide rich notification styles, this method has no effect. The
+ * user will always see the normal notification style.
+ *
+ * @param style Object responsible for modifying the notification style.
+ */
+ public Builder setStyle(Style style) {
+ if (mStyle != style) {
+ mStyle = style;
+ if (mStyle != null) {
+ mStyle.setBuilder(this);
+ }
+ }
+ return this;
+ }
+
+ /**
+ * @deprecated Use {@link #build()} instead.
+ */
+ @Deprecated
+ public Notification getNotification() {
+ return IMPL.build(this);
+ }
+
+ /**
+ * Combine all of the options that have been set and return a new {@link Notification}
+ * object.
+ */
+ public Notification build() {
+ return IMPL.build(this);
+ }
+ }
+
+ /**
+ * An object that can apply a rich notification style to a {@link Notification.Builder}
+ * object.
+ *
+ * If the platform does not provide rich notification styles, methods in this class have no
+ * effect.
+ */
+ public static abstract class Style
+ {
+ Builder mBuilder;
+ CharSequence mBigContentTitle;
+ CharSequence mSummaryText;
+ boolean mSummaryTextSet = false;
+
+ public void setBuilder(Builder builder) {
+ if (mBuilder != builder) {
+ mBuilder = builder;
+ if (mBuilder != null) {
+ mBuilder.setStyle(this);
+ }
+ }
+ }
+
+ public Notification build() {
+ Notification notification = null;
+ if (mBuilder != null) {
+ notification = mBuilder.build();
+ }
+ return notification;
+ }
+ }
+
+ /**
+ * Helper class for generating large-format notifications that include a large image attachment.
+ *
+ * If the platform does not provide large-format notifications, this method has no effect. The
+ * user will always see the normal notification view.
+ *
+ * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
+ *
+ *
+ * @see Notification#bigContentView
+ */
+ public static class BigPictureStyle extends Style {
+ Bitmap mPicture;
+
+ public BigPictureStyle() {
+ }
+
+ public BigPictureStyle(Builder builder) {
+ setBuilder(builder);
+ }
+
+ /**
+ * Overrides ContentTitle in the big form of the template.
+ * This defaults to the value passed to setContentTitle().
+ */
+ public BigPictureStyle setBigContentTitle(CharSequence title) {
+ mBigContentTitle = title;
+ return this;
+ }
+
+ /**
+ * Set the first line of text after the detail section in the big form of the template.
+ */
+ public BigPictureStyle setSummaryText(CharSequence cs) {
+ mSummaryText = cs;
+ mSummaryTextSet = true;
+ return this;
+ }
+
+ /**
+ * Provide the bitmap to be used as the payload for the BigPicture notification.
+ */
+ public BigPictureStyle bigPicture(Bitmap b) {
+ mPicture = b;
+ return this;
+ }
+ }
+
+ /**
+ * Helper class for generating large-format notifications that include a lot of text.
+ *
+ *
+ * If the platform does not provide large-format notifications, this method has no effect. The
+ * user will always see the normal notification view.
+ *
+ * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
+ *
+ *
+ * @see Notification#bigContentView
+ */
+ public static class BigTextStyle extends Style {
+ CharSequence mBigText;
+
+ public BigTextStyle() {
+ }
+
+ public BigTextStyle(Builder builder) {
+ setBuilder(builder);
+ }
+
+ /**
+ * Overrides ContentTitle in the big form of the template.
+ * This defaults to the value passed to setContentTitle().
+ */
+ public BigTextStyle setBigContentTitle(CharSequence title) {
+ mBigContentTitle = title;
+ return this;
+ }
+
+ /**
+ * Set the first line of text after the detail section in the big form of the template.
+ */
+ public BigTextStyle setSummaryText(CharSequence cs) {
+ mSummaryText = cs;
+ mSummaryTextSet = true;
+ return this;
+ }
+
+ /**
+ * Provide the longer text to be displayed in the big form of the
+ * template in place of the content text.
+ */
+ public BigTextStyle bigText(CharSequence cs) {
+ mBigText = cs;
+ return this;
+ }
+ }
+
+ /**
+ * Helper class for generating large-format notifications that include a list of (up to 5) strings.
+ *
+ *
+ * If the platform does not provide large-format notifications, this method has no effect. The
+ * user will always see the normal notification view.
+ *
+ * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like so:
+ *
+ *
+ * @see Notification#bigContentView
+ */
+ public static class InboxStyle extends Style {
+ ArrayList mTexts = new ArrayList();
+
+ public InboxStyle() {
+ }
+
+ public InboxStyle(Builder builder) {
+ setBuilder(builder);
+ }
+
+ /**
+ * Overrides ContentTitle in the big form of the template.
+ * This defaults to the value passed to setContentTitle().
+ */
+ public InboxStyle setBigContentTitle(CharSequence title) {
+ mBigContentTitle = title;
+ return this;
+ }
+
+ /**
+ * Set the first line of text after the detail section in the big form of the template.
+ */
+ public InboxStyle setSummaryText(CharSequence cs) {
+ mSummaryText = cs;
+ mSummaryTextSet = true;
+ return this;
+ }
+
+ /**
+ * Append a line to the digest section of the Inbox notification.
+ */
+ public InboxStyle addLine(CharSequence cs) {
+ mTexts.add(cs);
+ return this;
+ }
+ }
+
+ public static class Action {
+ public int icon;
+ public CharSequence title;
+ public PendingIntent actionIntent;
+
+ public Action(int icon_, CharSequence title_, PendingIntent intent_) {
+ this.icon = icon_;
+ this.title = title_;
+ this.actionIntent = intent_;
+ }
+ }
+}
diff --git a/lib/android/support/v4/app/NotificationCompatHoneycomb.java b/lib/android/support/v4/app/NotificationCompatHoneycomb.java
new file mode 100644
index 0000000..5530ecd
--- /dev/null
+++ b/lib/android/support/v4/app/NotificationCompatHoneycomb.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2012 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.support.v4.app;
+
+import android.annotation.TargetApi;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.widget.RemoteViews;
+
+@TargetApi(Build.VERSION_CODES.HONEYCOMB)
+class NotificationCompatHoneycomb {
+ @SuppressWarnings("deprecation")
+ static Notification add(Context context, Notification n,
+ CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
+ RemoteViews tickerView, int number,
+ PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon) {
+ Notification.Builder b = new Notification.Builder(context)
+ .setWhen(n.when)
+ .setSmallIcon(n.icon, n.iconLevel)
+ .setContent(n.contentView)
+ .setTicker(n.tickerText, tickerView)
+ .setSound(n.sound, n.audioStreamType)
+ .setVibrate(n.vibrate)
+ .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
+ .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
+ .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
+ .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
+ .setDefaults(n.defaults)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setContentInfo(contentInfo)
+ .setContentIntent(contentIntent)
+ .setDeleteIntent(n.deleteIntent)
+ .setFullScreenIntent(fullScreenIntent,
+ (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
+ .setLargeIcon(largeIcon)
+ .setNumber(number);
+
+ return b.getNotification();
+ }
+}
diff --git a/lib/android/support/v4/app/NotificationCompatIceCreamSandwich.java b/lib/android/support/v4/app/NotificationCompatIceCreamSandwich.java
new file mode 100644
index 0000000..f3f8cb4
--- /dev/null
+++ b/lib/android/support/v4/app/NotificationCompatIceCreamSandwich.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 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.support.v4.app;
+
+import android.annotation.TargetApi;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.widget.RemoteViews;
+
+@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
+class NotificationCompatIceCreamSandwich {
+ @SuppressWarnings("deprecation")
+ static Notification add(Context context, Notification n,
+ CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
+ RemoteViews tickerView, int number,
+ PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
+ int mProgressMax, int mProgress, boolean mProgressIndeterminate) {
+ Notification.Builder b = new Notification.Builder(context)
+ .setWhen(n.when)
+ .setSmallIcon(n.icon, n.iconLevel)
+ .setContent(n.contentView)
+ .setTicker(n.tickerText, tickerView)
+ .setSound(n.sound, n.audioStreamType)
+ .setVibrate(n.vibrate)
+ .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
+ .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
+ .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
+ .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
+ .setDefaults(n.defaults)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setContentInfo(contentInfo)
+ .setContentIntent(contentIntent)
+ .setDeleteIntent(n.deleteIntent)
+ .setFullScreenIntent(fullScreenIntent,
+ (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
+ .setLargeIcon(largeIcon)
+ .setNumber(number)
+ .setProgress(mProgressMax, mProgress, mProgressIndeterminate);
+
+ return b.getNotification();
+ }
+}
diff --git a/lib/android/support/v4/app/NotificationCompatJellybean.java b/lib/android/support/v4/app/NotificationCompatJellybean.java
new file mode 100644
index 0000000..6cc941f
--- /dev/null
+++ b/lib/android/support/v4/app/NotificationCompatJellybean.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2012 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.support.v4.app;
+
+import android.annotation.TargetApi;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Build;
+import android.widget.RemoteViews;
+import java.util.ArrayList;
+
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
+class NotificationCompatJellybean {
+ private Notification.Builder b;
+ @SuppressWarnings("deprecation")
+ public NotificationCompatJellybean(Context context, Notification n,
+ CharSequence contentTitle, CharSequence contentText, CharSequence contentInfo,
+ RemoteViews tickerView, int number,
+ PendingIntent contentIntent, PendingIntent fullScreenIntent, Bitmap largeIcon,
+ int mProgressMax, int mProgress, boolean mProgressIndeterminate,
+ boolean useChronometer, int priority, CharSequence subText) {
+ b = new Notification.Builder(context)
+ .setWhen(n.when)
+ .setSmallIcon(n.icon, n.iconLevel)
+ .setContent(n.contentView)
+ .setTicker(n.tickerText, tickerView)
+ .setSound(n.sound, n.audioStreamType)
+ .setVibrate(n.vibrate)
+ .setLights(n.ledARGB, n.ledOnMS, n.ledOffMS)
+ .setOngoing((n.flags & Notification.FLAG_ONGOING_EVENT) != 0)
+ .setOnlyAlertOnce((n.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)
+ .setAutoCancel((n.flags & Notification.FLAG_AUTO_CANCEL) != 0)
+ .setDefaults(n.defaults)
+ .setContentTitle(contentTitle)
+ .setContentText(contentText)
+ .setSubText(subText)
+ .setContentInfo(contentInfo)
+ .setContentIntent(contentIntent)
+ .setDeleteIntent(n.deleteIntent)
+ .setFullScreenIntent(fullScreenIntent,
+ (n.flags & Notification.FLAG_HIGH_PRIORITY) != 0)
+ .setLargeIcon(largeIcon)
+ .setNumber(number)
+ .setUsesChronometer(useChronometer)
+ .setPriority(priority)
+ .setProgress(mProgressMax, mProgress, mProgressIndeterminate);
+ }
+
+ public void addAction(int icon, CharSequence title, PendingIntent intent) {
+ b.addAction(icon, title, intent);
+ }
+
+ public void addBigTextStyle(CharSequence bigContentTitle, boolean useSummary,
+ CharSequence summaryText, CharSequence bigText) {
+ Notification.BigTextStyle style = new Notification.BigTextStyle(b)
+ .setBigContentTitle(bigContentTitle)
+ .bigText(bigText);
+ if (useSummary) {
+ style.setSummaryText(summaryText);
+ }
+ }
+
+ public void addBigPictureStyle(CharSequence bigContentTitle, boolean useSummary,
+ CharSequence summaryText, Bitmap bigPicture) {
+ Notification.BigPictureStyle style = new Notification.BigPictureStyle(b)
+ .setBigContentTitle(bigContentTitle)
+ .bigPicture(bigPicture);
+ if (useSummary) {
+ style.setSummaryText(summaryText);
+ }
+ }
+
+ public void addInboxStyle(CharSequence bigContentTitle, boolean useSummary,
+ CharSequence summaryText, ArrayList texts) {
+ Notification.InboxStyle style = new Notification.InboxStyle(b)
+ .setBigContentTitle(bigContentTitle);
+ if (useSummary) {
+ style.setSummaryText(summaryText);
+ }
+ for (CharSequence text: texts) {
+ style.addLine(text);
+ }
+ }
+
+ public Notification build() {
+ return b.build();
+ }
+}
diff --git a/lib/android/support/v4/content/LocalBroadcastManager.java b/lib/android/support/v4/content/LocalBroadcastManager.java
new file mode 100644
index 0000000..7a7c50f
--- /dev/null
+++ b/lib/android/support/v4/content/LocalBroadcastManager.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2011 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.support.v4.content;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+/**
+ * Helper to register for and send broadcasts of Intents to local objects
+ * within your process. This is has a number of advantages over sending
+ * global broadcasts with {@link android.content.Context#sendBroadcast}:
+ *
+ *
You know that the data you are broadcasting won't leave your app, so
+ * don't need to worry about leaking private data.
+ *
It is not possible for other applications to send these broadcasts to
+ * your app, so you don't need to worry about having security holes they can
+ * exploit.
+ *
It is more efficient than sending a global broadcast through the
+ * system.
+ *
+ */
+public class LocalBroadcastManager {
+ private static class ReceiverRecord {
+ final IntentFilter filter;
+ final BroadcastReceiver receiver;
+ boolean broadcasting;
+
+ ReceiverRecord(IntentFilter _filter, BroadcastReceiver _receiver) {
+ filter = _filter;
+ receiver = _receiver;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(128);
+ builder.append("Receiver{");
+ builder.append(receiver);
+ builder.append(" filter=");
+ builder.append(filter);
+ builder.append("}");
+ return builder.toString();
+ }
+ }
+
+ private static class BroadcastRecord {
+ final Intent intent;
+ final ArrayList receivers;
+
+ BroadcastRecord(Intent _intent, ArrayList _receivers) {
+ intent = _intent;
+ receivers = _receivers;
+ }
+ }
+
+ private static final String TAG = "LocalBroadcastManager";
+ private static final boolean DEBUG = false;
+
+ private final Context mAppContext;
+
+ private final HashMap> mReceivers
+ = new HashMap>();
+ private final HashMap> mActions
+ = new HashMap>();
+
+ private final ArrayList mPendingBroadcasts
+ = new ArrayList();
+
+ static final int MSG_EXEC_PENDING_BROADCASTS = 1;
+
+ private final Handler mHandler;
+
+ private static final Object mLock = new Object();
+ private static LocalBroadcastManager mInstance;
+
+ public static LocalBroadcastManager getInstance(Context context) {
+ synchronized (mLock) {
+ if (mInstance == null) {
+ mInstance = new LocalBroadcastManager(context.getApplicationContext());
+ }
+ return mInstance;
+ }
+ }
+
+ private LocalBroadcastManager(Context context) {
+ mAppContext = context;
+ mHandler = new Handler(context.getMainLooper()) {
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_EXEC_PENDING_BROADCASTS:
+ executePendingBroadcasts();
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ };
+ }
+
+ /**
+ * Register a receive for any local broadcasts that match the given IntentFilter.
+ *
+ * @param receiver The BroadcastReceiver to handle the broadcast.
+ * @param filter Selects the Intent broadcasts to be received.
+ *
+ * @see #unregisterReceiver
+ */
+ public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
+ synchronized (mReceivers) {
+ ReceiverRecord entry = new ReceiverRecord(filter, receiver);
+ ArrayList filters = mReceivers.get(receiver);
+ if (filters == null) {
+ filters = new ArrayList(1);
+ mReceivers.put(receiver, filters);
+ }
+ filters.add(filter);
+ for (int i=0; i entries = mActions.get(action);
+ if (entries == null) {
+ entries = new ArrayList(1);
+ mActions.put(action, entries);
+ }
+ entries.add(entry);
+ }
+ }
+ }
+
+ /**
+ * Unregister a previously registered BroadcastReceiver. All
+ * filters that have been registered for this BroadcastReceiver will be
+ * removed.
+ *
+ * @param receiver The BroadcastReceiver to unregister.
+ *
+ * @see #registerReceiver
+ */
+ public void unregisterReceiver(BroadcastReceiver receiver) {
+ synchronized (mReceivers) {
+ ArrayList filters = mReceivers.remove(receiver);
+ if (filters == null) {
+ return;
+ }
+ for (int i=0; i receivers = mActions.get(action);
+ if (receivers != null) {
+ for (int k=0; k categories = intent.getCategories();
+
+ final boolean debug = DEBUG ||
+ ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
+ if (debug) Log.v(
+ TAG, "Resolving type " + type + " scheme " + scheme
+ + " of intent " + intent);
+
+ ArrayList entries = mActions.get(intent.getAction());
+ if (entries != null) {
+ if (debug) Log.v(TAG, "Action list: " + entries);
+
+ ArrayList receivers = null;
+ for (int i=0; i= 0) {
+ if (debug) Log.v(TAG, " Filter matched! match=0x" +
+ Integer.toHexString(match));
+ if (receivers == null) {
+ receivers = new ArrayList();
+ }
+ receivers.add(receiver);
+ receiver.broadcasting = true;
+ } else {
+ if (debug) {
+ String reason;
+ switch (match) {
+ case IntentFilter.NO_MATCH_ACTION: reason = "action"; break;
+ case IntentFilter.NO_MATCH_CATEGORY: reason = "category"; break;
+ case IntentFilter.NO_MATCH_DATA: reason = "data"; break;
+ case IntentFilter.NO_MATCH_TYPE: reason = "type"; break;
+ default: reason = "unknown reason"; break;
+ }
+ Log.v(TAG, " Filter did not match: " + reason);
+ }
+ }
+ }
+
+ if (receivers != null) {
+ for (int i=0; i
+ * The abstract methods in this class are called from its worker thread, and
+ * hence should run in a limited amount of time. If they execute long
+ * operations, they should spawn new threads, otherwise the worker thread will
+ * be blocked.
+ *
+ * Subclasses must provide a public no-arg constructor.
+ */
+public abstract class GCMBaseIntentService extends IntentService {
+
+ public static final String TAG = "GCMBaseIntentService";
+
+ // wakelock
+ private static final String WAKELOCK_KEY = "GCM_LIB";
+ private static PowerManager.WakeLock sWakeLock;
+
+ // Java lock used to synchronize access to sWakelock
+ private static final Object LOCK = GCMBaseIntentService.class;
+
+ private final String[] mSenderIds;
+
+ // instance counter
+ private static int sCounter = 0;
+
+ private static final Random sRandom = new Random();
+
+ private static final int MAX_BACKOFF_MS =
+ (int) TimeUnit.SECONDS.toMillis(3600); // 1 hour
+
+ // token used to check intent origin
+ private static final String TOKEN =
+ Long.toBinaryString(sRandom.nextLong());
+ private static final String EXTRA_TOKEN = "token";
+
+ /**
+ * Constructor that does not set a sender id, useful when the sender id
+ * is context-specific.
+ *
+ * When using this constructor, the subclass must
+ * override {@link #getSenderIds(Context)}, otherwise methods such as
+ * {@link #onHandleIntent(Intent)} will throw an
+ * {@link IllegalStateException} on runtime.
+ */
+ protected GCMBaseIntentService() {
+ this(getName("DynamicSenderIds"), null);
+ }
+
+ /**
+ * Constructor used when the sender id(s) is fixed.
+ */
+ protected GCMBaseIntentService(String... senderIds) {
+ this(getName(senderIds), senderIds);
+ }
+
+ private GCMBaseIntentService(String name, String[] senderIds) {
+ super(name); // name is used as base name for threads, etc.
+ mSenderIds = senderIds;
+ }
+
+ private static String getName(String senderId) {
+ String name = "GCMIntentService-" + senderId + "-" + (++sCounter);
+ Log.v(TAG, "Intent service name: " + name);
+ return name;
+ }
+
+ private static String getName(String[] senderIds) {
+ String flatSenderIds = GCMRegistrar.getFlatSenderIds(senderIds);
+ return getName(flatSenderIds);
+ }
+
+ /**
+ * Gets the sender ids.
+ *
+ *
By default, it returns the sender ids passed in the constructor, but
+ * it could be overridden to provide a dynamic sender id.
+ *
+ * @throws IllegalStateException if sender id was not set on constructor.
+ */
+ protected String[] getSenderIds() {
+ if (mSenderIds == null) {
+ throw new IllegalStateException("sender id not set on constructor");
+ }
+ return mSenderIds;
+ }
+
+ /**
+ * Called when a cloud message has been received.
+ *
+ * @param context application's context.
+ * @param intent intent containing the message payload as extras.
+ */
+ protected abstract void onMessage(Context context, Intent intent);
+
+ /**
+ * Called when the GCM server tells pending messages have been deleted
+ * because the device was idle.
+ *
+ * @param context application's context.
+ * @param total total number of collapsed messages
+ */
+ protected void onDeletedMessages(Context context, int total) {
+ //do nothing
+ }
+
+ /**
+ * Called on a registration error that could be retried.
+ *
+ *
By default, it does nothing and returns {@literal true}, but could be
+ * overridden to change that behavior and/or display the error.
+ *
+ * @param context application's context.
+ * @param errorId error id returned by the GCM service.
+ *
+ * @return if {@literal true}, failed operation will be retried (using
+ * exponential backoff).
+ */
+ protected static boolean onRecoverableError(Context context, String errorId) {
+ return true;
+ }
+
+ /**
+ * Called on registration or unregistration error.
+ *
+ * @param context application's context.
+ * @param errorId error id returned by the GCM service.
+ */
+ protected abstract void onError(Context context, String errorId);
+
+ /**
+ * Called after a device has been registered.
+ *
+ * @param context application's context.
+ * @param registrationId the registration id returned by the GCM service.
+ */
+ protected abstract void onRegistered(Context context,
+ String registrationId);
+
+ /**
+ * Called after a device has been unregistered.
+ *
+ * @param registrationId the registration id that was previously registered.
+ * @param context application's context.
+ */
+ protected abstract void onUnregistered(Context context,
+ String registrationId);
+
+ @Override
+ public final void onHandleIntent(Intent intent) {
+ try {
+ Context context = getApplicationContext();
+ String action = intent.getAction();
+ if (action.equals(INTENT_FROM_GCM_REGISTRATION_CALLBACK)) {
+ GCMRegistrar.setRetryBroadcastReceiver(context);
+ handleRegistration(context, intent);
+ } else if (action.equals(INTENT_FROM_GCM_MESSAGE)) {
+ // checks for special messages
+ String messageType =
+ intent.getStringExtra(EXTRA_SPECIAL_MESSAGE);
+ if (messageType != null) {
+ if (messageType.equals(VALUE_DELETED_MESSAGES)) {
+ String sTotal =
+ intent.getStringExtra(EXTRA_TOTAL_DELETED);
+ if (sTotal != null) {
+ try {
+ int total = Integer.parseInt(sTotal);
+ Log.v(TAG, "Received deleted messages " +
+ "notification: " + total);
+ onDeletedMessages(context, total);
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "GCM returned invalid number of " +
+ "deleted messages: " + sTotal);
+ }
+ }
+ } else {
+ // application is not using the latest GCM library
+ Log.e(TAG, "Received unknown special message: " +
+ messageType);
+ }
+ } else {
+ onMessage(context, intent);
+ }
+ } else if (action.equals(INTENT_FROM_GCM_LIBRARY_RETRY)) {
+ String token = intent.getStringExtra(EXTRA_TOKEN);
+ if (!TOKEN.equals(token)) {
+ // make sure intent was generated by this class, not by a
+ // malicious app.
+ Log.e(TAG, "Received invalid token: " + token);
+ return;
+ }
+ // retry last call
+ if (GCMRegistrar.isRegistered(context)) {
+ GCMRegistrar.internalUnregister(context);
+ } else {
+ String[] senderIds = getSenderIds();
+ GCMRegistrar.internalRegister(context, senderIds);
+ }
+ }
+ } finally {
+ // Release the power lock, so phone can get back to sleep.
+ // The lock is reference-counted by default, so multiple
+ // messages are ok.
+
+ // If onMessage() needs to spawn a thread or do something else,
+ // it should use its own lock.
+ synchronized (LOCK) {
+ // sanity check for null as this is a public method
+ if (sWakeLock != null) {
+ Log.v(TAG, "Releasing wakelock");
+ sWakeLock.release();
+ } else {
+ // should never happen during normal workflow
+ Log.e(TAG, "Wakelock reference is null");
+ }
+ }
+ }
+ }
+
+ /**
+ * Called from the broadcast receiver.
+ *
+ * Will process the received intent, call handleMessage(), registered(),
+ * etc. in background threads, with a wake lock, while keeping the service
+ * alive.
+ */
+ static void runIntentInService(Context context, Intent intent,
+ String className) {
+ synchronized (LOCK) {
+ if (sWakeLock == null) {
+ // This is called from BroadcastReceiver, there is no init.
+ PowerManager pm = (PowerManager)
+ context.getSystemService(Context.POWER_SERVICE);
+ sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ WAKELOCK_KEY);
+ }
+ }
+ Log.v(TAG, "Acquiring wakelock");
+ sWakeLock.acquire();
+ intent.setClassName(context, className);
+ context.startService(intent);
+ }
+
+ private void handleRegistration(final Context context, Intent intent) {
+ String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID);
+ String error = intent.getStringExtra(EXTRA_ERROR);
+ String unregistered = intent.getStringExtra(EXTRA_UNREGISTERED);
+ Log.d(TAG, "handleRegistration: registrationId = " + registrationId +
+ ", error = " + error + ", unregistered = " + unregistered);
+
+ // registration succeeded
+ if (registrationId != null) {
+ GCMRegistrar.resetBackoff(context);
+ GCMRegistrar.setRegistrationId(context, registrationId);
+ onRegistered(context, registrationId);
+ return;
+ }
+
+ // unregistration succeeded
+ if (unregistered != null) {
+ // Remember we are unregistered
+ GCMRegistrar.resetBackoff(context);
+ String oldRegistrationId =
+ GCMRegistrar.clearRegistrationId(context);
+ onUnregistered(context, oldRegistrationId);
+ return;
+ }
+
+ // last operation (registration or unregistration) returned an error;
+ Log.d(TAG, "Registration error: " + error);
+ // Registration failed
+ if (ERROR_SERVICE_NOT_AVAILABLE.equals(error)) {
+ boolean retry = onRecoverableError(context, error);
+ if (retry) {
+ int backoffTimeMs = GCMRegistrar.getBackoff(context);
+ int nextAttempt = backoffTimeMs / 2 +
+ sRandom.nextInt(backoffTimeMs);
+ Log.d(TAG, "Scheduling registration retry, backoff = " +
+ nextAttempt + " (" + backoffTimeMs + ")");
+ Intent retryIntent =
+ new Intent(INTENT_FROM_GCM_LIBRARY_RETRY);
+ retryIntent.putExtra(EXTRA_TOKEN, TOKEN);
+ PendingIntent retryPendingIntent = PendingIntent
+ .getBroadcast(context, 0, retryIntent, 0);
+ AlarmManager am = (AlarmManager)
+ context.getSystemService(Context.ALARM_SERVICE);
+ am.set(AlarmManager.ELAPSED_REALTIME,
+ SystemClock.elapsedRealtime() + nextAttempt,
+ retryPendingIntent);
+ // Next retry should wait longer.
+ if (backoffTimeMs < MAX_BACKOFF_MS) {
+ GCMRegistrar.setBackoff(context, backoffTimeMs * 2);
+ }
+ } else {
+ Log.d(TAG, "Not retrying failed operation");
+ }
+ } else {
+ // Unrecoverable error, notify app
+ onError(context, error);
+ }
+ }
+
+}
diff --git a/lib/com/google/android/gcm/GCMBroadcastReceiver.java b/lib/com/google/android/gcm/GCMBroadcastReceiver.java
new file mode 100644
index 0000000..bbe7b66
--- /dev/null
+++ b/lib/com/google/android/gcm/GCMBroadcastReceiver.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * 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 com.google.android.gcm;
+
+import static com.google.android.gcm.GCMConstants.DEFAULT_INTENT_SERVICE_CLASS_NAME;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+/**
+ * {@link BroadcastReceiver} that receives GCM messages and delivers them to
+ * an application-specific {@link GCMBaseIntentService} subclass.
+ *
+ * By default, the {@link GCMBaseIntentService} class belongs to the application
+ * main package and is named
+ * {@link GCMConstants#DEFAULT_INTENT_SERVICE_CLASS_NAME}. To use a new class,
+ * the {@link #getGCMIntentServiceClassName(Context)} must be overridden.
+ */
+public final class GCMBroadcastReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "GCMBroadcastReceiver";
+ private static boolean mReceiverSet = false;
+
+ @Override
+ public final void onReceive(Context context, Intent intent) {
+ Log.v(TAG, "onReceive: " + intent.getAction());
+ // do a one-time check if app is using a custom GCMBroadcastReceiver
+ if (!mReceiverSet) {
+ mReceiverSet = true;
+ String myClass = getClass().getName();
+ if (!myClass.equals(GCMBroadcastReceiver.class.getName())) {
+ GCMRegistrar.setRetryReceiverClassName(myClass);
+ }
+ }
+ String className = getGCMIntentServiceClassName(context);
+ Log.v(TAG, "GCM IntentService class: " + className);
+ // Delegates to the application-specific intent service.
+ GCMBaseIntentService.runIntentInService(context, intent, className);
+ setResult(Activity.RESULT_OK, null /* data */, null /* extra */);
+ }
+
+ /**
+ * Gets the class name of the intent service that will handle GCM messages.
+ */
+ protected static String getGCMIntentServiceClassName(final Context context) {
+ return getDefaultIntentServiceClassName(context);
+ }
+
+ /**
+ * Gets the default class name of the intent service that will handle GCM
+ * messages.
+ */
+ private static final String getDefaultIntentServiceClassName(final Context context) {
+ String className = context.getPackageName() +
+ DEFAULT_INTENT_SERVICE_CLASS_NAME;
+ return className;
+ }
+}
diff --git a/lib/com/google/android/gcm/GCMConstants.java b/lib/com/google/android/gcm/GCMConstants.java
new file mode 100644
index 0000000..abcdcfb
--- /dev/null
+++ b/lib/com/google/android/gcm/GCMConstants.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * 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 com.google.android.gcm;
+
+/**
+ * Constants used by the GCM library.
+ */
+public final class GCMConstants {
+
+ /**
+ * Intent sent to GCM to register the application.
+ */
+ public static final String INTENT_TO_GCM_REGISTRATION =
+ "com.google.android.c2dm.intent.REGISTER";
+
+ /**
+ * Intent sent to GCM to unregister the application.
+ */
+ public static final String INTENT_TO_GCM_UNREGISTRATION =
+ "com.google.android.c2dm.intent.UNREGISTER";
+
+ /**
+ * Intent sent by GCM indicating with the result of a registration request.
+ */
+ public static final String INTENT_FROM_GCM_REGISTRATION_CALLBACK =
+ "com.google.android.c2dm.intent.REGISTRATION";
+
+ /**
+ * Intent used by the GCM library to indicate that the registration call
+ * should be retried.
+ */
+ public static final String INTENT_FROM_GCM_LIBRARY_RETRY =
+ "com.google.android.gcm.intent.RETRY";
+
+ /**
+ * Intent sent by GCM containing a message.
+ */
+ public static final String INTENT_FROM_GCM_MESSAGE =
+ "com.google.android.c2dm.intent.RECEIVE";
+
+ /**
+ * Extra used on {@link #INTENT_TO_GCM_REGISTRATION} to indicate the sender
+ * account (a Google email) that owns the application.
+ */
+ public static final String EXTRA_SENDER = "sender";
+
+ /**
+ * Extra used on {@link #INTENT_TO_GCM_REGISTRATION} to get the application
+ * id.
+ */
+ public static final String EXTRA_APPLICATION_PENDING_INTENT = "app";
+
+ /**
+ * Extra used on {@link #INTENT_FROM_GCM_REGISTRATION_CALLBACK} to indicate
+ * that the application has been unregistered.
+ */
+ public static final String EXTRA_UNREGISTERED = "unregistered";
+
+ /**
+ * Extra used on {@link #INTENT_FROM_GCM_REGISTRATION_CALLBACK} to indicate
+ * an error when the registration fails. See constants starting with ERROR_
+ * for possible values.
+ */
+ public static final String EXTRA_ERROR = "error";
+
+ /**
+ * Extra used on {@link #INTENT_FROM_GCM_REGISTRATION_CALLBACK} to indicate
+ * the registration id when the registration succeeds.
+ */
+ public static final String EXTRA_REGISTRATION_ID = "registration_id";
+
+ /**
+ * Type of message present in the {@link #INTENT_FROM_GCM_MESSAGE} intent.
+ * This extra is only set for special messages sent from GCM, not for
+ * messages originated from the application.
+ */
+ public static final String EXTRA_SPECIAL_MESSAGE = "message_type";
+
+ /**
+ * Special message indicating the server deleted the pending messages.
+ */
+ public static final String VALUE_DELETED_MESSAGES = "deleted_messages";
+
+ /**
+ * Number of messages deleted by the server because the device was idle.
+ * Present only on messages of special type
+ * {@link #VALUE_DELETED_MESSAGES}
+ */
+ public static final String EXTRA_TOTAL_DELETED = "total_deleted";
+
+ /**
+ * Permission necessary to receive GCM intents.
+ */
+ public static final String PERMISSION_GCM_INTENTS =
+ "com.google.android.c2dm.permission.SEND";
+
+ /**
+ * @see GCMBroadcastReceiver
+ */
+ public static final String DEFAULT_INTENT_SERVICE_CLASS_NAME =
+ ".GCMIntentService";
+
+ /**
+ * The device can't read the response, or there was a 500/503 from the
+ * server that can be retried later. The application should use exponential
+ * back off and retry.
+ */
+ public static final String ERROR_SERVICE_NOT_AVAILABLE =
+ "SERVICE_NOT_AVAILABLE";
+
+ /**
+ * There is no Google account on the phone. The application should ask the
+ * user to open the account manager and add a Google account.
+ */
+ public static final String ERROR_ACCOUNT_MISSING =
+ "ACCOUNT_MISSING";
+
+ /**
+ * Bad password. The application should ask the user to enter his/her
+ * password, and let user retry manually later. Fix on the device side.
+ */
+ public static final String ERROR_AUTHENTICATION_FAILED =
+ "AUTHENTICATION_FAILED";
+
+ /**
+ * The request sent by the phone does not contain the expected parameters.
+ * This phone doesn't currently support GCM.
+ */
+ public static final String ERROR_INVALID_PARAMETERS =
+ "INVALID_PARAMETERS";
+ /**
+ * The sender account is not recognized. Fix on the device side.
+ */
+ public static final String ERROR_INVALID_SENDER =
+ "INVALID_SENDER";
+
+ /**
+ * Incorrect phone registration with Google. This phone doesn't currently
+ * support GCM.
+ */
+ public static final String ERROR_PHONE_REGISTRATION_ERROR =
+ "PHONE_REGISTRATION_ERROR";
+
+ private GCMConstants() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/lib/com/google/android/gcm/GCMRegistrar.java b/lib/com/google/android/gcm/GCMRegistrar.java
new file mode 100644
index 0000000..0bd5c9f
--- /dev/null
+++ b/lib/com/google/android/gcm/GCMRegistrar.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * 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 com.google.android.gcm;
+
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Build;
+import android.util.Log;
+
+/**
+ * Utilities for device registration.
+ *
+ * Note: this class uses a private {@link SharedPreferences}
+ * object to keep track of the registration token.
+ */
+public final class GCMRegistrar {
+
+ /**
+ * Default lifespan (7 days) of the {@link #isRegisteredOnServer(Context)}
+ * flag until it is considered expired.
+ */
+ // NOTE: cannot use TimeUnit.DAYS because it's not available on API Level 8
+ public static final long DEFAULT_ON_SERVER_LIFESPAN_MS =
+ 1000 * 3600 * 24 * 7;
+
+ private static final String TAG = "GCMRegistrar";
+ private static final String BACKOFF_MS = "backoff_ms";
+ private static final String GSF_PACKAGE = "com.google.android.gsf";
+ private static final String PREFERENCES = "com.google.android.gcm";
+ private static final int DEFAULT_BACKOFF_MS = 3000;
+ private static final String PROPERTY_REG_ID = "regId";
+ private static final String PROPERTY_APP_VERSION = "appVersion";
+ /**
+ * {@link GCMBroadcastReceiver} instance used to handle the retry intent.
+ *
+ *
+ * This instance cannot be the same as the one defined in the manifest
+ * because it needs a different permission.
+ */
+ private static GCMBroadcastReceiver sRetryReceiver;
+
+ private static String sRetryReceiverClassName;
+
+ /**
+ * Checks if the device has the proper dependencies installed.
+ *
+ * This method should be called when the application starts to verify that
+ * the device supports GCM.
+ *
+ * @param context application context.
+ * @throws UnsupportedOperationException if the device does not support GCM.
+ */
+ public static void checkDevice(final Context context) {
+ final int version = Build.VERSION.SDK_INT;
+ if (version < 8) {
+ throw new UnsupportedOperationException("Device must be at least " +
+ "API Level 8 (instead of " + version + ")");
+ }
+ final PackageManager packageManager = context.getPackageManager();
+ try {
+ packageManager.getPackageInfo(GSF_PACKAGE, 0);
+ } catch (NameNotFoundException e) {
+ throw new UnsupportedOperationException(
+ "Device does not have package " + GSF_PACKAGE);
+ }
+ }
+
+ /**
+ * Initiate messaging registration for the current application.
+ *
+ * The result will be returned as an
+ * {@link GCMConstants#INTENT_FROM_GCM_REGISTRATION_CALLBACK} intent with
+ * either a {@link GCMConstants#EXTRA_REGISTRATION_ID} or
+ * {@link GCMConstants#EXTRA_ERROR}.
+ *
+ * @param context application context.
+ * @param senderIds Google Project ID of the accounts authorized to send
+ * messages to this application.
+ * @throws IllegalStateException if device does not have all GCM
+ * dependencies installed.
+ */
+ public static void register(Context context, String... senderIds) {
+ GCMRegistrar.resetBackoff(context);
+ internalRegister(context, senderIds);
+ }
+
+ static void internalRegister(Context context, String... senderIds) {
+ String flatSenderIds = getFlatSenderIds(senderIds);
+ Log.v(TAG, "Registering app " + context.getPackageName() +
+ " of senders " + flatSenderIds);
+ Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_REGISTRATION);
+ intent.setPackage(GSF_PACKAGE);
+ intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
+ PendingIntent.getBroadcast(context, 0, new Intent(), 0));
+ intent.putExtra(GCMConstants.EXTRA_SENDER, flatSenderIds);
+ context.startService(intent);
+ }
+
+ static String getFlatSenderIds(String... senderIds) {
+ if (senderIds == null || senderIds.length == 0) {
+ throw new IllegalArgumentException("No senderIds");
+ }
+ StringBuilder builder = new StringBuilder(senderIds[0]);
+ for (int i = 1; i < senderIds.length; i++) {
+ builder.append(',').append(senderIds[i]);
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Clear internal resources.
+ *
+ *
+ * This method should be called by the main activity's {@code onDestroy()}
+ * method.
+ */
+ public static synchronized void onDestroy(Context context) {
+ if (sRetryReceiver != null) {
+ Log.v(TAG, "Unregistering receiver");
+ context.unregisterReceiver(sRetryReceiver);
+ sRetryReceiver = null;
+ }
+ }
+
+ static void internalUnregister(Context context) {
+ Log.v(TAG, "Unregistering app " + context.getPackageName());
+ Intent intent = new Intent(GCMConstants.INTENT_TO_GCM_UNREGISTRATION);
+ intent.setPackage(GSF_PACKAGE);
+ intent.putExtra(GCMConstants.EXTRA_APPLICATION_PENDING_INTENT,
+ PendingIntent.getBroadcast(context, 0, new Intent(), 0));
+ context.startService(intent);
+ }
+
+ /**
+ * Lazy initializes the {@link GCMBroadcastReceiver} instance.
+ */
+ static synchronized void setRetryBroadcastReceiver(Context context) {
+ if (sRetryReceiver == null) {
+ if (sRetryReceiverClassName == null) {
+ // should never happen
+ Log.e(TAG, "internal error: retry receiver class not set yet");
+ sRetryReceiver = new GCMBroadcastReceiver();
+ } else {
+ Class> clazz;
+ try {
+ clazz = Class.forName(sRetryReceiverClassName);
+ sRetryReceiver = (GCMBroadcastReceiver) clazz.newInstance();
+ } catch (Exception e) {
+ Log.e(TAG, "Could not create instance of " +
+ sRetryReceiverClassName + ". Using " +
+ GCMBroadcastReceiver.class.getName() +
+ " directly.");
+ sRetryReceiver = new GCMBroadcastReceiver();
+ }
+ }
+ String category = context.getPackageName();
+ IntentFilter filter = new IntentFilter(
+ GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY);
+ filter.addCategory(category);
+ // must use a permission that is defined on manifest for sure
+ String permission = category + ".permission.C2D_MESSAGE";
+ Log.v(TAG, "Registering receiver");
+ context.registerReceiver(sRetryReceiver, filter, permission, null);
+ }
+ }
+
+ /**
+ * Sets the name of the retry receiver class.
+ */
+ static void setRetryReceiverClassName(String className) {
+ Log.v(TAG, "Setting the name of retry receiver class to " + className);
+ sRetryReceiverClassName = className;
+ }
+
+ /**
+ * Gets the current registration id for application on GCM service.
+ *
+ * If result is empty, the registration has failed.
+ *
+ * @return registration id, or empty string if the registration is not
+ * complete.
+ */
+ public static String getRegistrationId(Context context) {
+ final SharedPreferences prefs = getGCMPreferences(context);
+ String registrationId = prefs.getString(PROPERTY_REG_ID, "");
+ // check if app was updated; if so, it must clear registration id to
+ // avoid a race condition if GCM sends a message
+ int oldVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
+ int newVersion = getAppVersion(context);
+ if (oldVersion != Integer.MIN_VALUE && oldVersion != newVersion) {
+ Log.v(TAG, "App version changed from " + oldVersion + " to " +
+ newVersion + "; resetting registration id");
+ clearRegistrationId(context);
+ registrationId = "";
+ }
+ return registrationId;
+ }
+
+ /**
+ * Checks whether the application was successfully registered on GCM
+ * service.
+ */
+ static boolean isRegistered(Context context) {
+ return getRegistrationId(context).length() > 0;
+ }
+
+ /**
+ * Clears the registration id in the persistence store.
+ *
+ * @param context application's context.
+ * @return old registration id.
+ */
+ static String clearRegistrationId(Context context) {
+ return setRegistrationId(context, "");
+ }
+
+ /**
+ * Sets the registration id in the persistence store.
+ *
+ * @param context application's context.
+ * @param regId registration id
+ */
+ static String setRegistrationId(Context context, String regId) {
+ final SharedPreferences prefs = getGCMPreferences(context);
+ String oldRegistrationId = prefs.getString(PROPERTY_REG_ID, "");
+ int appVersion = getAppVersion(context);
+ Log.v(TAG, "Saving regId on app version " + appVersion);
+ Editor editor = prefs.edit();
+ editor.putString(PROPERTY_REG_ID, regId);
+ editor.putInt(PROPERTY_APP_VERSION, appVersion);
+ editor.commit();
+ return oldRegistrationId;
+ }
+
+ /**
+ * Gets the application version.
+ */
+ private static int getAppVersion(Context context) {
+ try {
+ PackageInfo packageInfo = context.getPackageManager()
+ .getPackageInfo(context.getPackageName(), 0);
+ return packageInfo.versionCode;
+ } catch (NameNotFoundException e) {
+ // should never happen
+ throw new RuntimeException("Coult not get package name: " + e);
+ }
+ }
+
+ /**
+ * Resets the backoff counter.
+ *
+ * This method should be called after a GCM call succeeds.
+ *
+ * @param context application's context.
+ */
+ static void resetBackoff(Context context) {
+ Log.d(TAG, "resetting backoff for " + context.getPackageName());
+ setBackoff(context, DEFAULT_BACKOFF_MS);
+ }
+
+ /**
+ * Gets the current backoff counter.
+ *
+ * @param context application's context.
+ * @return current backoff counter, in milliseconds.
+ */
+ static int getBackoff(Context context) {
+ final SharedPreferences prefs = getGCMPreferences(context);
+ return prefs.getInt(BACKOFF_MS, DEFAULT_BACKOFF_MS);
+ }
+
+ /**
+ * Sets the backoff counter.
+ *
+ * This method should be called after a GCM call fails, passing an
+ * exponential value.
+ *
+ * @param context application's context.
+ * @param backoff new backoff counter, in milliseconds.
+ */
+ static void setBackoff(Context context, int backoff) {
+ final SharedPreferences prefs = getGCMPreferences(context);
+ Editor editor = prefs.edit();
+ editor.putInt(BACKOFF_MS, backoff);
+ editor.commit();
+ }
+
+ private static SharedPreferences getGCMPreferences(Context context) {
+ return context.getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE);
+ }
+
+ private GCMRegistrar() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/proguard-project.txt b/proguard-project.txt
new file mode 100644
index 0000000..5a93951
--- /dev/null
+++ b/proguard-project.txt
@@ -0,0 +1,21 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+-dontobfuscate
+-libraryjars org.eclipse.jdt.annotation_1.0.0.dist.jar
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..a3ee5ab
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,14 @@
+# 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 edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-17
diff --git a/res/drawable-hdpi/cross.png b/res/drawable-hdpi/cross.png
new file mode 100644
index 0000000..44fae3f
Binary files /dev/null and b/res/drawable-hdpi/cross.png differ
diff --git a/res/drawable-hdpi/tick.png b/res/drawable-hdpi/tick.png
new file mode 100644
index 0000000..20068da
Binary files /dev/null and b/res/drawable-hdpi/tick.png differ
diff --git a/res/drawable-ldpi/cross.png b/res/drawable-ldpi/cross.png
new file mode 100644
index 0000000..6f00756
Binary files /dev/null and b/res/drawable-ldpi/cross.png differ
diff --git a/res/drawable-ldpi/tick.png b/res/drawable-ldpi/tick.png
new file mode 100644
index 0000000..360e423
Binary files /dev/null and b/res/drawable-ldpi/tick.png differ
diff --git a/res/drawable-mdpi/cross.png b/res/drawable-mdpi/cross.png
new file mode 100644
index 0000000..7cf518d
Binary files /dev/null and b/res/drawable-mdpi/cross.png differ
diff --git a/res/drawable-mdpi/tick.png b/res/drawable-mdpi/tick.png
new file mode 100644
index 0000000..f80d294
Binary files /dev/null and b/res/drawable-mdpi/tick.png differ
diff --git a/res/drawable-xhdpi/cross.png b/res/drawable-xhdpi/cross.png
new file mode 100644
index 0000000..e17cadd
Binary files /dev/null and b/res/drawable-xhdpi/cross.png differ
diff --git a/res/drawable-xhdpi/tick.png b/res/drawable-xhdpi/tick.png
new file mode 100644
index 0000000..3e775e0
Binary files /dev/null and b/res/drawable-xhdpi/tick.png differ
diff --git a/res/layout/local.xml b/res/layout/local.xml
new file mode 100644
index 0000000..2164b5c
--- /dev/null
+++ b/res/layout/local.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/main.xml b/res/layout/main.xml
new file mode 100644
index 0000000..1fc54d2
--- /dev/null
+++ b/res/layout/main.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/ongoing_list_item.xml b/res/layout/ongoing_list_item.xml
new file mode 100644
index 0000000..f71e285
--- /dev/null
+++ b/res/layout/ongoing_list_item.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/menu/main.xml b/res/menu/main.xml
new file mode 100644
index 0000000..cf1a1e8
--- /dev/null
+++ b/res/menu/main.xml
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..6e75444
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,447 @@
+
+ FonBot
+ Allows an application to send notifications through FonBot
+ Initial setup:\n
+
+
Enter your username and password in the preferences\n\n
+
+
+Sending commands:\n
+
+
via Jabber: Send commands to fonbot@ieval.ro from any Jabber/GTalk account\n
+
via Yahoo Messenger: Send commands to fonbotym\n
+
via SMS: Set a SMS Password in the preferences, then send SMSes with the SMS Password as the first line. The next lines will be processed as commands\n
+
via email: Send commands to fonbot@ieval.ro\n
+
+\nFonBot commands consist of a command name and zero or more arguments, separated by spaces. To include spaces in an argument, surround the argument with single or double quotes.\n\n
+Example command: sms 0755555555 \'This is a random text\'. This command would send a text message to 0755555555\n\n
+The help command can be used to get a list of commands and help for them. Examples:\n\n
+
+
help â shows a list of commands\n
+
help sms â shows help for the ls comand
+
+
+ User tapped \'%s\'
+ User navigated away from dialog
+ User canceled dialog
+ Admin disable requested
+ Admin enabled
+ Device password changed
+ Device login failed. Wrong password entered %s times
+ Device login succeeded
+ Logging inâ¦
+ Phone is now idle
+ "Phone is ringing. Incoming number: "
+ Phone is offhook
+ Location
+ Latitude
+ Longitude
+ Accuracy
+ Altitude
+ Bearing
+ Speed
+ at
+ Location provider %s disabled
+ Location provider %s enabled
+ Location provider %s is now available
+ Location provider %s is temporary unavailable
+ Location provider %s is out of service
+ Location provider %s is in an unknown state
+ No response returned from server
+ Connection error
+ SMS received from %1$s with text %2$s
+ Battery low
+ Battery okay
+ plugged in
+ unplugged
+ Headset (with a microphone)
+ Headset (without a microphone)
+ FonBot Help
+ FonBot is running
+ FonBot
+ Assistant
+ Callback
+ Car
+ Company main
+ Home fax
+ Work fax
+ Home
+ ISDN
+ Main
+ MMS
+ Mobile
+ Other
+ Other fax
+ Pager
+ Radio
+ TELEX
+ Textphone
+ Work
+ Work mobile
+ Work pager
+ Unknown (%d)
+ Ringingâ¦
+ Cannot grab camera
+ No longer ringing
+ No bluetooth adapter
+ Bluetooth: on
+ Bluetooth: off
+ Enabling bluetoothâ¦
+ Disabling bluetoothâ¦
+ "Incoming call from %s "
+ "Missed call from %s "
+ "Outgoing call to %s "
+ Duration: %1$d seconds starting at %2$s
+ No matching contacts found
+ Name: %1$s; Phone: %2$s; Type: %3$s
+ "Battery level: %f%%. "
+ "Not plugged in. "
+ "Plugged in (AC). "
+ "Plugged in (USB). "
+ "Plugged in (wireless). "
+ "Status: charging. "
+ "Status: discharging. "
+ "Status: full. "
+ "Status: not charging. "
+ Status: unknown.
+ "Temperature: %d. "
+ Voltage: %d.
+ Dialing %sâ¦
+ Preferences
+ Local commands
+ Help
+ Showing dialogâ¦
+ "Last known location: "
+ Listening for location updatesâ¦
+ Device locked
+ File \'%s\' not found
+ File sent
+ Cannot connect to host \'%1$s\' on port \'%2$d\'
+ I/O Error: %s
+ No longer listening for location updates
+ Error setting preview display
+ No help for this command
+ %s is not a directory
+ "Files in %s: "
+ No ringtone found
+ Ringer mode: normal
+ Ringer mode: vibrate
+ Ringer mode: silent
+ Unknown ringer mode
+ File deleted
+ Error while deleting file
+ Password cleared
+ Password set
+ Message was split into %d parts
+ TTS Engine not available
+ Speakingâ¦
+ Toast shown
+ Vibratingâ¦
+ URL opened
+ No activity found for this URL
+ Invalid URL
+ Wifi: on
+ Wifi: off
+ Enabling wifiâ¦
+ Disabling wifiâ¦
+ Polling serverâ¦
+ Polling stopped
+ Command disabled%s disabled
+ Command %s enabled
+ Polling every %d milliseconds
+ Incoming message from %1$s: \"%2$s\" sent at %3$s
+ Outgoing message to %1$s: \"%2$s\" sent at %3$s
+ Error writing to socket: %s
+ Cannot close socket: %s
+ Unknown host: %s
+ Photo sent
+ Sending photoâ¦
+ "Invalid length. Allowed values are: %s"
+ Could not parse argument. Allowed values are: %s
+ Exception while hanging up call %1$s: %2$s
+ Exception while answering call %1$s: %2$s
+ No such package
+ App launched
+ Exception while getting ITelephony %1$s: %2$s
+ Data: off
+ Data: on
+ Disabling dataâ¦
+ Enabling dataâ¦
+ Exception while determining data state
+ Enabling GPSâ¦
+ Disabling GPSâ¦
+ Enabling network locationâ¦
+ Disabling network locationâ¦
+ GPS: on
+ GPS: off
+ Network location: off
+ Network location: on
+
+ Usage: answer\n
+ Answers the phone, if it is ringing. Does nothing otherwise.\n
+ Example: answer
+
+
+ Usage: batt\n
+ Shows battery information\n
+ Example: batt
+
+
+ Usage: wipe type \"%s\"\n
+ If <type> is \"data\", wipes the phone, leaving the sdcard intact\n
+ If <type> is \"full\", wipes the phone and the sdcard\n
+ This command requires admin permissions\n
+ WARNING: THIS CANNOT BE UNDONE!\n
+ Example: wipe data
+
+
+ Usage: poll [ms]\n
+ With no arguments, polls the server once\n
+ With an argument, starts polling the server every <ms> milliseconds. If <ms> is 0, the polling is stopped\n
+ Example: poll 60000
+
+
+ Usage: contacts substring\n
+ Returns a list of contacts whose name or nickname contains <substring>\n
+ Example: contacts Jack
+
+
+ Usage: rm file\n
+ Removes the <file> file\n
+ Example: rm /mnt/sdcard/file
+
+
+ Usage: ls directory\n
+ Lists the contents of the <directory> directory\n
+ Example: ls /mnt/sdcard
+
+
+ Usage: sms phone_number message\n
+ Sends an sms with text <message> to <phone_number>.\n
+ Example: sms 0755555555 \"Test message\"
+
+
+ Usage: setpassword [password]\n
+ With no argument, clears the device password.\n
+ With an argument, sets the device password to <password>.\n
+ Example: setpassword verysecurepassword
+
+
+ Usage: ring on/off\n
+ Make phone start/stop ringing\n
+ Example: ring on
+
+
+ Usage: photo hostname port\n
+ Takes a photo and uploads it to <hostname>:<port>\n
+ Example: photo 1.1.1.1 8888
+
+
+ Usage: nolocation\n
+ Stops sending location updates.\n
+ Example: nolocation
+
+
+ Usage: ncfile filename hostname port\n
+ Uploads the <filename> file to <hostname>:<port>\n
+ Example: ncfile /mnt/sdcard/file 1.1.1.1 8888
+
+
+ Usage: lock\n
+ Locks the phone. Requires device admin.\n
+ Example: lock
+
+
+ Usage: flash on/off\n
+ Turns the flashlight on or off\n
+ Example: flash on
+
+
+ Usage: echo message â¦\n
+ Echoes <message>.\n
+ Example: echo Hello, world!
+
+
+ Usage: dial number\n
+ Dials <number>.\n
+ Example: dial 0755555555
+
+
+ Usage: wifi [on/off]\n
+ With no arguments, shows the wifi status\n
+ With an argument, turns the wifi on or off\n
+ Example: wifi on
+
+
+ Usage: view link\n
+ Opens the link <link> in an appropriate application\n
+ Example: view tel://0755555555
+
+
+ Usage: vibrate ms\n
+ Makes the phone vibrate for <ms> milliseconds\n
+ Example: vibrate 2500
+
+
+ Usage: toast text [length]\n
+ Shows a toast with the <text> message. <length> is the length of the toast (long or short). Default is short.\n
+ Example: toast \"Hello world!\" long
+
+
+ Usage: speak text â¦\n
+ Speaks <text>\n
+ Example: speak Hello, stranger!
+
+
+ Usage: smslog [count]\n
+ With no argument, shows the last 5 SMSes\n
+ With an argument, shows the last <count> SMSes\n
+ Example: smslog 10
+
+
+ Usage: play\n
+ Starts playing music\n
+ Example: play
+
+
+ Usage: pause\n
+ Stops playing music\n
+ Example: pause
+
+
+ Usage: next\n
+ Skips to the next track\n
+ Example: next
+
+
+ Usage: prev\n
+ Skips to the previous track\n
+ Example: prev
+
+
+ Usage: bluetooth [on/off]\n
+ With no arguments, prints the bluetooth status.\n
+ With an argument, turns bluetooth on or off.\n
+ Example: bluetooth on
+
+
+ Usage: calllog [count]\n
+ With no arguments, prints the last 5 calls.\n
+ With an argument, prints the last <count> calls\n
+ Example: calllog 10
+
+
+ Usage: dialog message [button] â¦\n
+ Shows a dialog box with the <message> text and the <buttonâ¦> buttons. Returns the button pressed\n
+ Example: dialog \"Hello stranger. Thanks for finding my phone, will you return it to me?\" Yes No
+
+
+ Usage: enable command\n
+ Enables a command, undoing the effects of a previous DISABLE command\n
+ This command can only be issued from the local command interface\n
+ Command list: %s\n
+ Example: disable toast
+
+
+ Usage: disable command\n" +
+ Disables a command. Once disabled, a command cannot be used until enabled with the ENABLE command\n
+ This command can only be issued from the local command interface\n
+ Command list: %s\n
+ Example: disable toast
+
+
+ Usage: help command\n
+ Prints help for <command>. Available commands are %s\n
+ Example: help batt
+
+
+ Usage: setnotification notification\n
+ Enables the <notification> notification.\n
+ Messages from this notification will be sent to this address.\n
+ Available notifications: %s\n
+ Example: setnotification sms
+
+
+ Usage: delnotification notification\n
+ Disables the <notification> notification.\n
+ Available notifications: %s\n
+ Example: delnotification sms
+
+
+ Usage: location provider [min_time [min_distance]]\n" +
+ Starts sending location updates. Location updates will be sent at most once each min_time (default: 500) milliseconds and only if the phone has moved at least min_distance meters (default: 0) from the last update\n
+ <provider> is the location provider, one of %s\n
+ Example: location network 0 0"
+
+
+ Usage: ringer mode\n
+ Sets the ringer mode. <mode> is one of: %s\n
+ Example: ringer vibrate
+
+
+ Usage: data [on/off]\n
+ With no arguments, shows the mobile data status\n
+ With an argument, turns the mobile data on or off\n
+ Example: data off
+
+
+ Usage: gps [on/off]\n
+ With no arguments, shows the GPS status\n
+ With an argument, turns the GPS on or off\n
+ Example: gps off
+
+
+ Usage: glocation [on/off]\n
+ With no arguments, shows the Google location service status\n
+ With an argument, turns the Google location service on or off\n
+ NOTE: turning the Google location service on remotely is not possible, since the user must agree to the service disclaimer.\n
+ Example: glocation off
+
+
+ Usage: hangup\n
+ Hangs the phone up.\n
+ Example: hangup
+
+
+ Usage: launch package\n
+ Launches the app defined by the <package> package\n
+ Example: launch ro.ieval.fonbot
+
+ Could not parse ms
+ Cannot parse provider. Allowed values are: %s
+ Cannot parse min_time
+ Cannot parse min_distance
+ Invalid ringer mode. Valid values are: %s
+ Cannot parse port
+ Notification enabled
+ MessageType should be one of: %s
+ Notification disabled
+ Security exception: %s
+ The second argument to wipe must be \"%s\"
+ WipeType should be one of: %s
+ Cannot parse count
+ No such command. Command list: %s
+ Cannot parse interval
+ Unknown command: \'%1$s\' (%2$s)
+ Error while processing command (%1$s: %2$s)
+ Rebootingâ¦
+
+ Usage: reboot\n
+ Reboots the phone.\n
+ Example: reboot
+
+
+ Usage: shutdown\n
+ Shuts the phone down.\n
+ Example: shutdown
+
+ Location tracking is active
+ The polling service is running
+ Cancel
+ Command sent
+ Could not parse id
+ Notification canceled
+ Notification shown
+ Notify help
+
\ No newline at end of file
diff --git a/res/xml/admin.xml b/res/xml/admin.xml
new file mode 100644
index 0000000..7b4883d
--- /dev/null
+++ b/res/xml/admin.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/xml/prefs.xml b/res/xml/prefs.xml
new file mode 100644
index 0000000..b289fc9
--- /dev/null
+++ b/res/xml/prefs.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/android/internal/telephony/ITelephony.aidl b/src/com/android/internal/telephony/ITelephony.aidl
new file mode 100644
index 0000000..706271c
--- /dev/null
+++ b/src/com/android/internal/telephony/ITelephony.aidl
@@ -0,0 +1,11 @@
+package com.android.internal.telephony;
+
+import android.os.Bundle;
+interface ITelephony {
+ boolean endCall();
+ void dial(String number);
+ void answerRingingCall();
+ boolean enableDataConnectivity();
+ boolean disableDataConnectivity();
+ int getDataState();
+}
\ No newline at end of file
diff --git a/src/org/eclipse/jdt/annotation/NonNull.java b/src/org/eclipse/jdt/annotation/NonNull.java
new file mode 100644
index 0000000..eaaae3d
--- /dev/null
+++ b/src/org/eclipse/jdt/annotation/NonNull.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Stephan Herrmann and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Herrmann - initial API and implementation
+ * IBM Corporation - bug fixes
+ *******************************************************************************/
+package org.eclipse.jdt.annotation;
+
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Qualifier for a type in a method signature or a local variable declaration:
+ * The entity (return value, parameter, local variable) whose type has this
+ * annotation can never have the value null at runtime.
+ *
+ * This has two consequences:
+ *
+ *
Dereferencing the entity is safe, i.e., no NullPointerException can occur at runtime.
+ *
An attempt to bind a null value to the entity is a compile time error.
+ *
+ * For the second case, diagnostics issued by the compiler should distinguish three situations:
+ *
+ *
Nullness of the value can be statically determined, the entity is definitely bound from either of:
+ *
the value null, or
+ *
an entity with a {@link Nullable @Nullable} type.
+ *
Nullness cannot definitely be determined, because different code branches yield different results.
+ *
Nullness cannot be determined, because other program elements are involved for which
+ * null annotations are lacking.
+ *
+ *
+ * @since 1.0
+ */
+@Documented
+@Retention(RetentionPolicy.CLASS)
+@Target({ METHOD, PARAMETER, LOCAL_VARIABLE })
+public @interface NonNull {
+ // marker annotation with no members
+}
diff --git a/src/org/eclipse/jdt/annotation/NonNullByDefault.java b/src/org/eclipse/jdt/annotation/NonNullByDefault.java
new file mode 100644
index 0000000..0ef1cac
--- /dev/null
+++ b/src/org/eclipse/jdt/annotation/NonNullByDefault.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Stephan Herrmann and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Herrmann - initial API and implementation
+ * IBM Corporation - bug fixes
+ *******************************************************************************/
+package org.eclipse.jdt.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation can be applied to a package, type, method or constructor in order to
+ * define that all contained entities for which a null annotation is otherwise lacking
+ * should be considered as {@link NonNull @NonNull}.
+ *
+ *
Canceling a default
+ *
By using a @NonNullByDefault annotation with the argument false,
+ * a default from any enclosing scope can be canceled for the element being annotated.
+ *
Nested defaults
+ *
If a @NonNullByDefault
+ * annotation is used within the scope of another @NonNullByDefault
+ * annotation or a project-wide default setting, the innermost annotation defines the
+ * default applicable at any given position (depending on the parameter {@link #value()}).
+ *
+ * Note that for applying an annotation to a package, a file by the name
+ * package-info.java is used.
+ *
+ * @since 1.0
+ */
+@Documented
+@Retention(RetentionPolicy.CLASS)
+@Target({ PACKAGE, TYPE, METHOD, CONSTRUCTOR })
+public @interface NonNullByDefault {
+ /**
+ * When parameterized with false, the annotation specifies that the current element should not apply
+ * any default to un-annotated types.
+ */
+ boolean value() default true;
+}
diff --git a/src/org/eclipse/jdt/annotation/Nullable.java b/src/org/eclipse/jdt/annotation/Nullable.java
new file mode 100644
index 0000000..e1a6a1b
--- /dev/null
+++ b/src/org/eclipse/jdt/annotation/Nullable.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Stephan Herrmann and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Herrmann - initial API and implementation
+ * IBM Corporation - bug fixes
+ *******************************************************************************/
+package org.eclipse.jdt.annotation;
+
+import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Qualifier for a type in a method signature or a local variable declaration:
+ * The entity (return value, parameter, local variable) whose type has this
+ * annotation is allowed to have the value null at runtime.
+ *
+ * This has two consequences:
+ *
+ *
Binding a null value to the entity is legal.
+ *
Dereferencing the entity is unsafe, i.e., a NullPointerException can occur at runtime.
+ *
+ *
+ * @since 1.0
+ */
+@Documented
+@Retention(RetentionPolicy.CLASS)
+@Target({ METHOD, PARAMETER, LOCAL_VARIABLE })
+public @interface Nullable {
+ // marker annotation with no members
+}
\ No newline at end of file
diff --git a/src/org/eclipse/jdt/annotation/package-info.java b/src/org/eclipse/jdt/annotation/package-info.java
new file mode 100644
index 0000000..78fe2f6
--- /dev/null
+++ b/src/org/eclipse/jdt/annotation/package-info.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Stephan Herrmann and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Stephan Herrmann - initial API and implementation
+ * IBM Corporation - bug fixes
+ *******************************************************************************/
+
+/**
+ * This package contains annotations that can trigger special behavior
+ * when annotated types are compiled by the Eclipse Compiler for Java.
+ *
+ * Currently, the package contains annotations that specify nullness contracts
+ * for annotated elements.
+ *