android10 bootAnimation启动过程

1.init.rc脚本中bootanim是disable的

2.启动界面依赖于android系统的surface管理服务,显示必须初始化完成

3.surfaceflinger服务完成后,才能显示开机界面

4.当system_server启动系统HomeUI的时候关闭bootanim

xref: /frameworks/base/cmds/bootanimation/bootanimation_main.cpp

36  int main()
37  {
38      setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
39  
40      bool noBootAnimation = bootAnimationDisabled();
41      ALOGI_IF(noBootAnimation,  "boot animation disabled");
42      if (!noBootAnimation) {
43  
44          sp<ProcessState> proc(ProcessState::self());
45          ProcessState::self()->startThreadPool();
46  
47          // create the boot animation object (may take up to 200ms for 2MB zip)
48          sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());
49  
50          waitForSurfaceFlinger();
51  
52          boot->run("BootAnimation", PRIORITY_DISPLAY);
53  
54          ALOGV("Boot animation set up. Joining pool.");
55  
56          IPCThreadState::self()->joinThreadPool();
57      }
58      return 0;
59  }

开启线程池,创建BootAnimation对象,等待SurfaceFlinger的创建,然后执行run方法。

xref: /frameworks/base/cmds/bootanimation/BootAnimation.cpp

103  
104  BootAnimation::BootAnimation(sp<Callbacks> callbacks)
105          : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
106          mTimeFormat12Hour(false), mTimeCheckThread(nullptr), mCallbacks(callbacks) {
107      mSession = new SurfaceComposerClient();
108  
109      std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
110      if (powerCtl.empty()) {
111          mShuttingDown = false;
112      } else {
113          mShuttingDown = true;
114      }
115      ALOGD("%sAnimationStartTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
116              elapsedRealtime());
117  }

在BootAnimation构造方法中创建了SurfaceComposerClient对象,"sys.powerctl"用于获取开关机的属性。

128  void BootAnimation::onFirstRef() {
129      status_t err = mSession->linkToComposerDeath(this);
130      SLOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
131      if (err == NO_ERROR) {
132          // Load the animation content -- this can be slow (eg 200ms)
133          // called before waitForSurfaceFlinger() in main() to avoid wait
134          ALOGD("%sAnimationPreloadTiming start time: %" PRId64 "ms",
135                  mShuttingDown ? "Shutdown" : "Boot", elapsedRealtime());
136          preloadAnimation();
137          ALOGD("%sAnimationPreloadStopTiming start time: %" PRId64 "ms",
138                  mShuttingDown ? "Shutdown" : "Boot", elapsedRealtime());
139      }
140  }

BootAnimation创建的时候使用了智能指针,所以会执行onFirstRef方法。

 
330  bool BootAnimation::preloadAnimation() {
331      findBootAnimationFile();
332      if (!mZipFileName.isEmpty()) {
333          mAnimation = loadAnimation(mZipFileName);
334          return (mAnimation != nullptr);
335      }
336  
337      return false;
338  }
339  
340  void BootAnimation::findBootAnimationFile() {
341      // If the device has encryption turned on or is in process
342      // of being encrypted we show the encrypted boot animation.
343      char decrypt[PROPERTY_VALUE_MAX];
344      property_get("vold.decrypt", decrypt, "");
345  
346      bool encryptedAnimation = atoi(decrypt) != 0 ||
347          !strcmp("trigger_restart_min_framework", decrypt);
348  
349      if (!mShuttingDown && encryptedAnimation) {
350          static const char* encryptedBootFiles[] =
351              {PRODUCT_ENCRYPTED_BOOTANIMATION_FILE, SYSTEM_ENCRYPTED_BOOTANIMATION_FILE};
352          for (const char* f : encryptedBootFiles) {
353              if (access(f, R_OK) == 0) {
354                  mZipFileName = f;
355                  return;
356              }
357          }
358      }
359  
360      const bool playDarkAnim = android::base::GetIntProperty("ro.boot.theme", 0) == 1;
361      static const char* bootFiles[] =
362          {APEX_BOOTANIMATION_FILE, playDarkAnim ? PRODUCT_BOOTANIMATION_DARK_FILE : PRODUCT_BOOTANIMATION_FILE,
363           OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};
364      static const char* shutdownFiles[] =
365          {PRODUCT_SHUTDOWNANIMATION_FILE, OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE, ""};
366  
367      for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {
368          if (access(f, R_OK) == 0) {
369              mZipFileName = f;
370              return;
371          }
372      }
373  }
1092  BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn)
1093  {
1094      if (mLoadedFiles.indexOf(fn) >= 0) {
1095          SLOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",
1096              fn.string());
1097          return nullptr;
1098      }
1099      ZipFileRO *zip = ZipFileRO::open(fn);
1100      if (zip == nullptr) {
1101          SLOGE("Failed to open animation zip \"%s\": %s",
1102              fn.string(), strerror(errno));
1103          return nullptr;
1104      }
1105  
1106      Animation *animation =  new Animation;
1107      animation->fileName = fn;
1108      animation->zip = zip;
1109      animation->clockFont.map = nullptr;
1110      mLoadedFiles.add(animation->fileName);
1111  
1112      parseAnimationDesc(*animation);
1113      if (!preloadZip(*animation)) {
1114          return nullptr;
1115      }
1116  
1117  
1118      mLoadedFiles.remove(fn);
1119      return animation;
1120  }

