1 /*
2 // Copyright (c) 2014 Intel Corporation 
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 #include <fcntl.h>
17 #include <errno.h>
18 #include <common/utils/HwcTrace.h>
19 #include <IDisplayDevice.h>
20 #include <DrmConfig.h>
21 #include <common/base/Drm.h>
22 #include <Hwcomposer.h>
23 
24 namespace android {
25 namespace intel {
26 
Drm()27 Drm::Drm()
28     : mDrmFd(0),
29       mLock(),
30       mInitialized(false)
31 {
32     memset(&mOutputs, 0, sizeof(mOutputs));
33 }
34 
~Drm()35 Drm::~Drm()
36 {
37     WARN_IF_NOT_DEINIT();
38 }
39 
initialize()40 bool Drm::initialize()
41 {
42     if (mInitialized) {
43         WLOGTRACE("Drm object has been initialized");
44         return true;
45     }
46 
47     const char *path = DrmConfig::getDrmPath();
48     mDrmFd = open(path, O_RDWR, 0);
49     if (mDrmFd < 0) {
50         ELOGTRACE("failed to open Drm, error: %s", strerror(errno));
51         return false;
52     }
53     DLOGTRACE("mDrmFd = %d", mDrmFd);
54 
55     memset(&mOutputs, 0, sizeof(mOutputs));
56     mInitialized = true;
57     return true;
58 }
59 
deinitialize()60 void Drm::deinitialize()
61 {
62     for (int i = 0; i < OUTPUT_MAX; i++) {
63         resetOutput(i);
64     }
65 
66     if (mDrmFd) {
67         close(mDrmFd);
68         mDrmFd = 0;
69     }
70     mInitialized = false;
71 }
72 
detect(int device)73 bool Drm::detect(int device)
74 {
75     RETURN_FALSE_IF_NOT_INIT();
76 
77     Mutex::Autolock _l(mLock);
78     int outputIndex = getOutputIndex(device);
79     if (outputIndex < 0 ) {
80         return false;
81     }
82 
83     resetOutput(outputIndex);
84 
85     // get drm resources
86     drmModeResPtr resources = drmModeGetResources(mDrmFd);
87     if (!resources) {
88         ELOGTRACE("fail to get drm resources, error: %s", strerror(errno));
89         return false;
90     }
91 
92     drmModeConnectorPtr connector = NULL;
93     DrmOutput *output = &mOutputs[outputIndex];
94     bool ret = false;
95 
96     // find connector for the given device
97     for (int i = 0; i < resources->count_connectors; i++) {
98         if (!resources->connectors || !resources->connectors[i]) {
99             ELOGTRACE("fail to get drm resources connectors, error: %s", strerror(errno));
100             continue;
101         }
102 
103         connector = drmModeGetConnector(mDrmFd, resources->connectors[i]);
104         if (!connector) {
105             ELOGTRACE("drmModeGetConnector failed");
106             continue;
107         }
108 
109         if (connector->connector_type != DrmConfig::getDrmConnector(device)) {
110             drmModeFreeConnector(connector);
111             continue;
112         }
113 
114         if (connector->connection != DRM_MODE_CONNECTED) {
115             ILOGTRACE("device %d is not connected", device);
116             drmModeFreeConnector(connector);
117             ret = true;
118             break;
119         }
120 
121         output->connector = connector;
122         output->connected = true;
123 
124         // get proper encoder for the given connector
125         if (connector->encoder_id) {
126             ILOGTRACE("Drm connector has encoder attached on device %d", device);
127             output->encoder = drmModeGetEncoder(mDrmFd, connector->encoder_id);
128             if (!output->encoder) {
129                 ELOGTRACE("failed to get encoder from a known encoder id");
130                 // fall through to get an encoder
131             }
132         }
133         if (!output->encoder) {
134             ILOGTRACE("getting encoder for device %d", device);
135             drmModeEncoderPtr encoder;
136             for (int j = 0; j < resources->count_encoders; j++) {
137                 if (!resources->encoders || !resources->encoders[j]) {
138                     ELOGTRACE("fail to get drm resources encoders, error: %s", strerror(errno));
139                     continue;
140                 }
141 
142                 encoder = drmModeGetEncoder(mDrmFd, resources->encoders[i]);
143                 if (!encoder) {
144                     ELOGTRACE("drmModeGetEncoder failed");
145                     continue;
146                 }
147                 if (encoder->encoder_type == DrmConfig::getDrmEncoder(device)) {
148                     output->encoder = encoder;
149                     break;
150                 }
151                 drmModeFreeEncoder(encoder);
152                 encoder = NULL;
153             }
154         }
155         if (!output->encoder) {
156             ELOGTRACE("failed to get drm encoder");
157             break;
158         }
159 
160         // get an attached crtc or spare crtc
161         if (output->encoder->crtc_id) {
162             ILOGTRACE("Drm encoder has crtc attached on device %d", device);
163             output->crtc = drmModeGetCrtc(mDrmFd, output->encoder->crtc_id);
164             if (!output->crtc) {
165                 ELOGTRACE("failed to get crtc from a known crtc id");
166                 // fall through to get a spare crtc
167             }
168         }
169         if (!output->crtc) {
170             ILOGTRACE("getting crtc for device %d", device);
171             drmModeCrtcPtr crtc;
172             for (int j = 0; j < resources->count_crtcs; j++) {
173                 if (!resources->crtcs || !resources->crtcs[j]) {
174                     ELOGTRACE("fail to get drm resources crtcs, error: %s", strerror(errno));
175                     continue;
176                 }
177 
178                 crtc = drmModeGetCrtc(mDrmFd, resources->crtcs[j]);
179                 if (!crtc) {
180                     ELOGTRACE("drmModeGetCrtc failed");
181                     continue;
182                 }
183                 // check if legal crtc to the encoder
184                 if (output->encoder->possible_crtcs & (1<<j)) {
185                     if (crtc->buffer_id == 0) {
186                         output->crtc = crtc;
187                         break;
188                     }
189                 }
190                 drmModeFreeCrtc(crtc);
191             }
192         }
193         if (!output->crtc) {
194             ELOGTRACE("failed to get drm crtc");
195             break;
196         }
197 
198         // current mode
199         if (output->crtc->mode_valid) {
200             ILOGTRACE("mode is valid, kernel mode settings");
201             memcpy(&output->mode, &output->crtc->mode, sizeof(drmModeModeInfo));
202             //output->fbId = output->crtc->buffer_id;
203             ret = true;
204         } else {
205             ELOGTRACE("mode is invalid. Kernel mode setting is not completed");
206             ret = false;
207         }
208 
209         if (outputIndex == OUTPUT_PRIMARY) {
210             if (!readIoctl(DRM_PSB_PANEL_ORIENTATION, &output->panelOrientation, sizeof(int))) {
211                 ELOGTRACE("failed to get device %d orientation", device);
212                 output->panelOrientation = PANEL_ORIENTATION_0;
213             }
214         } else {
215             output->panelOrientation = PANEL_ORIENTATION_0;
216         }
217         break;
218     }
219 
220     if (!ret) {
221         if (output->connector == NULL && outputIndex != OUTPUT_PRIMARY) {
222             // a fatal failure on primary device
223             // non fatal on secondary device
224             WLOGTRACE("device %d is disabled?", device);
225             ret = true;
226         }
227          resetOutput(outputIndex);
228     } else if (output->connected) {
229         ILOGTRACE("mode is: %dx%d@%dHz", output->mode.hdisplay, output->mode.vdisplay, output->mode.vrefresh);
230     }
231 
232     drmModeFreeResources(resources);
233     return ret;
234 }
235 
isSameDrmMode(drmModeModeInfoPtr value,drmModeModeInfoPtr base) const236 bool Drm::isSameDrmMode(drmModeModeInfoPtr value,
237         drmModeModeInfoPtr base) const
238 {
239     if (base->hdisplay == value->hdisplay &&
240         base->vdisplay == value->vdisplay &&
241         base->vrefresh == value->vrefresh &&
242         (base->flags & value->flags) == value->flags) {
243         VLOGTRACE("Drm mode is not changed");
244         return true;
245     }
246 
247     return false;
248 }
249 
setDrmMode(int device,drmModeModeInfo & value)250 bool Drm::setDrmMode(int device, drmModeModeInfo& value)
251 {
252     RETURN_FALSE_IF_NOT_INIT();
253     Mutex::Autolock _l(mLock);
254 
255     if (device != IDisplayDevice::DEVICE_EXTERNAL) {
256         WLOGTRACE("Setting mode on invalid device %d", device);
257         return false;
258     }
259 
260     int outputIndex = getOutputIndex(device);
261     if (outputIndex < 0 ) {
262         ELOGTRACE("invalid device");
263         return false;
264     }
265 
266     DrmOutput *output= &mOutputs[outputIndex];
267     if (!output->connected) {
268         ELOGTRACE("device is not connected");
269         return false;
270     }
271 
272     if (output->connector->count_modes <= 0) {
273         ELOGTRACE("invalid count of modes");
274         return false;
275     }
276 
277     drmModeModeInfoPtr mode;
278     int index = 0;
279     for (int i = 0; i < output->connector->count_modes; i++) {
280         mode = &output->connector->modes[i];
281         if (mode->type & DRM_MODE_TYPE_PREFERRED) {
282             index = i;
283         }
284         if (isSameDrmMode(&value, mode)) {
285             index = i;
286             break;
287         }
288     }
289 
290     mode = &output->connector->modes[index];
291     return setDrmMode(outputIndex, mode);
292 }
293 
setRefreshRate(int device,int hz)294 bool Drm::setRefreshRate(int device, int hz)
295 {
296     RETURN_FALSE_IF_NOT_INIT();
297     Mutex::Autolock _l(mLock);
298 
299     if (device != IDisplayDevice::DEVICE_EXTERNAL) {
300         WLOGTRACE("Setting mode on invalid device %d", device);
301         return false;
302     }
303 
304     int outputIndex = getOutputIndex(device);
305     if (outputIndex < 0 ) {
306         ELOGTRACE("invalid device");
307         return false;
308     }
309 
310     DrmOutput *output= &mOutputs[outputIndex];
311     if (!output->connected) {
312         ELOGTRACE("device is not connected");
313         return false;
314     }
315 
316     if (output->connector->count_modes <= 0) {
317         ELOGTRACE("invalid count of modes");
318         return false;
319     }
320 
321     drmModeModeInfoPtr mode;
322     int index = 0;
323     for (int i = 0; i < output->connector->count_modes; i++) {
324         mode = &output->connector->modes[i];
325         if (mode->type & DRM_MODE_TYPE_PREFERRED) {
326             index = i;
327         }
328         if (mode->hdisplay == output->mode.hdisplay &&
329             mode->vdisplay == output->mode.vdisplay &&
330             mode->vrefresh == (uint32_t)hz) {
331             index = i;
332             break;
333         }
334     }
335 
336     mode = &output->connector->modes[index];
337     return setDrmMode(outputIndex, mode);
338 }
339 
writeReadIoctl(unsigned long cmd,void * data,unsigned long size)340 bool Drm::writeReadIoctl(unsigned long cmd, void *data,
341                            unsigned long size)
342 {
343     int err;
344 
345     if (mDrmFd <= 0) {
346         ELOGTRACE("drm is not initialized");
347         return false;
348     }
349 
350     if (!data || !size) {
351         ELOGTRACE("invalid parameters");
352         return false;
353     }
354 
355     err = drmCommandWriteRead(mDrmFd, cmd, data, size);
356     if (err) {
357         WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
358         return false;
359     }
360 
361     return true;
362 }
363 
writeIoctl(unsigned long cmd,void * data,unsigned long size)364 bool Drm::writeIoctl(unsigned long cmd, void *data,
365                        unsigned long size)
366 {
367     int err;
368 
369     if (mDrmFd <= 0) {
370         ELOGTRACE("drm is not initialized");
371         return false;
372     }
373 
374     if (!data || !size) {
375         ELOGTRACE("invalid parameters");
376         return false;
377     }
378 
379     err = drmCommandWrite(mDrmFd, cmd, data, size);
380     if (err) {
381         WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
382         return false;
383     }
384 
385     return true;
386 }
387 
388 
readIoctl(unsigned long cmd,void * data,unsigned long size)389 bool Drm::readIoctl(unsigned long cmd, void *data,
390                        unsigned long size)
391 {
392     int err;
393 
394     if (mDrmFd <= 0) {
395         ELOGTRACE("drm is not initialized");
396         return false;
397     }
398 
399     if (!data || !size) {
400         ELOGTRACE("invalid parameters");
401         return false;
402     }
403 
404     err = drmCommandRead(mDrmFd, cmd, data, size);
405     if (err) {
406         WLOGTRACE("failed to call %ld ioctl with failure %d", cmd, err);
407         return false;
408     }
409 
410     return true;
411 }
412 
413 
getDrmFd() const414 int Drm::getDrmFd() const
415 {
416     return mDrmFd;
417 }
418 
getModeInfo(int device,drmModeModeInfo & mode)419 bool Drm::getModeInfo(int device, drmModeModeInfo& mode)
420 {
421     Mutex::Autolock _l(mLock);
422 
423     int outputIndex = getOutputIndex(device);
424     if (outputIndex < 0 ) {
425         return false;
426     }
427 
428     DrmOutput *output= &mOutputs[outputIndex];
429     if (output->connected == false) {
430         ELOGTRACE("device is not connected");
431         return false;
432     }
433 
434     if (output->mode.hdisplay == 0 || output->mode.vdisplay == 0) {
435         ELOGTRACE("invalid width or height");
436         return false;
437     }
438 
439     memcpy(&mode, &output->mode, sizeof(drmModeModeInfo));
440 
441 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
442     // FIXME: use default fb size instead of hdmi mode, because to
443     // support hdmi primary, we cannot report dynamic mode to SF.
444     mode.hdisplay = DEFAULT_DRM_FB_WIDTH;
445     mode.vdisplay = DEFAULT_DRM_FB_HEIGHT;
446 #endif
447 
448     return true;
449 }
450 
getPhysicalSize(int device,uint32_t & width,uint32_t & height)451 bool Drm::getPhysicalSize(int device, uint32_t& width, uint32_t& height)
452 {
453     Mutex::Autolock _l(mLock);
454 
455     int outputIndex = getOutputIndex(device);
456     if (outputIndex < 0 ) {
457         return false;
458     }
459 
460     DrmOutput *output= &mOutputs[outputIndex];
461     if (output->connected == false) {
462         ELOGTRACE("device is not connected");
463         return false;
464     }
465 
466     width = output->connector->mmWidth;
467     height = output->connector->mmHeight;
468     return true;
469 }
470 
getDisplayResolution(int device,uint32_t & width,uint32_t & height)471 bool Drm::getDisplayResolution(int device, uint32_t& width, uint32_t& height)
472 {
473     Mutex::Autolock _l(mLock);
474 
475     int outputIndex = getOutputIndex(device);
476     if (outputIndex < 0) {
477         return false;
478     }
479 
480     DrmOutput *output= &mOutputs[outputIndex];
481     if (output->connected == false) {
482         ELOGTRACE("device is not connected");
483         return false;
484     }
485 
486     width = output->mode.hdisplay;
487     height = output->mode.vdisplay;
488 
489     if (!width || !height) {
490         ELOGTRACE("invalid width or height");
491         return false;
492     }
493     return true;
494 }
495 
isConnected(int device)496 bool Drm::isConnected(int device)
497 {
498     Mutex::Autolock _l(mLock);
499 
500     int output = getOutputIndex(device);
501     if (output < 0 ) {
502         return false;
503     }
504 
505     return mOutputs[output].connected;
506 }
507 
setDpmsMode(int device,int mode)508 bool Drm::setDpmsMode(int device, int mode)
509 {
510     Mutex::Autolock _l(mLock);
511 
512 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
513     device = IDisplayDevice::DEVICE_EXTERNAL;
514 #endif
515 
516     int output = getOutputIndex(device);
517     if (output < 0 ) {
518         return false;
519     }
520 
521     if (mode != IDisplayDevice::DEVICE_DISPLAY_OFF &&
522             mode != IDisplayDevice::DEVICE_DISPLAY_STANDBY &&
523             mode != IDisplayDevice::DEVICE_DISPLAY_ON) {
524         ELOGTRACE("invalid mode %d", mode);
525         return false;
526     }
527 
528     DrmOutput *out = &mOutputs[output];
529     if (!out->connected) {
530         ELOGTRACE("device is not connected");
531         return false;
532     }
533 
534     drmModePropertyPtr props;
535     for (int i = 0; i < out->connector->count_props; i++) {
536         props = drmModeGetProperty(mDrmFd, out->connector->props[i]);
537         if (!props) {
538             continue;
539         }
540 
541         if (strcmp(props->name, "DPMS") == 0) {
542             int ret = drmModeConnectorSetProperty(
543                 mDrmFd,
544                 out->connector->connector_id,
545                 props->prop_id,
546                 (mode == IDisplayDevice::DEVICE_DISPLAY_ON) ? DRM_MODE_DPMS_ON :
547                         IDisplayDevice::DEVICE_DISPLAY_STANDBY == mode ?
548                         DRM_MODE_DPMS_STANDBY : DRM_MODE_DPMS_OFF);
549             drmModeFreeProperty(props);
550             if (ret != 0) {
551                 ELOGTRACE("unable to set DPMS %d", mode);
552                 return false;
553             } else {
554                 return true;
555             }
556         }
557         drmModeFreeProperty(props);
558     }
559     return false;
560 }
561 
resetOutput(int index)562 void Drm::resetOutput(int index)
563 {
564     DrmOutput *output = &mOutputs[index];
565 
566     output->connected = false;
567     memset(&output->mode, 0, sizeof(drmModeModeInfo));
568 
569     if (output->connector) {
570         drmModeFreeConnector(output->connector);
571         output->connector = 0;
572     }
573     if (output->encoder) {
574         drmModeFreeEncoder(output->encoder);
575         output->encoder = 0;
576     }
577     if (output->crtc) {
578         drmModeFreeCrtc(output->crtc);
579         output->crtc = 0;
580     }
581     if (output->fbId) {
582         drmModeRmFB(mDrmFd, output->fbId);
583         output->fbId = 0;
584     }
585     if (output->fbHandle) {
586         Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(output->fbHandle);
587         output->fbHandle = 0;
588     }
589 }
590 
initDrmMode(int outputIndex)591 bool Drm::initDrmMode(int outputIndex)
592 {
593     DrmOutput *output= &mOutputs[outputIndex];
594     if (output->connector->count_modes <= 0) {
595         ELOGTRACE("invalid count of modes");
596         return false;
597     }
598 
599     drmModeModeInfoPtr mode;
600     int index = 0;
601     for (int i = 0; i < output->connector->count_modes; i++) {
602         mode = &output->connector->modes[i];
603         if (mode->type & DRM_MODE_TYPE_PREFERRED) {
604             index = i;
605             break;
606         }
607     }
608 
609     return setDrmMode(outputIndex, &output->connector->modes[index]);
610 }
611 
setDrmMode(int index,drmModeModeInfoPtr mode)612 bool Drm::setDrmMode(int index, drmModeModeInfoPtr mode)
613 {
614     DrmOutput *output = &mOutputs[index];
615 
616     int oldFbId = 0;
617     int oldFbHandle = 0;
618     // reuse current frame buffer if there is no resolution change
619     int fbId = -1;
620 
621     drmModeModeInfo currentMode;
622     memcpy(&currentMode, &output->mode, sizeof(drmModeModeInfo));
623 
624     if (isSameDrmMode(mode, &currentMode))
625         return true;
626 
627     if (currentMode.hdisplay != mode->hdisplay ||
628         currentMode.vdisplay != mode->vdisplay) {
629 
630         oldFbId = output->fbId;
631         oldFbHandle = output->fbHandle;
632 
633         // allocate frame buffer
634         int stride = 0;
635 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
636         output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer(
637             DEFAULT_DRM_FB_WIDTH, DEFAULT_DRM_FB_HEIGHT, &stride);
638 #else
639         output->fbHandle = Hwcomposer::getInstance().getBufferManager()->allocFrameBuffer(
640             mode->hdisplay, mode->vdisplay, &stride);
641 #endif
642         if (output->fbHandle == 0) {
643             ELOGTRACE("failed to allocate frame buffer");
644             return false;
645         }
646 
647         int ret = 0;
648         ret = drmModeAddFB(
649             mDrmFd,
650 #ifdef INTEL_SUPPORT_HDMI_PRIMARY
651             DEFAULT_DRM_FB_WIDTH,
652             DEFAULT_DRM_FB_HEIGHT,
653 #else
654             mode->hdisplay,
655             mode->vdisplay,
656 #endif
657             DrmConfig::getFrameBufferDepth(),
658             DrmConfig::getFrameBufferBpp(),
659             stride,
660             output->fbHandle,
661             &output->fbId);
662         if (ret != 0) {
663             ELOGTRACE("drmModeAddFB failed, error: %d", ret);
664             return false;
665         }
666         fbId = output->fbId;
667     }
668 
669     ILOGTRACE("mode set: %dx%d@%dHz", mode->hdisplay, mode->vdisplay, mode->vrefresh);
670 
671     int ret = drmModeSetCrtc(mDrmFd, output->crtc->crtc_id, fbId, 0, 0,
672                    &output->connector->connector_id, 1, mode);
673 
674     if (ret == 0) {
675         //save mode
676         memcpy(&output->mode, mode, sizeof(drmModeModeInfo));
677     } else {
678         ELOGTRACE("drmModeSetCrtc failed. error: %d", ret);
679     }
680 
681     if (oldFbId) {
682         drmModeRmFB(mDrmFd, oldFbId);
683     }
684 
685     if (oldFbHandle) {
686         Hwcomposer::getInstance().getBufferManager()->freeFrameBuffer(oldFbHandle);
687     }
688 
689     return ret == 0;
690 }
691 
getOutputIndex(int device)692 int Drm::getOutputIndex(int device)
693 {
694     switch (device) {
695     case IDisplayDevice::DEVICE_PRIMARY:
696         return OUTPUT_PRIMARY;
697     case IDisplayDevice::DEVICE_EXTERNAL:
698         return OUTPUT_EXTERNAL;
699     default:
700         ELOGTRACE("invalid display device");
701         break;
702     }
703 
704     return -1;
705 }
706 
getPanelOrientation(int device)707 int Drm::getPanelOrientation(int device)
708 {
709     int outputIndex = getOutputIndex(device);
710     if (outputIndex < 0) {
711         ELOGTRACE("invalid device");
712         return PANEL_ORIENTATION_0;
713     }
714 
715     DrmOutput *output= &mOutputs[outputIndex];
716     if (output->connected == false) {
717         ELOGTRACE("device is not connected");
718         return PANEL_ORIENTATION_0;
719     }
720 
721     return output->panelOrientation;
722 }
723 
724 // HWC 1.4 requires that we return all of the compatible configs in getDisplayConfigs
725 // this is needed so getActiveConfig/setActiveConfig work correctly.  It is up to the
726 // user space to decide what speed to send.
detectAllConfigs(int device,int * modeCount)727 drmModeModeInfoPtr Drm::detectAllConfigs(int device, int *modeCount)
728 {
729     RETURN_NULL_IF_NOT_INIT();
730     Mutex::Autolock _l(mLock);
731 
732     if (modeCount != NULL)
733         *modeCount = 0;
734     else
735         return NULL;
736 
737     int outputIndex = getOutputIndex(device);
738     if (outputIndex < 0) {
739         ELOGTRACE("invalid device");
740         return NULL;
741     }
742 
743     DrmOutput *output= &mOutputs[outputIndex];
744     if (!output->connected) {
745         ELOGTRACE("device is not connected");
746         return NULL;
747     }
748 
749     if (output->connector->count_modes <= 0) {
750         ELOGTRACE("invalid count of modes");
751         return NULL;
752     }
753 
754     *modeCount = output->connector->count_modes;
755     return output->connector->modes;
756 }
757 
758 } // namespace intel
759 } // namespace android
760 
761