Home | History | Annotate | Download | only in common
      1 //
      2 // Copyright (C) 2011 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 #ifndef UPDATE_ENGINE_COMMON_ACTION_PROCESSOR_H_
     18 #define UPDATE_ENGINE_COMMON_ACTION_PROCESSOR_H_
     19 
     20 #include <deque>
     21 
     22 #include <base/macros.h>
     23 #include <brillo/errors/error.h>
     24 
     25 #include "update_engine/common/error_code.h"
     26 
     27 // The structure of these classes (Action, ActionPipe, ActionProcessor, etc.)
     28 // is based on the KSAction* classes from the Google Update Engine code at
     29 // http://code.google.com/p/update-engine/ . The author of this file sends
     30 // a big thanks to that team for their high quality design, implementation,
     31 // and documentation.
     32 
     33 // See action.h for an overview of this class and other Action* classes.
     34 
     35 // An ActionProcessor keeps a queue of Actions and processes them in order.
     36 
     37 namespace chromeos_update_engine {
     38 
     39 class AbstractAction;
     40 class ActionProcessorDelegate;
     41 
     42 class ActionProcessor {
     43  public:
     44   ActionProcessor() = default;
     45 
     46   virtual ~ActionProcessor();
     47 
     48   // Starts processing the first Action in the queue. If there's a delegate,
     49   // when all processing is complete, ProcessingDone() will be called on the
     50   // delegate.
     51   virtual void StartProcessing();
     52 
     53   // Aborts processing. If an Action is running, it will have
     54   // TerminateProcessing() called on it. The Action that was running and all the
     55   // remaining actions will be lost and must be re-enqueued if this Processor is
     56   // to use it.
     57   void StopProcessing();
     58 
     59   // Suspend the processing. If an Action is running, it will have the
     60   // SuspendProcessing() called on it, and it should suspend operations until
     61   // ResumeProcessing() is called on this class to continue. While suspended,
     62   // no new actions will be started. Calling SuspendProcessing while the
     63   // processing is suspended or not running this method performs no action.
     64   void SuspendProcessing();
     65 
     66   // Resume the suspended processing. If the ActionProcessor is not suspended
     67   // or not running in the first place this method performs no action.
     68   void ResumeProcessing();
     69 
     70   // Returns true iff the processing was started but not yet completed nor
     71   // stopped.
     72   bool IsRunning() const { return current_action_ != nullptr || suspended_; }
     73 
     74   // Adds another Action to the end of the queue.
     75   virtual void EnqueueAction(AbstractAction* action);
     76 
     77   // Sets/gets the current delegate. Set to null to remove a delegate.
     78   ActionProcessorDelegate* delegate() const { return delegate_; }
     79   void set_delegate(ActionProcessorDelegate *delegate) {
     80     delegate_ = delegate;
     81   }
     82 
     83   // Returns a pointer to the current Action that's processing.
     84   AbstractAction* current_action() const {
     85     return current_action_;
     86   }
     87 
     88   // Called by an action to notify processor that it's done. Caller passes self.
     89   void ActionComplete(AbstractAction* actionptr, ErrorCode code);
     90 
     91  private:
     92   // Continue processing actions (if any) after the last action terminated with
     93   // the passed error code. If there are no more actions to process, the
     94   // processing will terminate.
     95   void StartNextActionOrFinish(ErrorCode code);
     96 
     97   // Actions that have not yet begun processing, in the order in which
     98   // they'll be processed.
     99   std::deque<AbstractAction*> actions_;
    100 
    101   // A pointer to the currently processing Action, if any.
    102   AbstractAction* current_action_{nullptr};
    103 
    104   // The ErrorCode reported by an action that was suspended but finished while
    105   // being suspended. This error code is stored here to be reported back to the
    106   // delegate once the processor is resumed.
    107   ErrorCode suspended_error_code_{ErrorCode::kSuccess};
    108 
    109   // Whether the action processor is or should be suspended.
    110   bool suspended_{false};
    111 
    112   // A pointer to the delegate, or null if none.
    113   ActionProcessorDelegate* delegate_{nullptr};
    114 
    115   DISALLOW_COPY_AND_ASSIGN(ActionProcessor);
    116 };
    117 
    118 // A delegate object can be used to be notified of events that happen
    119 // in an ActionProcessor. An instance of this class can be passed to an
    120 // ActionProcessor to register itself.
    121 class ActionProcessorDelegate {
    122  public:
    123   virtual ~ActionProcessorDelegate() = default;
    124 
    125   // Called when all processing in an ActionProcessor has completed. A pointer
    126   // to the ActionProcessor is passed. |code| is set to the exit code of the
    127   // last completed action.
    128   virtual void ProcessingDone(const ActionProcessor* processor,
    129                               ErrorCode code) {}
    130 
    131   // Called when processing has stopped. Does not mean that all Actions have
    132   // completed. If/when all Actions complete, ProcessingDone() will be called.
    133   virtual void ProcessingStopped(const ActionProcessor* processor) {}
    134 
    135   // Called whenever an action has finished processing, either successfully
    136   // or otherwise.
    137   virtual void ActionCompleted(ActionProcessor* processor,
    138                                AbstractAction* action,
    139                                ErrorCode code) {}
    140 };
    141 
    142 }  // namespace chromeos_update_engine
    143 
    144 #endif  // UPDATE_ENGINE_COMMON_ACTION_PROCESSOR_H_
    145