查找开机动画的文件,通过zip文件名去加载动画。

boot->run执行后会运行BootAnimation::::readyToRun方法。

 
270  status_t BootAnimation::readyToRun() {
271      mAssets.addDefaultAssets();
272  
273      mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
274      if (mDisplayToken == nullptr)
275          return -1;
276  
277      DisplayInfo dinfo;
278      status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo);
279      if (status)
280          return -1;
281  
282      // create the native surface
283      sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
284              dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
285  
286      SurfaceComposerClient::Transaction t;
287      t.setLayer(control, 0x40000000)
288          .apply();
289  
290      sp<Surface> s = control->getSurface();
291  
292      // initialize opengl and egl
293      const EGLint attribs[] = {
294              EGL_RED_SIZE,   8,
295              EGL_GREEN_SIZE, 8,
296              EGL_BLUE_SIZE,  8,
297              EGL_DEPTH_SIZE, 0,
298              EGL_NONE
299      };
300      EGLint w, h;
301      EGLint numConfigs;
302      EGLConfig config;
303      EGLSurface surface;
304      EGLContext context;
305  
306      EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
307  
308      eglInitialize(display, nullptr, nullptr);
309      eglChooseConfig(display, attribs, &config, 1, &numConfigs);
310      surface = eglCreateWindowSurface(display, config, s.get(), nullptr);
311      context = eglCreateContext(display, config, nullptr, nullptr);
312      eglQuerySurface(display, surface, EGL_WIDTH, &w);
313      eglQuerySurface(display, surface, EGL_HEIGHT, &h);
314  
315      if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
316          return NO_INIT;
317  
318      mDisplay = display;
319      mContext = context;
320      mSurface = surface;
321      mWidth = w;
322      mHeight = h;
323      mFlingerSurfaceControl = control;
324      mFlingerSurface = s;
325      mTargetInset = -1;
326  
327      return NO_ERROR;
328  }

通过SurfaceComposerClient拿到显示的层并且创建宽和高,然后做一些OpenGL相关的工作。

IPCThreadState::self()->joinThreadPool执行之后,执行BootAnimation::threadLoop方法。

375  bool BootAnimation::threadLoop()
376  {
377      bool r;
378      // We have no bootanimation file, so we use the stock android logo
379      // animation.
380      if (mZipFileName.isEmpty()) {
381          r = android();
382      } else {
383          r = movie();
384      }
385  
386      eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
387      eglDestroyContext(mDisplay, mContext);
388      eglDestroySurface(mDisplay, mSurface);
389      mFlingerSurface.clear();
390      mFlingerSurfaceControl.clear();
391      eglTerminate(mDisplay);
392      eglReleaseThread();
393      IPCThreadState::self()->stopProcess();
394      return r;
395  }

