Chromium插件(Plugin)机制简要介绍和学习计划

发表于 5年以前  | 总阅读数:3060 次

在Chromium中,除了可以使用Extension增强浏览器功能,还可以使用Plugin。两者最大区别是前者用JS开发,后者用C/C++开发。这意味着Plugin以Native Code运行,在性能上要优于Extension,适合执行计算密集型工作。不过,以Native Code运行,使得Plugin在安全上面临更大挑战。本文接下来对Chromium的Plugin机制进行简要介绍和制定学习计划。

Chromium最初支持两种类型的Plugin:NPAPI Plugin和PPAPI Plugin。NPAPI的全称是Netscape Plugin Application Programming Interface,PPAPI的全称是Pepper Plugin Application Programming Interface。从表面上看,两者的区别在于使用了不同的API规范。其中,NPAPI来自于Mozilla,而PPAPI来自于Google。但实际上,PPAPI与另外一种称为Native Client(NaCl)的技术是紧密联系在一起的。

Native Client是一个由编译工具链(Toolchain)和运行时(Runtime)组成的集合。Toolchain包含在NaCl SDK中。此外,NaCl SDK还提供了PPAPI接口。也就是,通过NaCl SDK,我们可以开发PPAPI Plugin。这些PPAPI Plugin要使用NaCl SDK提供的Toolchain进行编译。Toolchain使用了修改过的GCC对PPAPI Plugin进行编译。这个修改过的GCC为PPAPI Plugin生成的每一条跳转指令的目标地址都是32位对齐的,并且PPAPI Plugin的第一条指令的地址也是32位对齐的。对齐的目的是出于安全考虑,防止恶意代码跳转到任意地址执行指令。同时,有些被认为是危险的指令是禁止使用的,例如ret指令。

除此之外,这个修改过的GCC还会设置一个系统API白名单。在这个白名单里面的系统API,被认为是安全的,也就是对系统不会造成威胁和破坏,它们可以被PPAPI Plugin调用。不在这个白名单内的系统API,将会被禁止调用。这意味着,我们在开发PPAPI Plugin的时候,只可以使用由Chromium提供的PPAPI,以及位于白名单内的系统API。

对PPAPI Plugin的CPU指令以及API调用进行限制,目的都是为了安全。这些安全理论基础可以参考Native Client: A Sandbox for Portable, Untrusted x86 Native CodeGoogle Native Client: Analysis Of A Secure Browser Plugin Sandbox这两个PDF文档,我们在这里就不展开来讲了。

单单靠Toolchain对PPAPI Plugin的CPU指令以及API调用进行限制是不足够的,因为黑客可以对编译后的PPAPI Plugin进行修改。因此,就需要有一套Runtime,在PPAPI Plugin加载时进行验证。这套Runtime由一个NaCl PPAPI Plugin和一个Service Runtime组成,如图1所示:

图1 NaCl Architecture

NaCl PPAPI Plugin是一个内置在Chromium中的PPAPI Plugin,它属于一个Trusted Plugin,运行在Render进程中。Chromium还内置了一个PPAPI Flash,它同样也是一个Trusted Plugin,运行在Render进程中。此外,负责解析网页的WebKit,以及运行网页中的JS的V8引擎,也是运行在Render进程中的。

注意,内置的PPAPI Plugin不需要使用NaCl技术,因为它们是Trusted Code。为了区分使用了NaCl技术的PPAPI Plugin和内置的PPAPI Plugin,我们将前者称为NaCl Module。NaCl Module是Untrusted Code,它们以两种形式存在:Portable Executable(PEXE)和Native Executable(NEXE)。PEXE是跨平台的,编译一次,可以在所有平台运行。NEXE是平台相关的,只可以运行在指定的平台。实际上,PEXE在加载之前,会先被翻译成NEXE再加载和执行。

在网页中,可以通过标签使用一个NaCl模块,如下所示:

<embed name="NaCl_module"
      id="hello_world"
      width=200 height=200
      src="hello_world.nmf"
      type="application/x-NaCl" />

其中,src属性指定了一个NaCl Module清单文件。这个清单文件以json格式描述了它由哪些文件组成,如下所示:

{ "files": {
      "libgcc_s.so.1": { "x86-32": { "url": "lib32/libgcc_s.so.1" } },
      "main.nexe": { "x86-32": { "url": "hw.nexe" } },
      "libc.so.3c8d1f2e": { "x86-32": { "url": "lib32/libc.so.3c8d1f2e" } },
      "libpthread.so.3c8d1f2e": { "x86-32": { "url": "lib32/libpthread.so.3c8d1f2e" } } },
      "program": { "x86-32": { "url": "lib32/runnable-ld.so" } }
    }

WebKit会将标签当作是一个Plugin,于是就会请求Chromium加载这个Plugin。Chromium发现要加载的Plugin的MIME Type为"application/x-NaCl",于是就会在当前的Render进程中创建一个NaCl PPAPI Plugin。这个NaCl PPAPI Plugin将会负责去加载真正的NaCl Module,也就是标签的src属性指定的NaCl Module。

NaCl PPAPI Plugin首先会解析要加载的NaCl Module的清单文件,然后通过Chromium提供的PPAPI接口去下载清单文件里面指定的文件。随后,NaCl PPAPI Plugin又会请求Chromium的Browser进程(即图1中的Broker进程)为它创建一个sel_ldr进程。这个sel_ldr进程与Render进程一样,运行在一个同样的Sandbox中。这个Sandbox称为Outer Sandbox。

上述sel_ldr进程启动起来之后,会加载一个Service Runtime。这个Service Runtime会加载真正的NaCl Module。不过,在加载之前,Service Runtime会对NaCl Module的指令及其调用的API进行验证。如果NaCl Module违反规则,那么它就不会被加载。这样就可以解决我们前面提到的NaCl Module使用修改过的GCC编译之后又被Hacked的问题。

Service Runtime作为NaCl技术的一部分,它是Trusted Code。NaCl Module是Untrusted Code。Service Runtime除了负责加载NaCl Module之外,还会为NaCl Module提供一些服务。例如,NaCl Module在调用白名单允许的系统API时,它不是直接调用的,而是要通过Service Runtime进行调用。尽管NaCl Module与Service Runtime在同一个进程中,但是NaCl Module是不可以直接执行Service Runtime的代码的。

当NaCl Module要执行Service Runtime的代码时,需要通过Trampoline和Springboard间接执行。Trampoline和Springboard的作用有点类似x86的调用门(Call Gate),目的就是为了保护Service Runtime的代码不会被随意执行,就像User Space的代码不能随意执行Kernel Space的代码一样。这套保护机制,以及前面提到的对NaCl Module的指令限制和系统API调用限制,称为Inner Sandbox。

NaCl Module是以间接方式调用Chromium提供的PPAPI接口的,表现它要通过NaCl PPAPI Plugin来调用Chromium提供的PPAPI接口。这意味着NaCl Module与NaCl PPAPI Plugin之间需要有一种通信机制。这种通信机制使用的协议称为Simple-RPC(Remote Procedure Call)协议,简称SRPC。SRPC协议建立在Inter-Module Communication(IMC)之上。IMC又是什么呢?实际上就是Unix Socket。总结来说,就是NaCl Module通过Unix Socket请求NaCl PPAPI Plugin为它调用Chromium提供的PPAPI接口。当然,这些远程请求会被NaCl SDK封装为简单的函数调用,这也是SRPC的由来。

从前面的分析就可以知道,一个使用了NaCl技术的PPAPI Plugin在执行时,被限制在两个Sandbox中。一个是Inner Sandbox,另一个是Outer Sandbox。其中,Inner Sandbox施加了强有力的保护。即使这层强有力的保护被突破,还有Outer Sandbox继续保护着。这样就可以很大程度上保证系统的安全。与此相反的是,NPAPI Plugin缺乏Inner Sandbox这样强有力的保护,就会很容易出现安全问题。同样,IE浏览器的ActiveX Plugin,也面临着NPAPI Plugin同样的安全问题。

