mirror of
https://github.com/fergalmoran/chrometophone.git
synced 2025-12-22 09:41:51 +00:00
Refactored application and server-side to use GCM instead of C2DM; removed and or deprecated C2DM code; removed unused code
This commit is contained in:
@@ -5,5 +5,6 @@
|
||||
<classpathentry kind="src" path="c2dm"/>
|
||||
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
|
||||
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
|
||||
<classpathentry kind="lib" path="libs/gcm.jar"/>
|
||||
<classpathentry kind="output" path="bin/classes"/>
|
||||
</classpath>
|
||||
|
||||
327
android/.settings/org.eclipse.jdt.core.prefs
Normal file
327
android/.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,327 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field.count_dependent=1585|-1|1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable.count_dependent=1585|-1|1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method.count_dependent=1585|-1|1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package.count_dependent=1585|-1|1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=1040
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter.count_dependent=1040|-1|1040
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type.count_dependent=1585|-1|1585
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants.count_dependent=0|-1|0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_field_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_for_statement=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_local_variable_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_new_anonymous_class=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration.count_dependent=16|-1|16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=80
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.comment_new_line_at_start_of_html_paragraph=true
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.force_if_else_statement_brace=false
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comment_prefix=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=80
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_comment_inline_tags=false
|
||||
org.eclipse.jdt.core.formatter.wrap_non_simple_local_variable_annotation=true
|
||||
org.eclipse.jdt.core.formatter.wrap_non_simple_member_annotation=true
|
||||
org.eclipse.jdt.core.formatter.wrap_non_simple_package_annotation=true
|
||||
org.eclipse.jdt.core.formatter.wrap_non_simple_parameter_annotation=false
|
||||
org.eclipse.jdt.core.formatter.wrap_non_simple_type_annotation=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
org.eclipse.jdt.core.formatter.wrap_prefer_two_fragments=false
|
||||
3
android/.settings/org.eclipse.jdt.ui.prefs
Normal file
3
android/.settings/org.eclipse.jdt.ui.prefs
Normal file
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_my-Android
|
||||
formatter_settings_version=12
|
||||
@@ -50,25 +50,30 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
-->
|
||||
<!-- In order to use the c2dm library, an
|
||||
application must declare a class with the name C2DMReceiver, in its
|
||||
own package, extending com.google.android.c2dm.C2DMBaseReceiver
|
||||
|
||||
It must also include this section in the manifest, replacing
|
||||
"com.google.android.apps.chrometophone" with its package name. -->
|
||||
<service android:name=".C2DMReceiver" />
|
||||
<!--
|
||||
Application-specific subclass of GCMBaseIntentService that will
|
||||
handle received messages.
|
||||
|
||||
<!-- Only google service can send data messages for the app. If permission is not set -
|
||||
any other app can generate it -->
|
||||
<receiver android:name="com.google.android.c2dm.C2DMBroadcastReceiver"
|
||||
By default, it must be named .GCMIntentService, unless the
|
||||
application uses a custom BroadcastReceiver that redefines its name.
|
||||
-->
|
||||
<service android:name=".GCMIntentService" />
|
||||
|
||||
<!--
|
||||
BroadcastReceiver that will receive intents from GCM
|
||||
services and handle them to the custom IntentService.
|
||||
|
||||
The com.google.android.c2dm.permission.SEND permission is necessary
|
||||
so only GCM services can send data messages for the app.
|
||||
-->
|
||||
<receiver
|
||||
android:name="com.google.android.gcm.GCMBroadcastReceiver"
|
||||
android:permission="com.google.android.c2dm.permission.SEND" >
|
||||
<!-- Receive the actual message -->
|
||||
<intent-filter>
|
||||
<!-- Receives the actual messages. -->
|
||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
||||
<category android:name="com.google.android.apps.chrometophone" />
|
||||
</intent-filter>
|
||||
<!-- Receive the registration id -->
|
||||
<intent-filter>
|
||||
<!-- Receives the registration id. -->
|
||||
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
|
||||
<category android:name="com.google.android.apps.chrometophone" />
|
||||
</intent-filter>
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.c2dm;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.IntentService;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.PowerManager;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Base class for C2D message receiver. Includes constants for the
|
||||
* strings used in the protocol.
|
||||
*/
|
||||
public abstract class C2DMBaseReceiver extends IntentService {
|
||||
private static final String C2DM_RETRY = "com.google.android.c2dm.intent.RETRY";
|
||||
|
||||
public static final String REGISTRATION_CALLBACK_INTENT = "com.google.android.c2dm.intent.REGISTRATION";
|
||||
private static final String C2DM_INTENT = "com.google.android.c2dm.intent.RECEIVE";
|
||||
|
||||
// Logging tag
|
||||
private static final String TAG = "C2DM";
|
||||
|
||||
// Extras in the registration callback intents.
|
||||
public static final String EXTRA_UNREGISTERED = "unregistered";
|
||||
|
||||
public static final String EXTRA_ERROR = "error";
|
||||
|
||||
public static final String EXTRA_REGISTRATION_ID = "registration_id";
|
||||
|
||||
public static final String ERR_SERVICE_NOT_AVAILABLE = "SERVICE_NOT_AVAILABLE";
|
||||
public static final String ERR_ACCOUNT_MISSING = "ACCOUNT_MISSING";
|
||||
public static final String ERR_AUTHENTICATION_FAILED = "AUTHENTICATION_FAILED";
|
||||
public static final String ERR_TOO_MANY_REGISTRATIONS = "TOO_MANY_REGISTRATIONS";
|
||||
public static final String ERR_INVALID_PARAMETERS = "INVALID_PARAMETERS";
|
||||
public static final String ERR_INVALID_SENDER = "INVALID_SENDER";
|
||||
public static final String ERR_PHONE_REGISTRATION_ERROR = "PHONE_REGISTRATION_ERROR";
|
||||
|
||||
// wakelock
|
||||
private static final String WAKELOCK_KEY = "C2DM_LIB";
|
||||
|
||||
private static PowerManager.WakeLock mWakeLock;
|
||||
private final String senderId;
|
||||
|
||||
/**
|
||||
* The C2DMReceiver class must create a no-arg constructor and pass the
|
||||
* sender id to be used for registration.
|
||||
*/
|
||||
public C2DMBaseReceiver(String senderId) {
|
||||
// senderId is used as base name for threads, etc.
|
||||
super(senderId);
|
||||
this.senderId = senderId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a cloud message has been received.
|
||||
*/
|
||||
protected abstract void onMessage(Context context, Intent intent);
|
||||
|
||||
/**
|
||||
* Called on registration error. Override to provide better
|
||||
* error messages.
|
||||
*
|
||||
* This is called in the context of a Service - no dialog or UI.
|
||||
*/
|
||||
public abstract void onError(Context context, String errorId);
|
||||
|
||||
/**
|
||||
* Called when a registration token has been received.
|
||||
*/
|
||||
public void onRegistered(Context context, String registrationId) throws IOException {
|
||||
// registrationId will also be saved
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the device has been unregistered.
|
||||
*/
|
||||
public void onUnregistered(Context context) {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void onHandleIntent(Intent intent) {
|
||||
try {
|
||||
Context context = getApplicationContext();
|
||||
if (intent.getAction().equals(REGISTRATION_CALLBACK_INTENT)) {
|
||||
handleRegistration(context, intent);
|
||||
} else if (intent.getAction().equals(C2DM_INTENT)) {
|
||||
onMessage(context, intent);
|
||||
} else if (intent.getAction().equals(C2DM_RETRY)) {
|
||||
C2DMessaging.register(context, senderId);
|
||||
}
|
||||
} 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 the onMessage() needs to spawn a thread or do something else,
|
||||
// it should use it's own lock.
|
||||
mWakeLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
if (mWakeLock == null) {
|
||||
// This is called from BroadcastReceiver, there is no init.
|
||||
PowerManager pm =
|
||||
(PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||
WAKELOCK_KEY);
|
||||
}
|
||||
mWakeLock.acquire();
|
||||
|
||||
// Use a naming convention, similar with how permissions and intents are
|
||||
// used. Alternatives are introspection or an ugly use of statics.
|
||||
String receiver = context.getPackageName() + ".C2DMReceiver";
|
||||
intent.setClassName(context, receiver);
|
||||
|
||||
context.startService(intent);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void handleRegistration(final Context context, Intent intent) {
|
||||
final String registrationId = intent.getStringExtra(EXTRA_REGISTRATION_ID);
|
||||
String error = intent.getStringExtra(EXTRA_ERROR);
|
||||
String removed = intent.getStringExtra(EXTRA_UNREGISTERED);
|
||||
|
||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||
Log.d(TAG, "dmControl: registrationId = " + registrationId +
|
||||
", error = " + error + ", removed = " + removed);
|
||||
}
|
||||
|
||||
if (removed != null) {
|
||||
// Remember we are unregistered
|
||||
C2DMessaging.clearRegistrationId(context);
|
||||
onUnregistered(context);
|
||||
return;
|
||||
} else if (error != null) {
|
||||
// we are not registered, can try again
|
||||
C2DMessaging.clearRegistrationId(context);
|
||||
// Registration failed
|
||||
Log.e(TAG, "Registration error " + error);
|
||||
onError(context, error);
|
||||
if ("SERVICE_NOT_AVAILABLE".equals(error)) {
|
||||
long backoffTimeMs = C2DMessaging.getBackoff(context);
|
||||
|
||||
Log.d(TAG, "Scheduling registration retry, backoff = " + backoffTimeMs);
|
||||
Intent retryIntent = new Intent(C2DM_RETRY);
|
||||
PendingIntent retryPIntent = PendingIntent.getBroadcast(context,
|
||||
0 /*requestCode*/, retryIntent, 0 /*flags*/);
|
||||
|
||||
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
am.set(AlarmManager.ELAPSED_REALTIME,
|
||||
backoffTimeMs, retryPIntent);
|
||||
|
||||
// Next retry should wait longer.
|
||||
backoffTimeMs *= 2;
|
||||
C2DMessaging.setBackoff(context, backoffTimeMs);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
onRegistered(context, registrationId);
|
||||
C2DMessaging.setRegistrationId(context, registrationId);
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, "Registration error " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
*/
|
||||
package com.google.android.c2dm;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
/**
|
||||
* Helper class to handle BroadcastReciver behavior.
|
||||
* - can only run for a limited amount of time - it must start a real service
|
||||
* for longer activity
|
||||
* - must get the power lock, must make sure it's released when all done.
|
||||
*
|
||||
*/
|
||||
public class C2DMBroadcastReceiver extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public final void onReceive(Context context, Intent intent) {
|
||||
// To keep things in one place.
|
||||
C2DMBaseReceiver.runIntentInService(context, intent);
|
||||
setResult(Activity.RESULT_OK, null /* data */, null /* extra */);
|
||||
}
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.c2dm;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
|
||||
/**
|
||||
* Utilities for device registration.
|
||||
*
|
||||
* Will keep track of the registration token in a private preference.
|
||||
*/
|
||||
public class C2DMessaging {
|
||||
public static final String EXTRA_SENDER = "sender";
|
||||
public static final String EXTRA_APPLICATION_PENDING_INTENT = "app";
|
||||
public static final String REQUEST_UNREGISTRATION_INTENT = "com.google.android.c2dm.intent.UNREGISTER";
|
||||
public static final String REQUEST_REGISTRATION_INTENT = "com.google.android.c2dm.intent.REGISTER";
|
||||
public static final String LAST_REGISTRATION_CHANGE = "last_registration_change";
|
||||
public static final String BACKOFF = "backoff";
|
||||
public static final String GSF_PACKAGE = "com.google.android.gsf";
|
||||
|
||||
|
||||
// package
|
||||
static final String PREFERENCE = "com.google.android.c2dm";
|
||||
|
||||
private static final long DEFAULT_BACKOFF = 30000;
|
||||
|
||||
/**
|
||||
* Initiate c2d messaging registration for the current application
|
||||
*/
|
||||
public static void register(Context context,
|
||||
String senderId) {
|
||||
Intent registrationIntent = new Intent(REQUEST_REGISTRATION_INTENT);
|
||||
registrationIntent.setPackage(GSF_PACKAGE);
|
||||
registrationIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT,
|
||||
PendingIntent.getBroadcast(context, 0, new Intent(), 0));
|
||||
registrationIntent.putExtra(EXTRA_SENDER, senderId);
|
||||
context.startService(registrationIntent);
|
||||
// TODO: if intent not found, notification on need to have GSF
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the application. New messages will be blocked by server.
|
||||
*/
|
||||
public static void unregister(Context context) {
|
||||
Intent regIntent = new Intent(REQUEST_UNREGISTRATION_INTENT);
|
||||
regIntent.setPackage(GSF_PACKAGE);
|
||||
regIntent.putExtra(EXTRA_APPLICATION_PENDING_INTENT, PendingIntent.getBroadcast(context,
|
||||
0, new Intent(), 0));
|
||||
context.startService(regIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current registration id.
|
||||
*
|
||||
* 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 = context.getSharedPreferences(
|
||||
PREFERENCE,
|
||||
Context.MODE_PRIVATE);
|
||||
String registrationId = prefs.getString("dm_registration", "");
|
||||
return registrationId;
|
||||
}
|
||||
|
||||
public static long getLastRegistrationChange(Context context) {
|
||||
final SharedPreferences prefs = context.getSharedPreferences(
|
||||
PREFERENCE,
|
||||
Context.MODE_PRIVATE);
|
||||
return prefs.getLong(LAST_REGISTRATION_CHANGE, 0);
|
||||
}
|
||||
|
||||
static long getBackoff(Context context) {
|
||||
final SharedPreferences prefs = context.getSharedPreferences(
|
||||
PREFERENCE,
|
||||
Context.MODE_PRIVATE);
|
||||
return prefs.getLong(BACKOFF, DEFAULT_BACKOFF);
|
||||
}
|
||||
|
||||
static void setBackoff(Context context, long backoff) {
|
||||
final SharedPreferences prefs = context.getSharedPreferences(
|
||||
PREFERENCE,
|
||||
Context.MODE_PRIVATE);
|
||||
Editor editor = prefs.edit();
|
||||
editor.putLong(BACKOFF, backoff);
|
||||
editor.commit();
|
||||
|
||||
}
|
||||
|
||||
// package
|
||||
static void clearRegistrationId(Context context) {
|
||||
final SharedPreferences prefs = context.getSharedPreferences(
|
||||
PREFERENCE,
|
||||
Context.MODE_PRIVATE);
|
||||
Editor editor = prefs.edit();
|
||||
editor.putString("dm_registration", "");
|
||||
editor.putLong(LAST_REGISTRATION_CHANGE, System.currentTimeMillis());
|
||||
editor.commit();
|
||||
|
||||
}
|
||||
|
||||
// package
|
||||
static void setRegistrationId(Context context, String registrationId) {
|
||||
final SharedPreferences prefs = context.getSharedPreferences(
|
||||
PREFERENCE,
|
||||
Context.MODE_PRIVATE);
|
||||
Editor editor = prefs.edit();
|
||||
editor.putString("dm_registration", registrationId);
|
||||
editor.commit();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,8 @@ import android.content.res.Configuration;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gcm.GCMRegistrar;
|
||||
|
||||
/**
|
||||
* Register/unregister with the Chrome to Phone App Engine server.
|
||||
*/
|
||||
@@ -40,7 +42,7 @@ public class DeviceRegistrar {
|
||||
public static final int ERROR_STATUS = 4;
|
||||
|
||||
private static final String TAG = "DeviceRegistrar";
|
||||
static final String SENDER_ID = "stp.chrome@gmail.com";
|
||||
static final String SENDER_ID = "206147423037";
|
||||
|
||||
private static final String REGISTER_PATH = "/register";
|
||||
private static final String UNREGISTER_PATH = "/unregister";
|
||||
@@ -52,12 +54,9 @@ public class DeviceRegistrar {
|
||||
public void run() {
|
||||
Intent updateUIIntent = new Intent("com.google.ctp.UPDATE_UI");
|
||||
try {
|
||||
HttpResponse res = makeRequest(context, deviceRegistrationID, REGISTER_PATH);
|
||||
HttpResponse res = makeRequest(context, deviceRegistrationID, REGISTER_PATH, "gcm");
|
||||
if (res.getStatusLine().getStatusCode() == 200) {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putString("deviceRegistrationID", deviceRegistrationID);
|
||||
editor.commit();
|
||||
GCMRegistrar.setRegisteredOnServer(context, true);
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, REGISTERED_STATUS);
|
||||
} else if (res.getStatusLine().getStatusCode() == 400) {
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, AUTH_ERROR_STATUS);
|
||||
@@ -82,24 +81,32 @@ public class DeviceRegistrar {
|
||||
}
|
||||
|
||||
public static void unregisterWithServer(final Context context,
|
||||
final String deviceRegistrationID) {
|
||||
final String deviceRegistrationID, final String deviceType) {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent updateUIIntent = new Intent("com.google.ctp.UPDATE_UI");
|
||||
try {
|
||||
HttpResponse res = makeRequest(context, deviceRegistrationID, UNREGISTER_PATH);
|
||||
HttpResponse res = makeRequest(context, deviceRegistrationID, UNREGISTER_PATH, deviceType);
|
||||
if (res.getStatusLine().getStatusCode() != 200) {
|
||||
Log.w(TAG, "Unregistration error " +
|
||||
String.valueOf(res.getStatusLine().getStatusCode()));
|
||||
} else {
|
||||
GCMRegistrar.setRegisteredOnServer(context, false);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Unregistration error " + e.getMessage());
|
||||
} finally {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.remove("deviceRegistrationID");
|
||||
if (deviceType.equals("gcm")) {
|
||||
editor.remove("accountName");
|
||||
} else {
|
||||
// this is an update from C2DM to GCM - keep the account,
|
||||
// but remove the old regId (the new one will be stored
|
||||
// on GCM's library preferences)
|
||||
editor.remove("deviceRegistrationID");
|
||||
}
|
||||
editor.commit();
|
||||
updateUIIntent.putExtra(STATUS_EXTRA, UNREGISTERED_STATUS);
|
||||
}
|
||||
@@ -111,9 +118,8 @@ public class DeviceRegistrar {
|
||||
}
|
||||
|
||||
private static HttpResponse makeRequest(Context context, String deviceRegistrationID,
|
||||
String urlPath) throws Exception {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
String accountName = settings.getString("accountName", null);
|
||||
String urlPath, String deviceType) throws Exception {
|
||||
String accountName = getAccountName(context);
|
||||
|
||||
List<NameValuePair> params = new ArrayList<NameValuePair>();
|
||||
params.add(new BasicNameValuePair("devregid", deviceRegistrationID));
|
||||
@@ -126,10 +132,18 @@ public class DeviceRegistrar {
|
||||
// TODO: Allow device name to be configured
|
||||
params.add(new BasicNameValuePair("deviceName", isTablet(context) ? "Tablet" : "Phone"));
|
||||
|
||||
params.add(new BasicNameValuePair("deviceType", deviceType));
|
||||
|
||||
AppEngineClient client = new AppEngineClient(context, accountName);
|
||||
return client.makeRequest(urlPath, params);
|
||||
}
|
||||
|
||||
static String getAccountName(Context context) {
|
||||
SharedPreferences settings = Prefs.get(context);
|
||||
String accountName = settings.getString("accountName", null);
|
||||
return accountName;
|
||||
}
|
||||
|
||||
static boolean isTablet (Context context) {
|
||||
// TODO: This hacky stuff goes away when we allow users to target devices
|
||||
int xlargeBit = 4; // Configuration.SCREENLAYOUT_SIZE_XLARGE; // upgrade to HC SDK to get this
|
||||
|
||||
@@ -26,10 +26,11 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.google.android.c2dm.C2DMBaseReceiver;
|
||||
import com.google.android.gcm.GCMBaseIntentService;
|
||||
|
||||
public class C2DMReceiver extends C2DMBaseReceiver {
|
||||
public C2DMReceiver() {
|
||||
public class GCMIntentService extends GCMBaseIntentService {
|
||||
|
||||
public GCMIntentService() {
|
||||
super(DeviceRegistrar.SENDER_ID);
|
||||
}
|
||||
|
||||
@@ -39,10 +40,8 @@ public class C2DMReceiver extends C2DMBaseReceiver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnregistered(Context context) {
|
||||
SharedPreferences prefs = Prefs.get(context);
|
||||
String deviceRegistrationID = prefs.getString("deviceRegistrationID", null);
|
||||
DeviceRegistrar.unregisterWithServer(context, deviceRegistrationID);
|
||||
public void onUnregistered(Context context, String registration) {
|
||||
DeviceRegistrar.unregisterWithServer(context, registration, "gcm");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,4 +97,5 @@ public class C2DMReceiver extends C2DMBaseReceiver {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.google.android.apps.chrometophone;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
@@ -21,8 +19,12 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseExpandableListAdapter;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ExpandableListView.OnChildClickListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.gcm.GCMRegistrar;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* Activity that shows the history of links received.
|
||||
@@ -42,10 +44,32 @@ public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Run the setup first if necessary
|
||||
SharedPreferences prefs = Prefs.get(this);
|
||||
if (prefs.getString("deviceRegistrationID", null) == null) {
|
||||
String c2dmRegId = prefs.getString("deviceRegistrationID", null);
|
||||
if (c2dmRegId != null) {
|
||||
// this is an update from the version that uses C2DM: must
|
||||
// unregister and register again using GCM
|
||||
DeviceRegistrar.unregisterWithServer(this, c2dmRegId, "ac2dm");
|
||||
GCMRegistrar.register(this, DeviceRegistrar.SENDER_ID);
|
||||
} else {
|
||||
// Run the setup first if necessary
|
||||
String gcmRegId = GCMRegistrar.getRegistrationId(this);
|
||||
if (gcmRegId.equals("")) {
|
||||
String accountName = DeviceRegistrar.getAccountName(this);
|
||||
if (accountName == null) {
|
||||
// first time app is run
|
||||
startActivity(new Intent(this, SetupActivity.class));
|
||||
} else {
|
||||
// app was converted from C2DM to GCM, but process didn't
|
||||
// complete
|
||||
GCMRegistrar.register(this, DeviceRegistrar.SENDER_ID);
|
||||
}
|
||||
} else {
|
||||
// check if the regId must be sent to the server
|
||||
if (!GCMRegistrar.isRegisteredOnServer(this)) {
|
||||
DeviceRegistrar.registerWithServer(this, gcmRegId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setContentView(R.layout.history);
|
||||
@@ -102,6 +126,7 @@ public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
|
||||
int childPosition, long id) {
|
||||
mSelectedLink = mListAdapter.getLinkAtPosition(groupPosition, childPosition);
|
||||
@@ -200,14 +225,17 @@ public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getChild(int groupPosition, int childPosition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getChildId(int groupPosition, int childPosition) {
|
||||
return moveCursorPosition(groupPosition, childPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
|
||||
View convertView, ViewGroup parent) {
|
||||
HistoryItemView itemView;
|
||||
@@ -231,22 +259,27 @@ public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
return itemView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildrenCount(int groupPosition) {
|
||||
return mChildCounts[groupPosition];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGroup(int groupPosition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupCount() {
|
||||
return DateBinSorter.NUM_BINS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getGroupId(int groupPosition) {
|
||||
return groupPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
|
||||
ViewGroup parent) {
|
||||
TextView item;
|
||||
@@ -261,10 +294,12 @@ public class HistoryActivity extends Activity implements OnChildClickListener {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.google.android.apps.chrometophone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Activity;
|
||||
@@ -39,10 +37,12 @@ import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.RadioGroup.OnCheckedChangeListener;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.c2dm.C2DMessaging;
|
||||
import com.google.android.gcm.GCMRegistrar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Setup activity - takes user through the setup.
|
||||
@@ -76,11 +76,11 @@ public class SetupActivity extends Activity {
|
||||
super.onResume();
|
||||
if (mPendingAuth) {
|
||||
mPendingAuth = false;
|
||||
String regId = C2DMessaging.getRegistrationId(this);
|
||||
if (regId != null && !"".equals(regId)) {
|
||||
String regId = GCMRegistrar.getRegistrationId(this);
|
||||
if (!regId.equals("")) {
|
||||
DeviceRegistrar.registerWithServer(this, regId);
|
||||
} else {
|
||||
C2DMessaging.register(this, DeviceRegistrar.SENDER_ID);
|
||||
GCMRegistrar.register(this, DeviceRegistrar.SENDER_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,6 +155,7 @@ public class SetupActivity extends Activity {
|
||||
|
||||
Button exitButton = (Button) findViewById(R.id.exit);
|
||||
exitButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
@@ -162,6 +163,7 @@ public class SetupActivity extends Activity {
|
||||
|
||||
Button nextButton = (Button) findViewById(R.id.next);
|
||||
nextButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setScreenContent(R.layout.select_account);
|
||||
}
|
||||
@@ -171,6 +173,7 @@ public class SetupActivity extends Activity {
|
||||
private void setSelectAccountScreenContent() {
|
||||
final Button backButton = (Button) findViewById(R.id.back);
|
||||
backButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setScreenContent(R.layout.intro);
|
||||
}
|
||||
@@ -178,6 +181,7 @@ public class SetupActivity extends Activity {
|
||||
|
||||
final Button nextButton = (Button) findViewById(R.id.next);
|
||||
nextButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ListView listView = (ListView) findViewById(R.id.select_account);
|
||||
mAccountSelectedPosition = listView.getCheckedItemPosition();
|
||||
@@ -208,6 +212,7 @@ public class SetupActivity extends Activity {
|
||||
private void setSelectLaunchModeScreenContent() {
|
||||
Button backButton = (Button) findViewById(R.id.back);
|
||||
backButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setScreenContent(R.layout.select_account);
|
||||
}
|
||||
@@ -215,6 +220,7 @@ public class SetupActivity extends Activity {
|
||||
|
||||
Button nextButton = (Button) findViewById(R.id.next);
|
||||
nextButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
storeLaunchModePreference();
|
||||
setScreenContent(R.layout.setup_complete);
|
||||
@@ -230,6 +236,7 @@ public class SetupActivity extends Activity {
|
||||
|
||||
Button backButton = (Button) findViewById(R.id.back);
|
||||
backButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setScreenContent(R.layout.select_launch_mode);
|
||||
}
|
||||
@@ -238,6 +245,7 @@ public class SetupActivity extends Activity {
|
||||
final Context context = this;
|
||||
Button finishButton = (Button) findViewById(R.id.finish);
|
||||
finishButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SharedPreferences prefs = Prefs.get(context);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
@@ -258,6 +266,7 @@ public class SetupActivity extends Activity {
|
||||
|
||||
RadioGroup launchMode = (RadioGroup) findViewById(R.id.launch_mode_radio);
|
||||
launchMode.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||
storeLaunchModePreference();
|
||||
} });
|
||||
@@ -265,6 +274,7 @@ public class SetupActivity extends Activity {
|
||||
|
||||
Button disconnectButton = (Button) findViewById(R.id.disconnect);
|
||||
disconnectButton.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
unregister();
|
||||
}
|
||||
@@ -302,7 +312,7 @@ public class SetupActivity extends Activity {
|
||||
editor.putString("accountName", account);
|
||||
editor.commit();
|
||||
|
||||
C2DMessaging.register(this, DeviceRegistrar.SENDER_ID);
|
||||
GCMRegistrar.register(this, DeviceRegistrar.SENDER_ID);
|
||||
}
|
||||
|
||||
private void unregister() {
|
||||
@@ -314,7 +324,7 @@ public class SetupActivity extends Activity {
|
||||
Button disconnectButton = (Button) findViewById(R.id.disconnect);
|
||||
disconnectButton.setEnabled(false);
|
||||
|
||||
C2DMessaging.unregister(this);
|
||||
GCMRegistrar.unregister(this);
|
||||
}
|
||||
|
||||
private String[] getGoogleAccounts() {
|
||||
|
||||
@@ -4,5 +4,7 @@
|
||||
<classpathentry kind="src" path="c2dm"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="com.google.appengine.eclipse.core.GAE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="war/WEB-INF/lib/gcm-server.jar"/>
|
||||
<classpathentry kind="lib" path="war/WEB-INF/lib/json_simple-1.1.jar"/>
|
||||
<classpathentry kind="output" path="war/WEB-INF/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -35,11 +35,16 @@ import javax.jdo.PersistenceManagerFactory;
|
||||
*/
|
||||
public class C2DMConfigLoader {
|
||||
private static final String TOKEN_FILE = "/dataMessagingToken.txt";
|
||||
private static final String API_KEY_FILE = "/dataMessagingApiKey.txt";
|
||||
private final PersistenceManagerFactory PMF;
|
||||
private static final Logger log = Logger.getLogger(C2DMConfigLoader.class.getName());
|
||||
|
||||
private static final int C2DM_TOKEN = 1;
|
||||
private static final int GCM_API_KEY = 2;
|
||||
|
||||
String currentToken;
|
||||
String c2dmUrl;
|
||||
String currentApiKey;
|
||||
|
||||
C2DMConfigLoader(PersistenceManagerFactory pmf) {
|
||||
this.PMF = pmf;
|
||||
@@ -56,7 +61,7 @@ public class C2DMConfigLoader {
|
||||
currentToken = token;
|
||||
PersistenceManager pm = PMF.getPersistenceManager();
|
||||
try {
|
||||
getDataMessagingConfig(pm).setAuthToken(token);
|
||||
getDataMessagingConfig(pm, TOKEN_FILE, C2DM_TOKEN).setAuthToken(token);
|
||||
} finally {
|
||||
pm.close();
|
||||
}
|
||||
@@ -76,30 +81,37 @@ public class C2DMConfigLoader {
|
||||
*/
|
||||
public String getToken() {
|
||||
if (currentToken == null) {
|
||||
currentToken = getDataMessagingConfig().getAuthToken();
|
||||
currentToken = getDataMessagingConfig(TOKEN_FILE, C2DM_TOKEN).getAuthToken();
|
||||
}
|
||||
return currentToken;
|
||||
}
|
||||
|
||||
public String getGcmApiKey() {
|
||||
if (currentApiKey == null) {
|
||||
currentApiKey = getDataMessagingConfig(API_KEY_FILE, GCM_API_KEY).getAuthToken();
|
||||
}
|
||||
return currentApiKey;
|
||||
}
|
||||
|
||||
public String getC2DMUrl() {
|
||||
if (c2dmUrl == null) {
|
||||
c2dmUrl = getDataMessagingConfig().getC2DMUrl();
|
||||
c2dmUrl = getDataMessagingConfig(TOKEN_FILE, C2DM_TOKEN).getC2DMUrl();
|
||||
}
|
||||
return c2dmUrl;
|
||||
}
|
||||
|
||||
public C2DMConfig getDataMessagingConfig() {
|
||||
private C2DMConfig getDataMessagingConfig(String file, int index) {
|
||||
PersistenceManager pm = PMF.getPersistenceManager();
|
||||
try {
|
||||
C2DMConfig dynamicConfig = getDataMessagingConfig(pm);
|
||||
C2DMConfig dynamicConfig = getDataMessagingConfig(pm, file, index);
|
||||
return dynamicConfig;
|
||||
} finally {
|
||||
pm.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static C2DMConfig getDataMessagingConfig(PersistenceManager pm) {
|
||||
Key key = KeyFactory.createKey(C2DMConfig.class.getSimpleName(), 1);
|
||||
private C2DMConfig getDataMessagingConfig(PersistenceManager pm, String file, int index) {
|
||||
Key key = KeyFactory.createKey(C2DMConfig.class.getSimpleName(), index);
|
||||
C2DMConfig dmConfig = null;
|
||||
try {
|
||||
dmConfig = pm.getObjectById(C2DMConfig.class, key);
|
||||
@@ -109,7 +121,7 @@ public class C2DMConfigLoader {
|
||||
dmConfig.setKey(key);
|
||||
// Must be in classpath, before sending. Do not checkin !
|
||||
try {
|
||||
InputStream is = C2DMConfigLoader.class.getClassLoader().getResourceAsStream(TOKEN_FILE);
|
||||
InputStream is = C2DMConfigLoader.class.getClassLoader().getResourceAsStream(file);
|
||||
String token;
|
||||
if (is != null) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010 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.c2dm.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* A task that sends tickles to device clients. This will be invoked by
|
||||
* AppEngine cron to retry failed requests.
|
||||
*
|
||||
* You must configure war/WEB-INF/queue.xml and the web.xml entries.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class C2DMRetryServlet extends HttpServlet {
|
||||
|
||||
private static final Logger log = Logger.getLogger(C2DMRetryServlet.class.getName());
|
||||
|
||||
public static final String URI = "/tasks/c2dm";
|
||||
|
||||
public static final String RETRY_COUNT = "X-AppEngine-TaskRetryCount";
|
||||
|
||||
static int MAX_RETRY = 3;
|
||||
|
||||
/**
|
||||
* Only admin can make this request.
|
||||
*/
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws IOException {
|
||||
|
||||
String registrationId = req.getParameter(C2DMessaging.PARAM_REGISTRATION_ID);
|
||||
String retryCount = req.getHeader(RETRY_COUNT);
|
||||
if (retryCount != null) {
|
||||
int retryCnt = Integer.parseInt(retryCount);
|
||||
if (retryCnt > MAX_RETRY) {
|
||||
log.severe("Too many retries, drop message for :" + registrationId);
|
||||
resp.setStatus(200);
|
||||
return; // will not try again.
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String[]> params = req.getParameterMap();
|
||||
String collapse = req.getParameter(C2DMessaging.PARAM_COLLAPSE_KEY);
|
||||
boolean delayWhenIdle =
|
||||
null != req.getParameter(C2DMessaging.PARAM_DELAY_WHILE_IDLE);
|
||||
|
||||
try {
|
||||
// Send doesn't retry !!
|
||||
// We use the queue exponential backoff for retries.
|
||||
boolean sentOk = C2DMessaging.get(getServletContext())
|
||||
.sendNoRetry(registrationId, collapse, params, delayWhenIdle);
|
||||
log.info("Retry result " + sentOk + " " + registrationId);
|
||||
if (sentOk) {
|
||||
resp.setStatus(200);
|
||||
resp.getOutputStream().write("OK".getBytes());
|
||||
} else {
|
||||
resp.setStatus(500); // retry this task
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
resp.setStatus(200);
|
||||
resp.getOutputStream().write(("Non-retriable error:" +
|
||||
ex.toString()).getBytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
package com.google.android.c2dm.server;
|
||||
|
||||
import com.google.android.gcm.server.Message;
|
||||
import com.google.android.gcm.server.Result;
|
||||
import com.google.android.gcm.server.Sender;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
@@ -34,13 +37,6 @@ import javax.jdo.PersistenceManagerFactory;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.google.appengine.api.taskqueue.Queue;
|
||||
import com.google.appengine.api.taskqueue.QueueFactory;
|
||||
import com.google.appengine.api.taskqueue.TaskHandle;
|
||||
import com.google.appengine.api.taskqueue.TaskOptions;
|
||||
|
||||
/**
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class C2DMessaging {
|
||||
private static final String UPDATE_CLIENT_AUTH = "Update-Client-Auth";
|
||||
@@ -113,6 +109,11 @@ public class C2DMessaging {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is deprecated because C2DM has been replaced by GCM, and it
|
||||
* provides a library with similar functionality.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean sendNoRetry(String registrationId,
|
||||
String collapse,
|
||||
Map<String, String[]> params,
|
||||
@@ -220,51 +221,11 @@ public class C2DMessaging {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to send a message, with 2 parameters.
|
||||
*
|
||||
* Permanent errors will result in IOException.
|
||||
* Retriable errors will cause the message to be scheduled for retry.
|
||||
* This method is deprecated because C2DM has been replaced by GCM, and it
|
||||
* provides a library with similar functionality.
|
||||
*/
|
||||
public void sendWithRetry(String token, String collapseKey,
|
||||
String name1, String value1, String name2, String value2,
|
||||
String name3, String value3)
|
||||
throws IOException {
|
||||
|
||||
Map<String, String[]> params = new HashMap<String, String[]>();
|
||||
if (value1 != null) params.put("data." + name1, new String[] {value1});
|
||||
if (value2 != null) params.put("data." + name2, new String[] {value2});
|
||||
if (value3 != null) params.put("data." + name3, new String[] {value3});
|
||||
|
||||
boolean sentOk = sendNoRetry(token, collapseKey, params, true);
|
||||
if (!sentOk) {
|
||||
retry(token, collapseKey, params, true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendNoRetry(String token, String collapseKey,
|
||||
String name1, String value1, String name2, String value2,
|
||||
String name3, String value3) {
|
||||
|
||||
Map<String, String[]> params = new HashMap<String, String[]>();
|
||||
if (value1 != null) params.put("data." + name1, new String[] {value1});
|
||||
if (value2 != null) params.put("data." + name2, new String[] {value2});
|
||||
if (value3 != null) params.put("data." + name3, new String[] {value3});
|
||||
|
||||
try {
|
||||
return sendNoRetry(token, collapseKey, params, true);
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final ThreadLocal<IOException> C2DM_EXCEPTION =
|
||||
new ThreadLocal<IOException>();
|
||||
|
||||
public static IOException getC2dmException() {
|
||||
return C2DM_EXCEPTION.get();
|
||||
}
|
||||
|
||||
public boolean sendNoRetry(String token, String collapseKey,
|
||||
@Deprecated
|
||||
public Object sendNoRetry(String token, String collapseKey,
|
||||
String... nameValues) {
|
||||
|
||||
Map<String, String[]> params = new HashMap<String, String[]>();
|
||||
@@ -281,42 +242,25 @@ public class C2DMessaging {
|
||||
}
|
||||
|
||||
try {
|
||||
C2DM_EXCEPTION.remove();
|
||||
return sendNoRetry(token, collapseKey, params, true);
|
||||
} catch (IOException ex) {
|
||||
// save exception in a thread-local object so it can be cheked for
|
||||
// unregistration later
|
||||
C2DM_EXCEPTION.set(ex);
|
||||
return false;
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void retry(String token, String collapseKey,
|
||||
Map<String, String[]> params, boolean delayWhileIdle) {
|
||||
Queue dmQueue = QueueFactory.getQueue("c2dm");
|
||||
public Result send(Message message, String regId) {
|
||||
String key = serverConfig.getGcmApiKey();
|
||||
Sender sender = new Sender(key);
|
||||
try {
|
||||
TaskOptions url =
|
||||
TaskOptions.Builder.withUrl(C2DMRetryServlet.URI)
|
||||
.param(C2DMessaging.PARAM_REGISTRATION_ID, token)
|
||||
.param(C2DMessaging.PARAM_COLLAPSE_KEY, collapseKey);
|
||||
if (delayWhileIdle) {
|
||||
url.param(PARAM_DELAY_WHILE_IDLE, "1");
|
||||
// TODO: should use AppEngine's queue mechanism to retry, otherwise the
|
||||
// request might time out
|
||||
Result result = sender.send(message, regId, 2 /* number of tries */);
|
||||
log.fine("Result: " + result);
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
log.log(Level.SEVERE, "Error sending " + message + " to " + regId, e);
|
||||
return null;
|
||||
}
|
||||
for (String key: params.keySet()) {
|
||||
String[] values = params.get(key);
|
||||
url.param(key, URLEncoder.encode(values[0], UTF8));
|
||||
}
|
||||
|
||||
// Task queue implements the exponential backoff
|
||||
long jitter = (int) Math.random() * DATAMESSAGING_MAX_JITTER_MSEC;
|
||||
url.countdownMillis(jitter);
|
||||
|
||||
TaskHandle add = dmQueue.add(url);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// Ignore - UTF8 should be supported
|
||||
log.log(Level.SEVERE, "Unexpected error", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BIN
appengine/lib/gcm-server.jar
Normal file
BIN
appengine/lib/gcm-server.jar
Normal file
Binary file not shown.
BIN
appengine/lib/json_simple-1.1.jar
Normal file
BIN
appengine/lib/json_simple-1.1.jar
Normal file
Binary file not shown.
@@ -23,7 +23,9 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.jdo.JDOObjectNotFoundException;
|
||||
import javax.jdo.PersistenceManager;
|
||||
import javax.jdo.Query;
|
||||
import javax.jdo.annotations.IdentityType;
|
||||
@@ -173,4 +175,14 @@ public class DeviceInfo {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static DeviceInfo getDeviceInfo(PersistenceManager pm, String regId) {
|
||||
Query query = pm.newQuery(DeviceInfo.class);
|
||||
query.setFilter("deviceRegistrationID == '" + regId + "'");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<DeviceInfo> result = (List<DeviceInfo>) query.execute();
|
||||
DeviceInfo deviceInfo = (result == null || result.isEmpty()) ? null : result.get(0);
|
||||
query.closeAll();
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -237,4 +237,17 @@ public class RequestInfo {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateRegistration(String regId, String canonicalRegId) {
|
||||
if (ctx == null) {
|
||||
return;
|
||||
}
|
||||
log.fine("Updating regId " + regId + " to canonical " + canonicalRegId);
|
||||
PersistenceManager pm = C2DMessaging.getPMF(ctx).getPersistenceManager();
|
||||
DeviceInfo device = DeviceInfo.getDeviceInfo(pm, regId);
|
||||
device.setDeviceRegistrationID(canonicalRegId);
|
||||
pm.currentTransaction().begin();
|
||||
pm.makePersistent(device);
|
||||
pm.currentTransaction().commit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
package com.google.android.chrometophone.server;
|
||||
|
||||
import com.google.android.c2dm.server.C2DMessaging;
|
||||
import com.google.android.gcm.server.Constants;
|
||||
import com.google.android.gcm.server.Message;
|
||||
import com.google.android.gcm.server.Message.Builder;
|
||||
import com.google.android.gcm.server.Result;
|
||||
import com.google.android.gcm.server.Sender;
|
||||
import com.google.appengine.api.channel.ChannelMessage;
|
||||
import com.google.appengine.api.channel.ChannelServiceFactory;
|
||||
|
||||
@@ -86,18 +91,18 @@ public class SendServlet extends HttpServlet {
|
||||
|
||||
// Send push message to phone
|
||||
C2DMessaging push = C2DMessaging.get(getServletContext());
|
||||
boolean res = false;
|
||||
Object res = null;
|
||||
|
||||
String collapseKey = "" + url.hashCode();
|
||||
|
||||
boolean reqDebug = "1".equals(reqInfo.getParameter("debug"));
|
||||
|
||||
int ac2dmCnt = 0;
|
||||
int deviceCount = 0;
|
||||
Iterator<DeviceInfo> iterator = reqInfo.devices.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
DeviceInfo deviceInfo = iterator.next();
|
||||
if ("ac2dm".equals(deviceInfo.getType())) {
|
||||
ac2dmCnt++;
|
||||
if (!DeviceInfo.TYPE_CHROME.equals(deviceInfo.getType())) {
|
||||
deviceCount++;
|
||||
}
|
||||
if (deviceNames != null) {
|
||||
boolean found = false;
|
||||
@@ -117,28 +122,57 @@ public class SendServlet extends HttpServlet {
|
||||
if (deviceInfo.getType().equals(DeviceInfo.TYPE_CHROME)) {
|
||||
res = doSendViaBrowserChannel(url, deviceInfo);
|
||||
} else {
|
||||
res = doSendViaC2dm(url, title, sel, push, collapseKey,
|
||||
deviceInfo, reqDebug);
|
||||
res = doSendViaGoogleCloud(url, title, sel, push, collapseKey,
|
||||
deviceInfo, reqDebug, deviceInfo.getType());
|
||||
}
|
||||
|
||||
if (res) {
|
||||
if (res == null) {
|
||||
log.info("Link sent to phone! collapse_key:" + collapseKey);
|
||||
ok = true;
|
||||
} else {
|
||||
// C2DM error
|
||||
if (res instanceof IOException) {
|
||||
IOException ex = (IOException) res;
|
||||
log.warning("Error: Unable to send link to device: " +
|
||||
deviceInfo.getDeviceRegistrationID());
|
||||
IOException ex = C2DMessaging.getC2dmException();
|
||||
if (ex != null) {
|
||||
if ("InvalidRegistration".equals(ex.getMessage())) {
|
||||
String error = "" + ex.getMessage();
|
||||
if (error.equals(Constants.ERROR_NOT_REGISTERED) || error.equals(Constants.ERROR_INVALID_REGISTRATION)) {
|
||||
// Prune device, it no longer works
|
||||
reqInfo.deleteRegistration(deviceInfo.getDeviceRegistrationID(),
|
||||
deviceInfo.getType());
|
||||
iterator.remove();
|
||||
ac2dmCnt--;
|
||||
deviceCount--;
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
// GCM result.
|
||||
if (res instanceof Result) {
|
||||
Result result = (Result) res;
|
||||
String regId = deviceInfo.getDeviceRegistrationID();
|
||||
if (result.getMessageId() != null) {
|
||||
log.info("Link sent to phone! collapse_key:" + collapseKey);
|
||||
ok = true;
|
||||
String canonicalRegId = result.getCanonicalRegistrationId();
|
||||
if (canonicalRegId != null) {
|
||||
// same device has more than on registration id: update it
|
||||
log.finest("canonicalRegId " + canonicalRegId);
|
||||
reqInfo.updateRegistration(regId, canonicalRegId);
|
||||
}
|
||||
} else {
|
||||
String error = result.getErrorCodeName();
|
||||
if (error.equals(Constants.ERROR_NOT_REGISTERED) || error.equals(Constants.ERROR_INVALID_REGISTRATION)) {
|
||||
// Prune device, it no longer works
|
||||
reqInfo.deleteRegistration(regId, deviceInfo.getType());
|
||||
iterator.remove();
|
||||
deviceCount--;
|
||||
} else {
|
||||
log.severe("Error sending message to device " + regId
|
||||
+ ": " + error);
|
||||
throw new IOException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +183,7 @@ public class SendServlet extends HttpServlet {
|
||||
// Show the 'no devices' if only the browser is registered.
|
||||
// We should also clarify that 'error status' mean no matching
|
||||
// device found ( when the extension allow specifying the destination )
|
||||
if (ac2dmCnt == 0 && "ac2dm".equals(deviceType)) {
|
||||
if (deviceCount == 0 && !DeviceInfo.TYPE_CHROME.equals(deviceType)) {
|
||||
log.warning("No device registered for " + reqInfo.userName);
|
||||
return DEVICE_NOT_REGISTERED_STATUS;
|
||||
} else {
|
||||
@@ -158,8 +192,8 @@ public class SendServlet extends HttpServlet {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doSendViaC2dm(String url, String title, String sel, C2DMessaging push,
|
||||
String collapseKey, DeviceInfo deviceInfo, boolean reqDebug) {
|
||||
private Object doSendViaGoogleCloud(String url, String title, String sel, C2DMessaging push,
|
||||
String collapseKey, DeviceInfo deviceInfo, boolean reqDebug, String deviceType) {
|
||||
|
||||
// Trim title, sel if needed.
|
||||
if (url.length() + title.length() + sel.length() > 1000) {
|
||||
@@ -177,13 +211,28 @@ public class SendServlet extends HttpServlet {
|
||||
}
|
||||
}
|
||||
|
||||
boolean res;
|
||||
res = push.sendNoRetry(deviceInfo.getDeviceRegistrationID(),
|
||||
String regId = deviceInfo.getDeviceRegistrationID();
|
||||
String debug = (deviceInfo.getDebug()) || reqDebug ? "1" : null;
|
||||
Object res;
|
||||
if (deviceType.equals(DeviceInfo.TYPE_AC2DM)) {
|
||||
res = push.sendNoRetry(regId,
|
||||
collapseKey,
|
||||
"url", url,
|
||||
"title", title,
|
||||
"sel", sel,
|
||||
"debug", deviceInfo.getDebug() || reqDebug ? "1" : null);
|
||||
"debug", debug);
|
||||
} else {
|
||||
Builder builder = new Message.Builder()
|
||||
.collapseKey(collapseKey)
|
||||
.addData("url", url)
|
||||
.addData("title", title)
|
||||
.addData("sel", sel);
|
||||
if (debug != null) {
|
||||
builder.addData("debug", debug);
|
||||
}
|
||||
Message message = builder.build();
|
||||
res = push.send(message, regId);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ public class UnregisterServlet extends HttpServlet {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: make sure new app passes deviceType
|
||||
String deviceType = reqInfo.getParameter("deviceType");
|
||||
if (deviceType == null) {
|
||||
deviceType = "ac2dm";
|
||||
|
||||
@@ -55,13 +55,6 @@
|
||||
</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>dataMessagingServlet</servlet-name>
|
||||
<servlet-class>
|
||||
com.google.android.c2dm.server.C2DMRetryServlet
|
||||
</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>SenderServlet</servlet-name>
|
||||
<servlet-class>com.google.android.chrometophone.server.SenderServlet
|
||||
@@ -130,20 +123,6 @@
|
||||
<url-pattern>/admin/convertStats</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>dataMessagingServlet</servlet-name>
|
||||
<url-pattern>/tasks/c2dm</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>tasks</web-resource-name>
|
||||
<url-pattern>/tasks/*</url-pattern>
|
||||
</web-resource-collection>
|
||||
<auth-constraint>
|
||||
<role-name>admin</role-name>
|
||||
</auth-constraint>
|
||||
</security-constraint>
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>admin</web-resource-name>
|
||||
|
||||
@@ -174,4 +174,3 @@ function closeBrowserChannel() {
|
||||
socketCloseRequested = true;
|
||||
if (socket) socket.close();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user