如果mZipFileName为空则播放原生android动画,如果不是空则播放zip包里面的动画。使用OpenGL绘制动画。这里主要分析move方法。

 
832  bool BootAnimation::movie()
833  {
834      if (mAnimation == nullptr) {
835          mAnimation = loadAnimation(mZipFileName);
836      }
837  
838      if (mAnimation == nullptr)
839          return false;
840  
841      // mCallbacks->init() may get called recursively,
842      // this loop is needed to get the same results
843      for (const Animation::Part& part : mAnimation->parts) {
844          if (part.animation != nullptr) {
845              mCallbacks->init(part.animation->parts);
846          }
847      }
848      mCallbacks->init(mAnimation->parts);
849  
850      bool anyPartHasClock = false;
851      for (size_t i=0; i < mAnimation->parts.size(); i++) {
852          if(validClock(mAnimation->parts[i])) {
853              anyPartHasClock = true;
854              break;
855          }
856      }
857      if (!anyPartHasClock) {
858          mClockEnabled = false;
859      }
860  
861      // Check if npot textures are supported
862      mUseNpotTextures = false;
863      String8 gl_extensions;
864      const char* exts = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
865      if (!exts) {
866          glGetError();
867      } else {
868          gl_extensions.setTo(exts);
869          if ((gl_extensions.find("GL_ARB_texture_non_power_of_two") != -1) ||
870              (gl_extensions.find("GL_OES_texture_npot") != -1)) {
871              mUseNpotTextures = true;
872          }
873      }
874  
875      // Blend required to draw time on top of animation frames.
876      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
877      glShadeModel(GL_FLAT);
878      glDisable(GL_DITHER);
879      glDisable(GL_SCISSOR_TEST);
880      glDisable(GL_BLEND);
881  
882      glBindTexture(GL_TEXTURE_2D, 0);
883      glEnable(GL_TEXTURE_2D);
884      glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
885      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
886      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
887      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
888      glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
889  
890      bool clockFontInitialized = false;
891      if (mClockEnabled) {
892          clockFontInitialized =
893              (initFont(&mAnimation->clockFont, CLOCK_FONT_ASSET) == NO_ERROR);
894          mClockEnabled = clockFontInitialized;
895      }
896  
897      if (mClockEnabled && !updateIsTimeAccurate()) {
898          mTimeCheckThread = new TimeCheckThread(this);
899          mTimeCheckThread->run("BootAnimation::TimeCheckThread", PRIORITY_NORMAL);
900      }
901  
902      playAnimation(*mAnimation);
903  
904      if (mTimeCheckThread != nullptr) {
905          mTimeCheckThread->requestExit();
906          mTimeCheckThread = nullptr;
907      }
908  
909      if (clockFontInitialized) {
910          glDeleteTextures(1, &mAnimation->clockFont.texture.name);
911      }
912  
913      releaseAnimation(mAnimation);
914      mAnimation = nullptr;
915  
916      return false;
917  }
918  
919  bool BootAnimation::playAnimation(const Animation& animation)
920  {
921      const size_t pcount = animation.parts.size();
922      nsecs_t frameDuration = s2ns(1) / animation.fps;
923      const int animationX = (mWidth - animation.width) / 2;
924      const int animationY = (mHeight - animation.height) / 2;
925  
926      SLOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
927              elapsedRealtime());
928      for (size_t i=0 ; i<pcount ; i++) {
929          const Animation::Part& part(animation.parts[i]);
930          const size_t fcount = part.frames.size();
931          glBindTexture(GL_TEXTURE_2D, 0);
932  
933          // Handle animation package
934          if (part.animation != nullptr) {
935              playAnimation(*part.animation);
936              if (exitPending())
937                  break;
938              continue; //to next part
939          }
940  
941          for (int r=0 ; !part.count || r<part.count ; r++) {
942              // Exit any non playuntil complete parts immediately
943              if(exitPending() && !part.playUntilComplete)
944                  break;
945  
946              mCallbacks->playPart(i, part, r);
947  
948              glClearColor(
949                      part.backgroundColor[0],
950                      part.backgroundColor[1],
951                      part.backgroundColor[2],
952                      1.0f);
953  
954              for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
955                  const Animation::Frame& frame(part.frames[j]);
956                  nsecs_t lastFrame = systemTime();
957  
958                  if (r > 0) {
959                      glBindTexture(GL_TEXTURE_2D, frame.tid);
960                  } else {
961                      if (part.count != 1) {
962                          glGenTextures(1, &frame.tid);
963                          glBindTexture(GL_TEXTURE_2D, frame.tid);
964                          glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
965                          glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
966                      }
967                      int w, h;
968                      initTexture(frame.map, &w, &h);
969                  }
970  
971                  const int xc = animationX + frame.trimX;
972                  const int yc = animationY + frame.trimY;
973                  Region clearReg(Rect(mWidth, mHeight));
974                  clearReg.subtractSelf(Rect(xc, yc, xc+frame.trimWidth, yc+frame.trimHeight));
975                  if (!clearReg.isEmpty()) {
976                      Region::const_iterator head(clearReg.begin());
977                      Region::const_iterator tail(clearReg.end());
978                      glEnable(GL_SCISSOR_TEST);
979                      while (head != tail) {
980                          const Rect& r2(*head++);
981                          glScissor(r2.left, mHeight - r2.bottom, r2.width(), r2.height());
982                          glClear(GL_COLOR_BUFFER_BIT);
983                      }
984                      glDisable(GL_SCISSOR_TEST);
985                  }
986                  // specify the y center as ceiling((mHeight - frame.trimHeight) / 2)
987                  // which is equivalent to mHeight - (yc + frame.trimHeight)
988                  glDrawTexiOES(xc, mHeight - (yc + frame.trimHeight),
989                                0, frame.trimWidth, frame.trimHeight);
990                  if (mClockEnabled && mTimeIsAccurate && validClock(part)) {
991                      drawClock(animation.clockFont, part.clockPosX, part.clockPosY);
992                  }
993                  handleViewport(frameDuration);
994  
995                  eglSwapBuffers(mDisplay, mSurface);
996  
997                  nsecs_t now = systemTime();
998                  nsecs_t delay = frameDuration - (now - lastFrame);
999                  //SLOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay));
1000                  lastFrame = now;
1001  
1002                  if (delay > 0) {
1003                      struct timespec spec;
1004                      spec.tv_sec  = (now + delay) / 1000000000;
1005                      spec.tv_nsec = (now + delay) % 1000000000;
1006                      int err;
1007                      do {
1008                          err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, nullptr);
1009                      } while (err<0 && errno == EINTR);
1010                  }
1011  
1012                  checkExit();
1013              }
1014  
1015              usleep(part.pause * ns2us(frameDuration));
1016  
1017              // For infinite parts, we've now played them at least once, so perhaps exit
1018              if(exitPending() && !part.count && mCurrentInset >= mTargetInset)
1019                  break;
1020          }
1021  
1022      }
1023  
1024      // Free textures created for looping parts now that the animation is done.
1025      for (const Animation::Part& part : animation.parts) {
1026          if (part.count != 1) {
1027              const size_t fcount = part.frames.size();
1028              for (size_t j = 0; j < fcount; j++) {
1029                  const Animation::Frame& frame(part.frames[j]);
1030                  glDeleteTextures(1, &frame.tid);
1031              }
1032          }
1033      }
1034  
1035      return true;
1036  }