虽然前面我们一直把PPAPI Plugin和NaCl联系在一起,但事实上,PPAPI Plugin也可以完全脱离NaCl而存在,例如,图1所示的内置在Chromium中的NaCl PPAPI Plugin和PPAPI Flash Plugin。Chromium提供了一个PPAPI SDK。通过这个SDK,就可以开发与NaCl技术无关的PPAPI Plugin。不过,这些PPAPI Plugin是不能通过Web Store分发的,只能由用户在本地安装。

接下来,基于越简单越容易理解的原则,我们将忽略掉NaCl技术,分析Chromium的PPAPI Plugin机制,并且假设它们是运行在独立的Plugin进程中的,就如我们在前面Chromium的Plugin进程启动过程分析一文所述的。

从前面Chromium的Plugin进程启动过程分析一文可以知道,WebKit在解析网页时碰到标签时,就会请求Browser进程启动一个Plugin进程加载该标签描述的Plugin。Plugin进程启动起来之后,会通过Unix Socket分别与Browser进程以及负责加载网页的Render进程建立通信通道,如图2所示:

图2 Plugin进程、Render进程和Browser进程的关系

Plugin进程启动之后,主要涉及到的是它与Render进程之间的通信。首先,Render进程会请求Plugin进程加载指定的Plugin Module。Plugin Module加载完成之后,Render进程再请求Plugin进程创建Plugin Instance。Plugin Instance创建出来之后,就会进入运行状态。在运行的过程中,它会不断地通过Chromium提供的PPAPI接口请求Render进程执行相应的操作,从而完成自身的功能。

要理解Chromium的Plugin机制,重点在于掌握前面我们提到的两个基本概念Plugin Module和Plugin Instance,以及Plugin Instance调用PPAPI接口的过程。为了更好地理解Chromium的Plugin机制,我们结合Chromium在源码中提供的一个GLES2 Example进行说明。

每一个Plugin都对应有一个Module,每一个Module又可以创建多个Instance,如图3所示:

图3 Plugin Module与Plugin Instance的关系

网页中的每一个标签在Render进程中都对应有一个PepperPluginInstanceImpl对象。这些PepperPluginInstanceImpl对象在Plugin进程中又都会有一个对应的pp::Instance对象。这些PepperPluginInstanceImpl对象和pp::Instance对象就是用来描述Plugin Instance的。

当PepperPluginInstanceImpl与pp::Instance需要通信时,就会通过图2所示的Unix Socket相互发送IPC消息。这些IPC消息的发送与接收在Render进程一侧由一个HostDispatcher负责,而在Plugin进程一侧由一个PluginDispatcher负责。

具有相同src值的标签对应的Plugin Instance属于同一个Plugin Module。Render进程为标签创建Plugin Instance时,首先会检查要创建的Plugin Instance所对应的Plugin Module是否已经加载。如果还没有加载,那么就会按照图4所示的流程进行加载:

图4 Plugin Module的加载流程

标签创建Plugin Instance的请求是由WebKit发起的。这个请求会交给Content层处理。Content层检测到要创建的Plugin Instance对应的Plugin Module还没有加载时,就会创建一个Out-of-Process Plugin Module。这里我们假设标签描述的Plugin是一个非内置Plugin,因此需要为它创建一个Out-of-Process Plugin Module。

Content层在创建Out-of-Process Plugin Module的过程中,会请求Browser进程创建一个Plugin进程,并且请求在该Plugin进程中加载Plugin Module。Plugin Module实际上就是一个SO文件。这个SO文件加载完成后,Plugin进程会调用由它导出的一个函数PPP_InitializeModule,用来对刚刚加载的Plugin Module进行初始化。

