• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.voicemail.impl.scheduling;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.os.BadParcelableException;
22 import android.os.Bundle;
23 import android.support.annotation.NonNull;
24 import com.android.voicemail.impl.VvmLog;
25 
26 /** Common operations on {@link Task} */
27 final class Tasks {
28 
Tasks()29   private Tasks() {}
30 
31   static final String EXTRA_CLASS_NAME = "extra_class_name";
32 
33   /** The task cannot be created. */
34   static final class TaskCreationException extends Exception {
TaskCreationException(Throwable throwable)35     TaskCreationException(Throwable throwable) {
36       super(throwable);
37     }
38   }
39 
40   /**
41    * Create a task from a bundle. The bundle is created either with {@link #toBundle(Task)} or
42    * {@link #createIntent(Context, Class)} from the target {@link Task}
43    */
44   @NonNull
createTask(Context context, Bundle extras)45   public static Task createTask(Context context, Bundle extras) throws TaskCreationException {
46     // The extra contains custom parcelables which cannot be unmarshalled by the framework class
47     // loader.
48     extras.setClassLoader(context.getClassLoader());
49     String className;
50     try {
51       className = extras.getString(EXTRA_CLASS_NAME);
52     } catch (BadParcelableException e) {
53       // BadParcelableException:Parcelable protocol requires that the class implements Parcelable
54       // This happens when the task is submitted before an update, and can no longer be unparceled.
55       throw new TaskCreationException(e);
56     }
57     VvmLog.i("Task.createTask", "create task:" + className);
58     if (className == null) {
59       throw new IllegalArgumentException("EXTRA_CLASS_NAME expected");
60     }
61     try {
62       Task task = (Task) Class.forName(className).getDeclaredConstructor().newInstance();
63       task.onCreate(context, extras);
64       return task;
65     } catch (ReflectiveOperationException e) {
66       throw new IllegalArgumentException(e);
67     }
68   }
69 
70   /**
71    * Serializes necessary states to a bundle that can be used to restore the task with {@link
72    * #createTask(Context, Bundle)}
73    */
toBundle(Task task)74   public static Bundle toBundle(Task task) {
75     Bundle result = task.toBundle();
76     result.putString(EXTRA_CLASS_NAME, task.getClass().getName());
77     return result;
78   }
79 
80   /**
81    * Create an intent that when called with {@link Context#startService(Intent)}, will queue the
82    * <code>task</code>. Implementations of {@link Task} should use the result of this and fill in
83    * necessary information.
84    */
createIntent(Context context, Class<? extends Task> task)85   public static Intent createIntent(Context context, Class<? extends Task> task) {
86     Intent intent = new Intent(context, TaskReceiver.class);
87     intent.setPackage(context.getPackageName());
88     intent.putExtra(EXTRA_CLASS_NAME, task.getName());
89     return intent;
90   }
91 }
92