拿到move包,对配置文件进行解析,并设置相关的参数。在playAnimation方法中不断的调用for循环进行界面的刷新,通过​​​​​​​checkExit检测是否要退出动画。

static const char EXIT_PROP_NAME[] = "service.bootanim.exit";

466  void BootAnimation::checkExit() {
467      // Allow surface flinger to gracefully request shutdown
468      char value[PROPERTY_VALUE_MAX];
469      property_get(EXIT_PROP_NAME, value, "0");
470      int exitnow = atoi(value);
471      if (exitnow) {
472          requestExit();
473          mCallbacks->shutdown();
474      }
475  }

service.bootanim.exit取值为0的时候是启动,取值为1的时候是退出。

xref: /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp


75  int main(int, char**) {
76      signal(SIGPIPE, SIG_IGN);
77  
78      hardware::configureRpcThreadpool(1 /* maxThreads */,
79              false /* callerWillJoin */);
80  
81      startGraphicsAllocatorService();
82  
83      // When SF is launched in its own process, limit the number of
84      // binder threads to 4.
85      ProcessState::self()->setThreadPoolMaxThreadCount(4);
86  
87      // start the thread pool
88      sp<ProcessState> ps(ProcessState::self());
89      ps->startThreadPool();
90  
91      // instantiate surfaceflinger
92      sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
93  
94      setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
95  
96      set_sched_policy(0, SP_FOREGROUND);
97  
98      // Put most SurfaceFlinger threads in the system-background cpuset
99      // Keeps us from unnecessarily using big cores
100      // Do this after the binder thread pool init
101      if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);
102  
103      // initialize before clients can connect
104      flinger->init();
105  
106      // publish surface flinger
107      sp<IServiceManager> sm(defaultServiceManager());
108      sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
109                     IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
110  
111      startDisplayService(); // dependency on SF getting registered above
112  
113      struct sched_param param = {0};
114      param.sched_priority = 2;
115      if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
116          ALOGE("Couldn't set SCHED_FIFO");
117      }
118  
119      // run surface flinger in this thread
120      flinger->run();
121  
122      return 0;
123  }