其中的一个初始化操作就是创建一个pp::Module对象。每一个Plugin都要在自己的Module文件中自定义一个pp::Module类。例如,GLES2 Example自定义的pp::Module类为GLES2DemoModule,如下所示:

// This object is the global object representing this plugin library as long
    // as it is loaded.
    class GLES2DemoModule : public pp::Module {
     public:
      GLES2DemoModule() : pp::Module() {}
      virtual ~GLES2DemoModule() {}

      virtual pp::Instance* CreateInstance(PP_Instance instance) {
        return new GLES2DemoInstance(instance, this);
      }
    };

这个类定义在文件external/chromium_org/ppapi/examples/gles2/gles2.cc中。

同时,每一个Plugin还必须要在自己的Module文件中定义一个函数CreateModule。这个函数就是用来创建自定义的pp::Module对象的。例如,GLES2 Example定义的函数CreateModule的实现如下所示:

namespace pp {
    // Factory function for your specialization of the Module object.
    Module* CreateModule() {
      return new GLES2DemoModule();
    }
    }  // namespace pp

这个函数定义在文件external/chromium_org/ppapi/examples/gles2/gles2.cc中。

有了这个自定义的pp::Module对象之后,以后就可以调用它的成员函数CreateInstance创建Plugin Instance了。GLES2 Example用GLES2DemoInstance类来描述Plugin Instance。这个GLES2DemoInstance类必须要继承于pp::Instance类,它的定义如下所示:

class GLES2DemoInstance : public pp::Instance,
                              public pp::Graphics3DClient {

     public:
      GLES2DemoInstance(PP_Instance instance, pp::Module* module);
      virtual ~GLES2DemoInstance();

      ......
    };

这个类定义在文件external/chromium_org/ppapi/examples/gles2/gles2.cc中。

Plugin Module的其它初始化工作还包括初始化一系列的PPAPI接口。这些PPAPI接口可以被自定义的pp::Instance调用。

回到Render进程中,当Plugin Module加载完成后,Render进程就会基于刚刚加载的Plugin Module创建一个Plugin Instance,也就是一个PepperPluginInstanceImpl对象。这个PepperPluginInstanceImpl对象接下来会被初始化。在初始化的过程中,它会请求Plugin进程创建一个对应的pp::Instance对象,如图5所示:

图5 Plugin Instance的创建过程

Render进程存在一个PPP_INSTANCE_INTERFACE_1_1接口,PepperPluginInstanceImpl对象会通过该接口请求Plugin进程创建一个对应的pp::Instance对象。

PPP_INSTANCE_INTERFACE_1_1接口定义了一个DidCreate操作。执行该操作的时候,Render进程就会向Plugin进程发送一个类型PpapiMsg_PPPInstance_DidCreate的IPC消息。该IPC消息携带了一个API_ID_PPP_INSTANCE参数,表示需要将它分发给一个PPP_Instance_Proxy对象处理。

Plugin进程也存在一个PPP_INSTANCE_INTERFACE_1_1接口。PPP_Instance_Proxy对象接收到类型PpapiMsg_PPPInstance_DidCreate的IPC消息时,就会执行该接口的DidCreate操作。这个操作在执行的过程中,就会调用前面在加载Plugin Module时创建的自定义pp::Module对象的成员函数CreateInstance,结果就会获得一个自定义的pp::Instance对象。

从前面的分析可以知道,对于GLES2 Example来说,它自定义的pp::Instance对象是一个GLES2DemoInstance对象。这个GLES2DemoInstance对象会通过Chromium提供的OpenGL ES 2.0 PPAPI接口为标签上绘制内容。

Plugin进程在加载Module的时候,会初始化一个PPB_OPENGLES_INTERFACE接口。该接口描述的就是一个OpenGL ES 2.0 PPAPI接口,它定义了一系列的OpenGL操作。每一个操作都对应一个OpenGL函数,如图6所示:

图6 OpenGL ES 2.0 PPAPI接口的调用过程

这些OpenGL操作又是通过调用GLES2Implementation类的同名成员函数实现的。例如,PPB_OPENGLES_INTERFACE接口定义的ActiveTexture操作,是通过调用GLES2Implementation类的成员函数ActiveTexture实现的。

从前面Chromium硬件加速渲染的OpenGL命令执行过程分析一文可以知道,GLES2Implementation类描述的是一个Comand Buffer OpenGL接口,它的成员函数被调用的时候,实际上只是将要执行的OpenGL命令写入到一个Command Buffer中去,然后通知GPU进程执行该Command Buffer中的OpenGL命令。

不过,图6所示的GLES2Implementation对象并不是将Command Buffer的OpenGL命令直接传递给GPU进程执行的,而通过一个PpapCommandBufferProxy对象传递给Render进程中的一个CommandBufferProxyImpl对象处理。这个CommandBufferProxyImpl对象又会将传递给它的OpenGL命令写入到自己的Command Buffer中去,然后再通知GPU进程中的一个GpuCommandBufferStub对象执行该Command Buffer中的OpenGL命令。

由此可见,Plugin通过PPB_OPENGLES_INTERFACE接口执行OpenGL命令时,要执行的OpenGL命令会先传递给Render进程,Render进程再传递给GPU进程执行。为什么Plugin不直接将OpenGL命令传递给GPU进程执行呢?这是因为Plugin在运行的过程中,只能够与Render进程交互。因此,当它需要请求其它进程执行某一个操作时,就需要通过Render进程间接执行。

Plugin在执行OpenGL命令之前,首先要初始化一个OpenGL环境。这个初始化操作发生在Plugin对应的标签的视图创建完成时。这时候标签在Render进程中对应的PepperPluginInstanceImpl对象就会通过PPP_INSTANCE_INTERFACE_1_1接口向它在Plugin进程中对应的pp::Instance对象发出通知,如图7所示:

图7 Plugin初始化OpenGL环境的过程

PPP_INSTANCE_INTERFACE_1_1接口定义了一个DidChangeView操作。当标签的视图第一次创建或者以后大小发生变化时,该操作都会被执行。在执行的时候,它会向Plugin进程发送一个类型为PpapiMsg_PPPInstance_DidChangeView的IPC消息。这个IPC消息携带了一个APP_ID_PPP_INSTANCE参数,表示需要将它分发给一个PPP_Instance_Proxy对象处理。

前面提到,Plugin进程也存在一个PPP_INSTANCE_INTERFACE_1_1接口。PPP_Instance_Proxy对象接收到类型PpapiMsg_PPPInstance_DidChangeView的IPC消息时,就会执行该接口的DidChangeView操作。这个操作在执行的过程中,又会找到之前加载Plugin Instance时创建的一个自定义pp::Instance对象,并且调用它的成员函数DidChangeView,用来通知它标签的视图大小发生了变化。

在GLES2 Example中,自定义的pp::Instance对象是一个GLES2DemoInstance对象。当这个GLES2DemoInstance对象的成员函数DidChangeView第一次被调用的时候,会做两件事情。第一件事情是创建一个Graphics3D对象。这个Graphics3D对象在Plugin进程中用来描述一个OpenGL环境。第二件事情是将前面创建的OpenGL环境与当前正在处理的Plugin进行绑定。这两件事情完成之后,一个Plugin的OpenGL环境就创建和初始化完成了。

Plugin的OpenGL环境的创建过程如图8所示:

图8 Plugin的OpenGL环境的创建过程