对SurfaceFlinger进行初始化,调用init方法。

xref: /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

// Do not call property_set on main thread which will be blocked by init
608  // Use StartPropertySetThread instead.
609  void SurfaceFlinger::init() {
610      ALOGI(  "SurfaceFlinger's main thread ready to run. "
611              "Initializing graphics H/W...");
612  
613      ALOGI("Phase offset NS: %" PRId64 "", mPhaseOffsets->getCurrentAppOffset());
614  
615      Mutex::Autolock _l(mStateLock);
616      // start the EventThread
617      mScheduler =
618              getFactory().createScheduler([this](bool enabled) { setPrimaryVsyncEnabled(enabled); },
619                                           mRefreshRateConfigs);
620      auto resyncCallback =
621              mScheduler->makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));
622  
623      mAppConnectionHandle =
624              mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
625                                           resyncCallback,
626                                           impl::EventThread::InterceptVSyncsCallback());
627      mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),
628                                                         resyncCallback, [this](nsecs_t timestamp) {
629                                                             mInterceptor->saveVSyncEvent(timestamp);
630                                                         });
631  
632      mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
633      mVsyncModulator.setSchedulerAndHandles(mScheduler.get(), mAppConnectionHandle.get(),
634                                             mSfConnectionHandle.get());
635  
636      mRegionSamplingThread =
637              new RegionSamplingThread(*this, *mScheduler,
638                                       RegionSamplingThread::EnvironmentTimingTunables());
639  
640      // Get a RenderEngine for the given display / config (can't fail)
641      int32_t renderEngineFeature = 0;
642      renderEngineFeature |= (useColorManagement ?
643                              renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0);
644      renderEngineFeature |= (useContextPriority ?
645                              renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
646      renderEngineFeature |=
647              (enable_protected_contents(false) ? renderengine::RenderEngine::ENABLE_PROTECTED_CONTEXT
648                                                : 0);
649  
650      // TODO(b/77156734): We need to stop casting and use HAL types when possible.
651      // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
652      mCompositionEngine->setRenderEngine(
653              renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
654                                                 renderEngineFeature, maxFrameBufferAcquiredBuffers));
655  
656      LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
657              "Starting with vr flinger active is not currently supported.");
658      mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
659      mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
660      // Process any initial hotplug and resulting display changes.
661      processDisplayHotplugEventsLocked();
662      const auto display = getDefaultDisplayDeviceLocked();
663      LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
664      LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
665                          "Internal display is disconnected.");
666  
667      if (useVrFlinger) {
668          auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
669              // This callback is called from the vr flinger dispatch thread. We
670              // need to call signalTransaction(), which requires holding
671              // mStateLock when we're not on the main thread. Acquiring
672              // mStateLock from the vr flinger dispatch thread might trigger a
673              // deadlock in surface flinger (see b/66916578), so post a message
674              // to be handled on the main thread instead.
675              postMessageAsync(new LambdaMessage([=] {
676                  ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
677                  mVrFlingerRequestsDisplay = requestDisplay;
678                  signalTransaction();
679              }));
680          };
681          mVrFlinger = dvr::VrFlinger::Create(getHwComposer().getComposer(),
682                                              getHwComposer()
683                                                      .fromPhysicalDisplayId(*display->getId())
684                                                      .value_or(0),
685                                              vrFlingerRequestDisplayCallback);
686          if (!mVrFlinger) {
687              ALOGE("Failed to start vrflinger");
688          }
689      }
690  
691      // initialize our drawing state
692      mDrawingState = mCurrentState;
693  
694      // set initial conditions (e.g. unblank default device)
695      initializeDisplays();
696  
697      getRenderEngine().primeCache();
698  
699      // Inform native graphics APIs whether the present timestamp is supported:
700  
701      const bool presentFenceReliable =
702              !getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable);
703      mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
704  
705      if (mStartPropertySetThread->Start() != NO_ERROR) {
706          ALOGE("Run StartPropertySetThread failed!");
707      }
708  
709      mScheduler->setChangeRefreshRateCallback(
710              [this](RefreshRateType type, Scheduler::ConfigEvent event) {
711                  Mutex::Autolock lock(mStateLock);
712                  setRefreshRateTo(type, event);
713              });
714      mScheduler->setGetVsyncPeriodCallback([this] {
715          Mutex::Autolock lock(mStateLock);
716          return getVsyncPeriod();
717      });
718  
719      mRefreshRateConfigs.populate(getHwComposer().getConfigs(*display->getId()));
720      mRefreshRateStats.setConfigMode(getHwComposer().getActiveConfigIndex(*display->getId()));
721  
722      ALOGV("Done initializing");
723  }

mStartPropertySetThread->Start​​​​​​​启动线程,对 "service.bootanim.exit"赋值为0,开起开机动画。

xref: /frameworks/native/services/surfaceflinger/StartPropertySetThread.cpp

20  namespace android {
21  
22  StartPropertySetThread::StartPropertySetThread(bool timestampPropertyValue):
23          Thread(false), mTimestampPropertyValue(timestampPropertyValue) {}
24  
25  status_t StartPropertySetThread::Start() {
26      return run("SurfaceFlinger::StartPropertySetThread", PRIORITY_NORMAL);
27  }
28  
29  bool StartPropertySetThread::threadLoop() {
30      // Set property service.sf.present_timestamp, consumer need check its readiness
31      property_set(kTimestampProperty, mTimestampPropertyValue ? "1" : "0");
32      // Clear BootAnimation exit flag
33      property_set("service.bootanim.exit", "0");
34      // Start BootAnimation if not started
35      property_set("ctl.start", "bootanim");
36      // Exit immediately
37      return false;
38  }
39  
40  } // namespace android

xref: /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

526  void SurfaceFlinger::bootFinished()
527  {
528      if (mStartPropertySetThread->join() != NO_ERROR) {
529          ALOGE("Join StartPropertySetThread failed!");
530      }
531      const nsecs_t now = systemTime();
532      const nsecs_t duration = now - mBootTime;
533      ALOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
534  
535      // wait patiently for the window manager death
536      const String16 name("window");
537      sp<IBinder> window(defaultServiceManager()->getService(name));
538      if (window != 0) {
539          window->linkToDeath(static_cast<IBinder::DeathRecipient*>(this));
540      }
541      sp<IBinder> input(defaultServiceManager()->getService(
542              String16("inputflinger")));
543      if (input == nullptr) {
544          ALOGE("Failed to link to input service");
545      } else {
546          mInputFlinger = interface_cast<IInputFlinger>(input);
547      }
548  
549      if (mVrFlinger) {
550        mVrFlinger->OnBootFinished();
551      }
552  
553      // stop boot animation
554      // formerly we would just kill the process, but we now ask it to exit so it
555      // can choose where to stop the animation.
556      property_set("service.bootanim.exit", "1");
557  
558      const int LOGTAG_SF_STOP_BOOTANIM = 60110;
559      LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
560                     ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
561  
562      postMessageAsync(new LambdaMessage([this]() NO_THREAD_SAFETY_ANALYSIS {
563          readPersistentProperties();
564          mBootStage = BootStage::FINISHED;
565  
566          // set the refresh rate according to the policy
567          const auto& performanceRefreshRate =
568                  mRefreshRateConfigs.getRefreshRate(RefreshRateType::PERFORMANCE);
569  
570          if (performanceRefreshRate && isDisplayConfigAllowed(performanceRefreshRate->configId)) {
571              setRefreshRateTo(RefreshRateType::PERFORMANCE, Scheduler::ConfigEvent::None);
572          } else {
573              setRefreshRateTo(RefreshRateType::DEFAULT, Scheduler::ConfigEvent::None);
574          }
575      }));
576  }

当主Launcher拉起来了之后会向SurfaceFlinger发送消息调用bootFinished方法,将"service.bootanim.exit"设置为1,结束开机动画。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值