Plugin进程存在一个PPB_GRAPHICS_3D_INTERFACE_1_0接口。PPB_GRAPHICS_3D_INTERFACE_1_0接口定义了一个Create操作。在Plugin进程中创建OpenGL环境,也就是一个Graphics3D对象的时候,上述的Create操作会被执行。在执行的过程中,它会通过一个APP_ID_RESOURCE_CREATION参数找到一个ResourceCreationProxy对象,然后再通过这个ResourceCreationProxy对象向Render进程发送一个类型为PpapiHostMsg_PPBGraphics3D_Create的IPC消息。这个IPC消息携带了一个APP_ID_PPB_GRAPHICS_3D参数,表示要将它分发给一个PPB_Graphics3D_Proxy对象处理。

PPB_Graphics3D_Proxy对象在处理类型为PpapiHostMsg_PPBGraphics3D_Create的IPC消息时,会创建一个PPB_Graphics3D_Impl对象。这个PPB_Graphics3D_Impl对象在创建的过程中,会与GPU进程建立一个GPU通道。这个GPU通道建立起来之后,就会在GPU进程中获得一个OpenGL环境。这个OpenGL环境就是用来执行Plugin发出的OpenGL命令的。Render进程与GPU进程建立GPU通道的过程,可以参考前面Chromium硬件加速渲染的OpenGL上下文创建过程分析一文。

给Plugin绑定OpenGL环境的过程如图9所示:

图9 Plugin绑定OpenGL环境的过程

Plugin进程存在一个PPB_INSTANCE_INTERFACE_1_1接口。PPP_INSTANCE_INTERFACE_1_1接口定义了一个BindGraphics操作。该操作在执行的时候,会通过一个APP_ID_PPB_INSTANCE参数找到一个PPB_Instance_Proxy对象,然后再通过这个PPB_Instance_Proxy对象向Render进程发送一个类型为PpapiHostMsg_PPBInstance_BindGraphics的IPC消息。这个IPC消息携带了一个APP_ID_PPB_INSTANCE参数,表示要将它分发给一个PPB_Instance_Proxy对象处理。

PPB_Instance_Proxy对象在处理类型为PpapiHostMsg_PPBInstance_BindGraphics的IPC消息,会找到要绑定OpenGL环境的Plugin Instance,也就是一个PepperPluginInstanceImpl对象,然后调用这个PepperPluginInstanceImpl对象的成员函数BindToInstance,将其绑定到指定的OpenGL环境中去,也就是与前面创建的一个PPB_Graphics3D_Impl对象建立关联。

这样,我们就介绍完了Chromium的Plugin机制。由于Chromium已不再支持NPAPI Plugin,这里我们说的Plugin,指的是PPAPI Plugin,也称为Pepper Plugin。Pepper Plugin可以通过NaCl SDK开发,也可以通过PPAPI SDK开发。通过NaCl SDK开发的Pepper Plugin在NaCl环境中运行,受到两个Sandbox保护,因此它的安全性是非常高的。在Web Store中分发的Pepper Plugin必须要通过NaCl SDK开发,以及运行在NaCl环境中。内置的Pepper Plugin,或者仅仅在本地安装的Pepper Plugin,可以不运行在NaCl环境中,因此它们可以通过PPAPI SDK进行开发。

不管是否运行在NaCl环境中,Pepper Plugin使用Chromium提供的PPAPI接口的方式都是一样的。换句话说,就是NaCl环境对Pepper Plugin来说是透明的。为了简单起见,在接下来的文章中,我们假设Pepper Plugin是基于PPAPI SDK开发的,也就是它没有运行在NaCl环境中。

接下来,我们将结合文中提到的GLES2 Example,按照以下三个情景,对Chromium的Pepper Plugin机制进行更详细的分析:

1. Plugin Module的加载过程

2. Plugin Instance的创建过程

3. Pugin Instance的3D渲染过程

其中,前面两个情景有助于我们理清Plugin Module与Plugin Instance的关系,第三个情景有助于我们理解Plugin调用PPAPI接口的过程,也就是Plugin与浏览器的交互过程。理解了这三个情景之后,我们就可以深刻理解Chromium的Pepper Plugin机制了。敬请关注!更多的信息也可以关注老罗的新浪微博:http://weibo.com/shengyangluo

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 目录