精华内容
参与话题
问答
  • WinXW_android

    千次阅读 2013-09-24 18:38:16
    1.关机充电图标不显示: 现象:开机后,插入充电器,再按正常流程关机。 关机后,短按power键,屏幕无充电图标显示(此时充电器还是插入的)。 解决方法:配置 [pmu_para] power_start = 0 即可 ...


    1.关机充电图标不显示:

    现象:开机后,插入充电器,再按正常流程关机。 关机后,短按power键,屏幕无充电图标显示(此时充电器还是插入的)。

    解决方法:配置 [pmu_para] power_start = 0 即可


    2.设置-语言与输入法-Japanese IME,点击学习词典初始化报错;

    现象及解决方法:

    正常情况,需要选择默认输入法为Japanese IME后才可以清空词典。 case OpenWnnEvent.INITIALIZE_LEARNING_DICTIONARY: mConverterEN.initializeDictionary(WnnEngine.DICTIONARY_TYPE_LEARN); mConverterJAJP.initializeDictionary(WnnEngine.DICTIONARY_TYPE_LEARN); return true; 这里在按了“学习词典初始化”菜单后会调用到以上代码,而此时mConverterEN和mConverterJAJP未被初始化,为null,只有在选择了默认输入法为Japanese IME后,相关的onCreate函数被调用才会new这两个对象以及生成相应的词典文件。


    3.data分区扩到4G 恢复出厂设置就没作用了

    解决方法:

    diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c
    old mode 100644
    new mode 100755
    index 10b672a..469ce7c
    --- a/drivers/mtd/nand/sunxi_nand.c
    +++ b/drivers/mtd/nand/sunxi_nand.c
    @ -38,7 +38,7 @ int sunxi_nand_read_opts(nand_info_t *nand, uint offset, size_t *length,
    unsigned int nSectNum,  nSectorCnt;
    - nSectNum = (unsigned int)(offset / 512);
    + nSectNum = (unsigned int)(offset );
    nSectorCnt = (unsigned int)(*length / 512);
    #ifdef DEBUG
    printf("sunxi nand read: start sector %x counts %x ", nSectNum, nSectorCnt);
    @ -51,7 +51,7 @ int sunxi_nand_write_opts(nand_info_t *nand, uint offset, size_t *length,
    unsigned int nSectNum,  nSectorCnt;
    - nSectNum = (unsigned int)(offset / 512);
    + nSectNum = (unsigned int)(offset);
    nSectorCnt = (unsigned int)(*length / 512);
    #ifdef DEBUG
    printf("sunxi nand write: start sector %x counts %x ", nSectNum, nSectorCnt);
    diff --git a/drivers/storage_type/sunxi_flash.c b/drivers/storage_type/sunxi_flash.c
    index c78c392..2c9cf17 100755
    --- a/drivers/storage_type/sunxi_flash.c
    +++ b/drivers/storage_type/sunxi_flash.c
    @ -66,7 +66,7 @ sunxi_flash_nand_read(unsigned int start_block, unsigned int nblock, void *buffe
    tick_printf(FILE, LINE);
            nsize = nblock<<9;
    -       ret = sunxi_nand_read_opts(&nand_info[0], start_block<<9, &nsize, buffer, 0);
    +       ret = sunxi_nand_read_opts(&nand_info[0], start_block, &nsize, buffer, 0);
            tick_printf(FILE, LINE);
    return ret;
    @ -77,7 +77,7 @ sunxi_flash_nand_write(unsigned int start_block, unsigned int nblock, void *buff
            unsigned int nsize;
    nsize = nblock<<9;
    -       return sunxi_nand_write_opts(&nand_info[0], start_block<<9, &nsize, buffer, 0);
    +       return sunxi_nand_write_opts(&nand_info[0], start_block, &nsize, buffer, 0);
     }
    修改后ok。

    4.支持多用户功能

    <integer name="config_multiuserMaximumUsers">8</integer>


    5.在首次开机时默认将Play商店停用:

    修改:packages\apps\Provision,在这里将vending应用停用
    try{

            PackageManager pm = getPackageManager();
    try {
    pm.setApplicationEnabledSetting("com.android.vending", PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);
    } catch(Exception e) {
    android.util.Log.i("chen", "change fail");
    }
            PackageManager pm = getPackageManager();
    try {
    pm.setApplicationEnabledSetting("com.android.vending", PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);
    } catch(Exception e) {
    android.util.Log.i("chen", "change fail");
    }
            PackageManager pm = getPackageManager();
    try {
    pm.setApplicationEnabledSetting("com.android.vending", PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);
    } catch(Exception e) {
    android.util.Log.i("chen", "change fail");
    }
    pm.setApplicationEnabledSetting("com.android.vending", PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0);}catch(...){}
    并在Provision应用的AndroidManifest.xml中增加权限
    <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />


    6. 4.1 在播放视频时,视频切换会出现花屏:

    在 device\softwinner\common\hardware\libhardware\hwcomposer\hwcomposer.cpp  里

    static int hwc_show(sun4i_hwc_context_t *ctx,uint32_t value)
    {
    unsigned long               args[4]={0};
        unsigned int                screen_idx;
        int ret = 0;
     
          for(screen_idx=0; screen_idx<2; screen_idx++)
          {
              if(((screen_idx == 0) && (ctx->mode==HWC_MODE_SCREEN0 || ctx->mode==HWC_MODE_SCREEN0_AND_SCREEN1 ))
                  || ((screen_idx == 1) && (ctx->mode == HWC_MODE_SCREEN1 || ctx->mode==HWC_MODE_SCREEN0_TO_SCREEN1 || ctx->mode==HWC_MODE_SCREEN0_AND_SCREEN1)))
              {
                  if(ctx->video_layerhdl[screen_idx] != 0)
                  {
                      if(value == 0)
                      {
                          args[0]                         = screen_idx;
                          args[1]                         = ctx->video_layerhdl[screen_idx];
                          ioctl(ctx->dispfd, DISP_CMD_LAYER_CLOSE,args);
     
                          args[0]                         = screen_idx;
                          args[1]                         = ctx->video_layerhdl[screen_idx];
                          ret = ioctl(ctx->dispfd, DISP_CMD_VIDEO_STOP, args);
     
                      }
                      else
                      {
                          args[0]                         = screen_idx;
                          args[1]                         = ctx->video_layerhdl[screen_idx];
                          ioctl(ctx->dispfd, DISP_CMD_LAYER_OPEN,args);
     
                          args[0]                         = screen_idx;
                          args[1]                         = ctx->video_layerhdl[screen_idx];
                          ret = ioctl(ctx->dispfd, DISP_CMD_VIDEO_START, args);
                      }
                  }
              }
          }
     
       return ret;
    }
     
    在 hwc_setparameter 函数加上
    }else if(param == HWC_LAYER_SHOW){
    ret = hwc_show(ctx,value);
    }

    7.添加新的产品编译项:

    以abcd为例
    cp -r crane-m1003h6 crane-abcd
    cd crane-abcd
    grep -r -l "m1003h6" ./* | xargs sed -i 's/m1003h6/abcd/g'
    mv crane_m1003h6.mk crane_abcd.mk

    8.播放Mp3,屏幕暗下去以后,调节音量键无效:

    1. 去掉isScreenOn的判断
    a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
    +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
    @@ -3352,7 +3352,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                 case KeyEvent.KEYCODE_VOLUME_MUTE: {
                     if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                         if (down) {
    -                        if (isScreenOn && !mVolumeDownKeyTriggered
    +                        if (!mVolumeDownKeyTriggered
                                     && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                                 mVolumeDownKeyTriggered = true;
                                 mVolumeDownKeyTime = event.getDownTime();
    @@ -3366,7 +3366,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                         }
                     } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
                         if (down) {
    -                        if (isScreenOn && !mVolumeUpKeyTriggered
    +                        if (!mVolumeUpKeyTriggered
                                     && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                                 mVolumeUpKeyTriggered = true;
                                 cancelPendingPowerKeyAction();

    2. 不让按键进入suspend
    --- a/drivers/input/keyboard/sun4i-keyboard.c
    +++ b/drivers/input/keyboard/sun4i-keyboard.c
    @@ -183,7 +183,7 @@ static void sun4i_keyboard_suspend(struct early_suspend *h)
         
            if (NORMAL_STANDBY == standby_type) {
     
    -               writel(0,KEY_BASSADDRESS + LRADC_CTRL);
    +               //writel(0,KEY_BASSADDRESS + LRADC_CTRL);
            /*process for super standby*/   
            } else if(SUPER_STANDBY == standby_type) {
                    ;
    @@ -466,5 +466,5 @@ MODULE_AUTHOR(" <@>");


    9.Google Play 搜不到某个应用:

    google play搜不到某个应用的分析和解决方法
        搜不到应用是设备缺少该应用所必须的权限,即使安装了也可能出现部分功能不能正常使用的情况。如何让A1X搜到应用,下面以搜索IDTV应用为例:
    1. 先在pc上打开google play搜到IDTV这个应用
    2. 查看这个应用所需要的权限,需要定位,WIFI等
    3. 查看设备所具有的权限etc/permissions/*
    4. 比较找到设备所缺少的权限,例如A10默认缺少IDTV所必须的定位权限。
    5. 将可疑的权限文件push到etc/permissions/下,恢复出厂设置再次测试能否搜到。
    6. 在项目中拷贝所需的权限,例如打开网络定位的功能。
    如果难以定位缺少所需的权限,其他手机可搜索到,比较etc/permissions/*下的内容,反复push,恢复出厂设置后测试。
    所有权限文件路径:frameworks/native/data/etc/*


    10. Google Play 上下载的水果忍者运行出错

    下载的水果忍者带有广告, 会请求定位服务。没有gps,所以要保证有网络定位功能。

    请检查 config_networkLocationProvider 是否为 null

    修改: 
    <string name="config_networkLocationProviderPackageName" translatable="false">com.google.android.location</string>


    11.内存使用状态显示问题:

    现象:在settings->apps->观察internal storage 显示信息(有显示已用空间与可用空间的数值)->点击右边任意一个应用->返回->再观察 internal storage 显示信息(无已用空间与可用空间的数值显示)
    解决方法:
    diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
    --- a/src/com/android/settings/applications/ManageApplications.java
    +++ b/src/com/android/settings/applications/ManageApplications.java
    @@ -855,13 +855,16 @@ public class ManageApplications extends Fragment implements
    mColorBar.setRatios((totalStorage-freeStorage-appStorage)/(float)totalStorage,
    appStorage/(float)totalStorage, freeStorage/(float)totalStorage);
    long usedStorage = totalStorage - freeStorage;
    - if (mLastUsedStorage != usedStorage) {
    +	
    + //if (mLastUsedStorage != usedStorage) {
    + if (true) {
    mLastUsedStorage = usedStorage;
    String sizeStr = Formatter.formatShortFileSize(getActivity(), usedStorage);
    mUsedStorageText.setText(getActivity().getResources().getString(
    R.string.service_foreground_processes, sizeStr));
    }
    - if (mLastFreeStorage != freeStorage) {
    + //if (mLastFreeStorage != freeStorage) {
    + if (true) {
    mLastFreeStorage = freeStorage;
    String sizeStr = Formatter.formatShortFileSize(getActivity(), freeStorage);
    mFreeStorageText.setText(getActivity().getResources().getString(
    

    12.隐藏状态栏:

    如果有应用程序的源码,可以在需要隐藏状态栏的activity中添加android:theme=”@android:style/Theme.NoTitleBar.Fullscreen”
    具体修改应用程序的androidmenifest.xml文件
    <activity android:name="xxx"
                       android:label="@string/app_name"
                       android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >

    如果没有应用的源码,在PhoneWindowManager.java文件 finishAnimationLw函数中,针对特殊的应用判断。已有视频播放的参考代码,参照修改即可。


    13.预装APK过大,升级固件在一定百分比出错

    可以试一下做如下修改
    1:修改 BoardConfig.mk
    BOARD_SYSTEMIMAGE_PARTITION_SIZE 要比预装的总空间大。
     
    2:通过更改devices/softwinner/crane_xx/package.sh如下
    mv out/target/product/crane-evb_mmc/system.img out/target/product/crane-evb_mmc/system.img_old
    simg2img out/target/product/crane-evb_mmc/system.img_old out/target/product/crane-evb_mmc/system.img
    cd $PACKAGE
    ./pack -c sun4i -p crane -b evb_mmc
    cd -

    另见WORKING_NOTE

    14.蓝牙可用设备会显示之前搜索到但已关闭的设备

    蓝牙的缓存管理CachedBluetoothDeviceManager中, 只有添加设备, 没有清除。

    修改如下:
    在CachedBluetoothDeviceManager中添加删除接口
            void removeAllCacheDevices() {
                synchronized(this) {
                    List<CachedBluetoothDevice> mCachedList = mCachedDevices;
                    for (int i = mCachedList.size() - 1; i >= 0; i--) {
                        mCachedList.remove(mCachedList.get(0));
                    }
                }
            }
    在startScanning的地方调用,调用方式
             mLocalManager = LocalBluetoothManager.getInstance(context);
             if (mLocalManager == null) {
                 Log.e(TAG, "Bluetooth is not supported on this device");
                 return;
             }
       mLocalManager.getCachedDeviceManager().removeAllCacheDevices();

    15.修改Launcher显示的列数:

    将Launcher修改为7列, 如下两种方法均可.
    方法1: workspace.xml 文件中, 在 launcher:defaultScreen="2" 的下面增加一行: launcher:cellCountX="7"
    方法2: dimens.xml 文件中, 修改workspace_cell_width的值. 改小, 使屏幕宽度除以这个值大于7.

    16.状态栏的日期格式不随设置的日期格式改变

    修改如下:
    文件: frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\DateView.java
    函数: updateClock
    CharSequence date = DateFormat.getLongDateFormat(context).format(now); // java语言长日期格式
    改为
    CharSequence date = DateFormat.getDateFormat(context).format(now);  // 从设置读取日期格式


    17.超请播放器分享功能相关问题:

    现象:A131.5版本上,客户在美国那边发现在超清播放器里面图片分享的功能,如果只安装了gmail或者email的时候无法使用,但是安装了比如facebooktwitter这些东西之后就可以使用了
    解决方法:
    在 frameworks\base\core\java\android\widget\ActivityChooserView.java
     public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) {  这个函数大概 239 行,
     mAdapter = new ActivityChooserViewAdapter(); 加上
            mAdapter.setShowFooterView(true);

    18.Google Chrome 进Setting 停止运行:

    现象:通过play store下载安装Google Chrome。打开该浏览器,点右上角菜单,选择“Settings”,出现停止运行提示。
    解决方法:
    与尺寸有关,小尺寸有问题.使用的preference_headers.xml不同.
    修改文件 frameworks\base\core\java\android\preference\PreferenceActivity.java
        public Header onGetInitialHeader() {
        // 添加这个for循环
        for (Header h : mHeaders) {
                if (h.fragment != null) {
                    return h;
                }
            }
            return mHeaders.get(0);
        }


    19.升级后首次开机不显示音量图标:

    现象:升级后首次开机需要先待机锁屏再解锁,才能显示音量图标
    解决方法:
    在 TabletStatusBar.java 文件的 makeStatusBarView 函数中,
    mVolumeDownButton = mNavigationArea.findViewById(R.id.volume_down);
    mVolumeUpButton = mNavigationArea.findViewById(R.id.volume_up);
    // 增加下面这个if分支
    if(mContext.getResources().getBoolean(R.bool.hasVolumeButton))
    {
    mVolumeUpButton.setVisibility(View.VISIBLE);
    mVolumeDownButton.setVisibility(View.VISIBLE);
    }

    20、视频实时旋转

    1.frameworks\base\services\surfaceflinger\SurfaceTextureLayer.cpp 中修改一下函数
    uint32_t SurfaceTextureLayer::getParameter(uint32_t cmd) 
    {
        uint32_t res = 0;
        
    /* if(cmd == NATIVE_WINDOW_CMD_GET_SURFACE_TEXTURE_TYPE) {
    return 1;
    }
    */
     
        sp<Layer> layer(mLayer.promote());
        if (layer != NULL) 
        {
            res = layer->getDisplayParameter(cmd);
        }
        
        return res;
    }
     
     
    2.在frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java  中
    rotationForOrientationLw() 函数里 注释掉多余的
    // if(MediaPlayer.isPlayingVideo())
    // {
    // Log.i(TAG, "MediaPlayer.isPlayingVideo");
    // if(SystemProperties.getInt("ro.sf.hwrotation",0)==270)
    // {
    // sensorRotation = Surface.ROTATION_90;
    // }
    // else
    // {
    // sensorRotation = Surface.ROTATION_0;
    // }
    // }
    // else
    // {
    Log.i(TAG, "MediaPlayer.is not PlayingVideo");
    sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
    // }
     
    3.修改 packages\apps\Gallery2\AndroidManifest.xml  修改
            <activity android:name="com.android.gallery3d.app.MovieActivity"
                    android:label="@string/movie_view_label"
    android:configChanges="keyboardHidden|orientation"
                    android:theme="@style/Theme.Movie" >

    21、开启wifi连3G会出现wifi和3G两个图标,退出3G后3G图标不消失

    修改如红色代码所示:


    ./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java


     void refreshViews() {
            Context context = mContext;

            int combinedSignalIconId = 0;
            int combinedActivityIconId = 0;
            String combinedLabel = "";
            String wifiLabel = "";
            String mobileLabel = "";
            int N;

             if (mWifiConnected && !mDataConnected) {
                 mDataSignalIconId = mPhoneSignalIconId = 0;
                mobileLabel = "";
            }
      
          if (!mHasMobileDataFeature) {
                mDataSignalIconId = mPhoneSignalIconId = 0;
                mobileLabel = "";
            } else {




    22.解锁界面应用图标特大:

    frameworks\base\core\java\com\android\internal\widget\multiwaveview\MultiWaveView.java
    把下面代码红色部分注释掉

    public void setTargetResources(ArrayList<Drawable> drawables)
    {
           Resources res = getContext().getResources();
           int count = drawables.size();
      Drawable drawable = null;
           ArrayList<TargetDrawable> targetDrawables = new ArrayList<TargetDrawable>(count);
      if(count > mMaxAppIconNum)
      count = mMaxAppIconNum;
            for (int i = 0; i < count; i++) {
    if(i!=0)
    {
                drawable = zoomDrawable(drawables.get(i),mIconSize,mIconSize);
    }else
    {
       drawable = drawables.get(i);
    }
      public void setTargetResources(ArrayList<Drawable> drawables)
    {
    Resources res = getContext().getResources();
    int count = drawables.size();
    Drawable drawable = null;
     ArrayList<TargetDrawable> targetDrawables = new ArrayList<TargetDrawable>(count);
    if(count > mMaxAppIconNum)
    count = mMaxAppIconNum;
    for (int i = 0; i < count; i++) {
    // if(i!=0)
    // {
    // drawable = zoomDrawable(drawables.get(i),mIconSize,mIconSize);
    // }else
    //
    {
    drawable = drawables.get(i);
    //}
    }


    23.高清播放器图片预览时,不是居中

    修改
     packages\apps\Gallery2\src\com\android\gallery3d\ui\SlideshowView.java  
    public void apply(GLCanvas canvas) {
    //            float centerX = viewWidth / 2 + mMovingVector.x * mProgress;
    //            float centerY = viewHeight / 2 + mMovingVector.y * mProgress;
                
                float centerX = viewWidth / 2 ;
                float centerY = viewHeight / 2 ;
    //            float centerX = viewWidth / 2 + mMovingVector.x * mProgress;
    //            float centerY = viewHeight / 2 + mMovingVector.y * mProgress;
                
                float centerX = viewWidth / 2 ;
                float centerY = viewHeight / 2 ;
    约 152 行
        // float centerX = viewWidth / 2 + mMovingVector.x * mProgress;
       //  float centerY = viewHeight / 2 + mMovingVector.y * mProgress;
      float centerX = viewWidth / 2 ;
      float centerY = viewHeight / 2 ;    

    24.休眠间歇性唤醒:

    现象:在standby时,系统间歇性会被唤醒
    解决方法:

    由于android本身timer机制导致,可以通过如下配置进行优化:

    1.  进入menuconfig

    2.  选择device drivers -> real time clock

    3.  选择android alarm clock wakeup


    25、音乐播放器中,均衡器界面不起作用

    现象:音乐播放器,选择 ‘音效’ ,出现 均衡器 界面,界面上所有操作都不起作用
    解决方法:
    修改
    packages\apps\MusicFX\src\com\android\musicfx\ActivityMusic.java 

    protected void onResume() { 
    中 460 行 
    \\ mIsHeadsetOn = (audioManager.isWiredHeadsetOn() || audioManager.isBluetoothA2dpOn());
     改为 mIsHeadsetOn = true;

     private void updateUI() {
    中 551 行
    /**
    final boolean isEnabled = ControlPanelEffect.getParameterBoolean(mContext,
                    mCallingPackageName, mAudioSession, ControlPanelEffect.Key.global_enabled);
    final boolean isEnabled = ControlPanelEffect.getParameterBoolean(mContext,
                    mCallingPackageName, mAudioSession, ControlPanelEffect.Key.global_enabled);
    final boolean isEnabled = ControlPanelEffect.getParameterBoolean(mContext,
                    mCallingPackageName, mAudioSession, ControlPanelEffect.Key.global_enabled); 
     * final boolean isEnabled = ControlPanelEffect.getParameterBoolean(mContext,
    * mCallingPackageName, mAudioSession, ControlPanelEffect.Key.global_enabled);
    **/
     改为
      final boolean isEnabled = ControlPanelEffect.getParameterBoolean(mContext,
     mCallingPackageName, mAudioSession, 
    ControlPanelEffect.Key.virt_enabled);

    26、修改播放器拖动时的状态条宽度:

    修改
    android4.0\packages\apps\Gallery2\res\layout\media_status.xml

            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
            <SeekBar
                android:id="@+id/mediacontroller_progress"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="0dip"
                android:layout_weight="1"
                android:paddingTop="30dp"
                android:layout_height="60dip" />
    <SeekBar
         android:id="@+id/mediacontroller_progress"
         style="?android:attr/progressBarStyleHorizontal"
         android:layout_width="0dip"
        android:layout_weight="1"
        android:paddingTop="30dp"
        android:layout_height="60dip" 
    />  

    数值根据需要进行调整。

    27、Music播放器无法点击前一首

    修改 android4.0\packages\apps\Music\src\com\android\music\MediaPlaybackActivity.java
     431行 onClick()函数里
     if (mService == null) return;
                try {
                        mService.prev();
                    }
                } catch (RemoteException ex) {
                }

    28、Google拼音输入法,横屏时有些应用没有中文选项:

    现象:google拼音版本1.2版. 在launcher自定义文件夹名称, email输入邮件主题等横屏输入中文时, 不显示中文候选框, 无法输入.
    解决方法:
    在横屏时全屏来输入, 去掉相应布局文件中的 android:imeOptions="flagNoExtractUi".


    29、播放电影字幕与菜单重叠:

    现象:播放外带字幕电影,播放电影且已有字幕出现在屏幕上时触摸屏幕调出子菜单,字幕和菜单重叠,下一条字幕出现时则恢复正常。
    解决方法:
    修改 Gallery2\src\com\android\gallery3d\app\MediaController.java  在initControllerView  函数最后加 mUpSubPos += 10; 即可


    30、卡启动,Nand分区识别:

    现象:卡启动时,如何识别到nand并对其进行操作
    解决方法:

    关于要在卡启动识别到nand,有两种情况:

    1. nand上已经有分区;

    2. nand是裸片;

     第一种情况下卡启动时nand驱动能够初始化成功,用户可以通过mount命令挂载nand的分区;

     第二种情况下要先给nand一个虚拟的mbr,使得启动时nand能够初始化成功,

    可以通过修改nand驱动的源码达到这一目的。

     A10平台修改linux-3.0/drivers/block/sun4i_nand/nfd/mbr.c

    A1X平台修改linux-3.0/drivers/block/sun5i_nand/nfd/mbr.c

    具体改动如下:

    int mbr2disks(struct nand_disk* disk_array)

    {

             int part_cnt = 0;

             int part_index;

    #if 0

             if(_get_mbr()){

                       printk("get mbr error\n" );

                       return part_cnt;

             }

             part_index = 0;

     

             for(part_cnt = 0; part_cnt<MAX_PART_COUNT; part_cnt++)

                       part_secur[part_index] = 0;       

             //查找出所有的LINUX盘符

             for(part_cnt = 0; part_cnt < mbr->PartCount && part_cnt < MAX_PART_COUNT; part_cnt++)

             {

                 //if((mbr->array[part_cnt].user_type == 2) || (mbr->array[part_cnt].user_type == 0))

                 {

                                PRINT("The %d disk name = %s, class name = %s, disk size = %d\n", part_index, mbr->array[part_cnt].name,

                                 mbr->array[part_cnt].classname, mbr->array[part_cnt].lenlo);

                                disk_array[part_index].offset = mbr->array[part_cnt].addrlo;

                                disk_array[part_index].size = mbr->array[part_cnt].lenlo;

                                part_secur[part_index] = mbr->array[part_cnt].user_type;

                                part_index ++;

                 }

             }

             disk_array[part_index - 1].size = DiskSize - mbr->array[mbr->PartCount - 1].addrlo;

             _free_mbr();

             PRINT("The %d disk size = %lu\n", part_index - 1, disk_array[part_index - 1].size);

             PRINT("part total count = %d\n", part_index);

    #else

             part_index = 1;

             disk_array[0].offset = 0;

             disk_array[0].size = DiskSize;

             part_secur[0] = 0;

    #endif

             return part_index;

    }

     

    红色部分为改动的内容,旧版的SDK需要做适当的修改才可通过编译,

    去掉:part_secur[0] = 0;


    31、Android4.0 蓝牙键盘不能用:

    在menuconfig中,打开HIDP protocol support选项为y

    32.让多台机器公用一个下载帐号:

    将授权机器的密钥文件(id_rsa和id_rsa.pub)copy到新机器用户目录下面的.ssh文件夹里,如果没有就新建。

    同时将相关文件的权限进行修改:

    owner  和group 设置成新机器上的用户
    id_rsa文件权限设置成600



    33.高清播放器删除最后一张图片,图片再无法移动:

    改 Gallery2\src\com\android\gallery3d\ui\PhotoView.java 

    public void startSlideInAnimation(int direction) {
    ...
            mTransitionMode = direction; 改成  mTransitionMode = TRANS_NONE;

    }

    34.在系统中去掉蓝牙相关功能:

    现象:小机不带蓝牙功能,但系统自带的widget上有蓝牙选项,该如何去掉?
    解决方法:
    在android4.0\device\softwinner\crane-common\tablet_core_hardware.xml中
    注释掉 <feature name="android.hardware.bluetooth" />

    35.默认竖屏模式下,高清播放器休眠后自动播放视频

    现象:默认竖屏模式下,高清播放器休眠后自动播放视频
    解决方法:
    由于播放器,不支持竖屏模式,所以休眠之后,由于横竖屏切换,导致播放器再次运行 可以适当的延长播放器的暂停时间,以回避这问题。 packages\apps\Gallery2\src\com\android\gallery3d\app\MovieActivity.java
    import android.os.PowerManager; 
    import android.content.Context; 
    import android.os.SystemClock;


    private PowerManager mPowerManager; 
    @Overridepublic void onCreate(Bundle icicle) {         。。。 
    mPowerManager = (PowerManager)getApplicationContext().getSystemService(Context.POWER_SERVICE);
     
    }

    public void onPause() {  if(mPowerManager != null){ if(!mPowerManager.isScreenOn()){ SystemClock.sleep(1000);}}mControl.onPause();super.onPause();}

    36.阿拉伯文下高清播放器不能搜索到.avi 格式的媒体文件

    由于阿拉伯文下 .avi 后缀的视频,后缀名被转码后识别不了,需要修改以下地方。
    frameworks\base\media\java\android\media\MediaFile.java 

        public static MediaFileType getFileType(String path) {
            int lastDot = path.lastIndexOf(".");
            if (lastDot < 0)
                return null;
            return sFileTypeMap.get(path.substring(lastDot + 1).toUpperCase(Locale.ENGLISH));
        }
        public static MediaFileType getFileType(String path) {
            int lastDot = path.lastIndexOf(".");
            if (lastDot < 0)
                return null;
            return sFileTypeMap.get(path.substring(lastDot + 1).toUpperCase(Locale.ENGLISH));
        }
    public static MediaFileType getFileType(String path) {
    int lastDot = path.lastIndexOf(".");
    if (lastDot < 0)
    return null;
     return sFileTypeMap.get(path.substring(lastDot + 1).toUpperCase(Locale.ENGLISH));
    }

    37.字体为超大时,竖屏在解锁界面,解锁的图标显示不全:

    现象:800x600,lcd_denisty 160
    解决方法:
    frameworks/base/core/res/res/layout-sw600dp/keyguard_screen_tab_unlock.xml
    适当加大72行的android:layout_weight="1"
    这样解锁部分的面积会增加,解决这个问题
    其他分辨率需要修改其他layout文件夹下的keyguard_screen_tab_unlock.xml

    38.音效里的Normal和Flat功能反:

    frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.h
    gEqualizerPresets数组,名字可以随意修改

    39.动态壁纸,线性光幕效果有黑块:

    效果:将壁纸设为动态壁纸中的“线性光幕效果”时,在主界面旋转屏幕时未显示完整,即往边上拉存在黑块问题。
    解决方法:

    修改:
    android\packages\wallpapers\Basic\src\com\android\wallpaper\nexus\NexusRS.java

        @Override
        public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
            //mXOffset = xOffset; 
            //mScript.set_gXOffset(xOffset);
        }



    40.修改Setting里面各字体对应的大小:

    现象:感觉setting里面字体大小选择的变化幅度太大,希望小不要太小,特大不要太大,每级变化的幅度缩小点该如何修改
    解决方法:
    android4.0\packages\apps\Settings\res\values\arrays.xml 文件里
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.85</item>
            <item>1.0</item>
            <item>1.15</item>
            <item>1.30</item>
        </string-array>
    默认是0.15的梯度 改成合适的梯度如
        <string-array name="entryvalues_font_size" translatable="false">
            <item>0.90</item>
            <item>1.0</item>
            <item>1.10</item>
            <item>1.20</item>
        </string-array>

    41.浏览器为Android模式时在线看视频卡:

    现象:
    A10
    1:在浏览时有时偶尔会退出
    2:浏览器用android模式,看在线视频十几分钟左右后会卡,但用ipad模式不会卡
    问题分析:
    1。需要具体分析问题,我们其它客户案上浏览正常
    2。android模式采用的flash格式播放,而ipad采用的html5。flash由于自身格式和片源分割的关系,在线视频有机率产生不同步或卡顿问题。该问题由flash自身引起,这也是为何flash会逐渐被html5取代的一个方面。

    42.Android4.0自动弹出USB:

    修改 frameworks\base\packages\SystemUI\src\com\android\systemui\usb\StorageNotification.java
     private void onStorageStateChangedAsync(String path, String oldState, String newState) {        Slog.i(TAG, String.format( private void onStorageStateChangedAsync(String path, String oldState, String newState) {        Slog.i(TAG, String.format( private void onStorageStateChangedAsync(String path, String oldState, String newState) {
    	...
    	//注释掉以下代码
    //            Intent intent = new Intent();//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_stop_notification_title,//                    com.android.internal.R.string.usb_storage_stop_notification_message,//                    com.android.internal.R.drawable.stat_sys_warning, false, true, pi);  //Intent intent = new Intent();
    //            Intent intent = new Intent();//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_stop_notification_title,//                    com.android.internal.R.string.usb_storage_stop_notification_message,//                    com.android.internal.R.drawable.stat_sys_warning, false, true, pi) ;//intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
     //PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
     //setUsbStorageNotification(
     //			com.android.internal.R.string.usb_storage_stop_notification_title,
     //			com.android.internal.R.string.usb_storage_stop_notification_message,
    //			com.android.internal.R.drawable.stat_sys_warning, false, true, pi);
    		...
    }
    
    
    void updateUsbMassStorageNotification(boolean available) {
          StorageManager mStorageManager = null;
    	if (available) 
    	{
    		if(mContext != null)
    		{
    			mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
    		}
    		else
    		{
    			Slog.w(TAG, "mContext is null ,getSystemService error !");
    		}
    
    		//            Intent intent = new Intent();
    		//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);
    		//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    		//            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);
    		//            setUsbStorageNotification(
    		//                    com.android.internal.R.string.usb_storage_notification_title,
    		//                    com.android.internal.R.string.usb_storage_notification_message,
    		//                    com.android.internal.R.drawable.stat_sys_data_usb,
    		//                    false, true, pi);
    
    	 if(mStorageManager != null)
                {
    		mStorageManager.enableUsbMassStorage();
    	  }  
         //            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_notification_title,//                    com.android.internal.R.string.usb_storage_notification_message,//                    com.android.internal.R.drawable.stat_sys_data_usb,//                    false, true, pi);//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_notification_title,//                    com.android.internal.R.string.usb_storage_notification_message,//                    com.android.internal.R.drawable.stat_sys_data_usb,//                    false, true, pi);//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_notification_title,//                    com.android.internal.R.string.usb_storage_notification_message,//                    com.android.internal.R.drawable.stat_sys_data_usb,//                    false, true, pi);//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_notification_title,//                    com.android.internal.R.string.usb_storage_notification_message,//                    com.android.internal.R.drawable.stat_sys_data_usb,//                    false, true, pi);//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_notification_title,//                    com.android.internal.R.string.usb_storage_notification_message,//                    com.android.internal.R.drawable.stat_sys_data_usb,//                    false, true, pi);//            intent.setClass(mContext, com.android.systemui.usb.UsbStorageActivity.class);//            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);            PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0);//            setUsbStorageNotification(//                    com.android.internal.R.string.usb_storage_notification_title,//                    com.android.internal.R.string.usb_storage_notification_message,//                    com.android.internal.R.drawable.stat_sys_data_usb,//                    false, true, pi)
    	}
    else if(!mUmsAvailable || !atLeastOneDeviceMounted())
    	{
                setUsbStorageNotification(0, 0, 0, false, false, null);
                if(mStorageManager != null)
                {
                	mStorageManager.disableUsbMassStorage();
                }
            }
    
    	
    }


    43.电池提示无法获取电池使用数据:

    现象:设置--电池--,里面提示无法获取电池使用数据
    解决方法:
    android4.0 (1.2版本之后,之前没有此功能)
    在device\softwinner\crane-xxx\overlay\frameworks\base\core\res\res\xml  目录下, 增加 power_profile.xml
    power_profile.xml 内容如下
    <?xml version="1.0" encoding="utf-8"?><!--**** Copyright 2009, The Android Open Source Project**** Licensed under the Apache License, Version 2.0 (the "License")** you may not use this file except in compliance with the License.** You may obtain a copy of the License at****     http://www.apache.org/licenses/LICENSE-2.0**** Unless required by applicable law or agreed to in writing, software** distributed under the License is distributed on an "AS IS" BASIS,** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.** See the License for the specific language governing permissions and** limitations under the License.*/-->
    <device name="Android">	<item name="none">0</item>	<item name="screen.on">55</item>	<item name="bluetooth.active">142</item>	<item name="bluetooth.on">1</item>	<item name="bluetooth.at">35690</item>	<item name="screen.full">115</item>	<item name="wifi.on">4</item>	<item name="wifi.active">130</item>	<item name="wifi.scan">104</item>	<item name="dsp.audio">75</item>	<item name="dsp.video">75</item>	<item name="radio.active">300</item>	<item name="gps.on">170</item>	<item name="radio.scanning">70</item>	<array name="radio.on">		<value>3</value>		<value>3</value>	</array>	<array name="cpu.speeds">		<value>1000000</value>		<value>900000</value>		<value>800000</value>		<value>700000</value>		<value>600000</value>		<value>500000</value>		<value>400000</value>		<value>300000</value>		<value>200000</value>		<value>100000</value>	</array>	<item name="cpu.idle">10</item>	<array name="cpu.active">		<value>840</value>		<value>760</value>		<value>680</value>		<value>520</value>		<value>440</value>		<value>360</value>		<value>280</value>		<value>200</value>		<value>120</value>		<value>40</value>	</array>	<item name="battery.capacity">1000</item></device>
    <?xml version="1.0" encoding="utf-8"?><!--**** Copyright 2009, The Android Open Source Project**** Licensed under the Apache License, Version 2.0 (the "License")** you may not use this file except in compliance with the License.** You may obtain a copy of the License at****     http://www.apache.org/licenses/LICENSE-2.0**** Unless required by applicable law or agreed to in writing, software** distributed under the License is distributed on an "AS IS" BASIS,** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.** See the License for the specific language governing permissions and** limitations under the License.*/-->
    <device name="Android">	<item name="none">0</item>	<item name="screen.on">55</item>	<item name="bluetooth.active">142</item>	<item name="bluetooth.on">1</item>	<item name="bluetooth.at">35690</item>	<item name="screen.full">115</item>	<item name="wifi.on">4</item>	<item name="wifi.active">130</item>	<item name="wifi.scan">104</item>	<item name="dsp.audio">75</item>	<item name="dsp.video">75</item>	<item name="radio.active">300</item>	<item name="gps.on">170</item>	<item name="radio.scanning">70</item>	<array name="radio.on">		<value>3</value>		<value>3</value>	</array>	<array name="cpu.speeds">		<value>1000000</value>		<value>900000</value>		<value>800000</value>		<value>700000</value>		<value>600000</value>		<value>500000</value>		<value>400000</value>		<value>300000</value>		<value>200000</value>		<value>100000</value>	</array>	<item name="cpu.idle">10</item>	<array name="cpu.active">		<value>840</value>		<value>760</value>		<value>680</value>		<value>520</value>		<value>440</value>		<value>360</value>		<value>280</value>		<value>200</value>		<value>120</value>		<value>40</value>	</array>	<item name="battery.capacity">1000</item></device>
    <?xml version="1.0" encoding="utf-8"?><!--**** Copyright 2009, The Android Open Source Project**** Licensed under the Apache License, Version 2.0 (the "License")** you may not use this file except in compliance with the License.** You may obtain a copy of the License at****     http://www.apache.org/licenses/LICENSE-2.0**** Unless required by applicable law or agreed to in writing, software** distributed under the License is distributed on an "AS IS" BASIS,** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.** See the License for the specific language governing permissions and** limitations under the License.*/-->
    <device name="Android">	<item name="none">0</item>	<item name="screen.on">55</item>	<item name="bluetooth.active">142</item>	<item name="bluetooth.on">1</item>	<item name="bluetooth.at">35690</item>	<item name="screen.full">115</item>	<item name="wifi.on">4</item>	<item name="wifi.active">130</item>	<item name="wifi.scan">104</item>	<item name="dsp.audio">75</item>	<item name="dsp.video">75</item>	<item name="radio.active">300</item>	<item name="gps.on">170</item>	<item name="radio.scanning">70</item>	<array name="radio.on">		<value>3</value>		<value>3</value>	</array>	<array name="cpu.speeds">		<value>1000000</value>		<value>900000</value>		<value>800000</value>		<value>700000</value>		<value>600000</value>		<value>500000</value>		<value>400000</value>		<value>300000</value>		<value>200000</value>		<value>100000</value>	</array>	<item name="cpu.idle">10</item>	<array name="cpu.active">		<value>840</value>		<value>760</value>		<value>680</value>		<value>520</value>		<value>440</value>		<value>360</value>		<value>280</value>		<value>200</value>		<value>120</value>		<value>40</value>	</array>	<item name="battery.capacity">1000</item></device>
    <?xml version="1.0" encoding="utf-8"?>
    	<device name="Android">
     	<item name="none">0</item><item name="screen.on">55</item>	<item name="bluetooth.active">142</item>	<item name="bluetooth.on">1</item>	<item name="bluetooth.at">35690</item>	<item name="screen.full">115</item>	<item name="wifi.on">4</item>	<item name="wifi.active">130</item>	<item name="wifi.scan">104</item>	<item name="dsp.audio">75</item>	<item name="dsp.video">75</item>	<item name="radio.active">300</item>	<item name="gps.on">170</item>	<item name="radio.scanning">70</item>
    <item name="screen.on">55</item>
    <item name="bluetooth.active">142</item>
    <item name="bluetooth.on">1</item>
    	<item name="bluetooth.at">35690</item>
    	<item name="screen.full">115</item>
    	<item name="wifi.on">4</item>
    	<item name="wifi.active">130</item>
    	<item name="wifi.scan">104</item>
    	<item name="dsp.audio">75</item>
    	<item name="dsp.video">75</item>
    	<item name="radio.active">300</item>
    	<item name="gps.on">170</item>
    	<item name="radio.scanning">70</item>
    	<array name="radio.on">
    		<value>3</value>
    		<value>3</value>
    	</array>
    	<array name="cpu.speeds">
    		<value>1000000</value>
    		<value>900000</value>
    		<value>800000</value>
    		<value>600000</value>
    		<value>400000</value>
    		<value>100000</value>
    	</array>
    	<item name="cpu.idle">6</item>
    	<array name="cpu.active">
    		<value>1008</value>
    		<value>960</value>
    		<value>860</value>
    		<value>680</value>
    		<value>440</value>
    		<value>40</value>
    	</array>
    	<item name="battery.capacity">1000</item>
    </device>


    44.Android2.3上开启U盘自扫描:

    现象;插入U盘后在播放器中看不到U盘文件,如何才能打开
    解决方法:
    需修改
    frameworks\base\core\java\android\provider\Settings.java
    frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\DatabaseHelper.java
    packages\providers\MediaProvider\src\com\android\providers\media\MediaScannerReceiver.java
    packages\providers\MediaProvider\src\com\android\providers\media\MediaScannerService.java
    具体修改如若无法完成,可参考相关补丁包----补丁呢!!!


    45.如何降低CPU最高频率:

    现象:目前系统为动态调频,如何限定最高CPU频率
    解决方法:

    降低CPU频率需要作以下两个修改:
    1)在lichee\tools\pack\chips\sun5i\configs\android\xxx\sys_config1.fex文件(“xxx”为对应的方案配置文件目录)中修改启动频率:
           [target]boot_clock =1008
        boot_clock为启动的CPU频率,单位为MHz,根据需要自行修改,该值不能大于最高频率;

        2)在lichee\linux-3.0\arch\arm\mach-sun4i\cpu-freq\cpu-freq.h文件中修改CPU的最高频率:
            #define SUN4I_CPUFREQ_MAX       (1008000000)
           SUN4I_CPUFREQ_MAX为CPU允许运行的最高频率,单位是Hz,根据需要自行修改;



    46、Android4.0阿拉伯语言的问题:

    现象:android4.0在阿拉伯语语言系统下,APK程序进入到”设置”--“应用程序“--”储存转移“,点击“移至平板电脑”,出现无法移动的对话框
    另:在使用google market 下载apk时,出现错误的提示框,也是由于 android4.0 在阿拉伯文支持上有问题。
    解决方法:
    由于android4.0 对阿拉伯文支持问题,在调用String.format()方法的时候会出现有乱码的情况。
    具体此问题,需要修改
    frameworks\base\services\java\com\android\server\MountService.java
    将 
    public int createSecureContainer(String id, int sizeMb, String fstype,
                                        String key, int ownerUid) {
    public int createSecureContainer(String id, int sizeMb, String fstype,
                                        String key, int ownerUid) {
    public int createSecureContainer(String id, int sizeMb, String fstype,
                                        String key, int ownerUid) {
    public int createSecureContainer(String id, int sizeMb, String fstype,String key, int ownerUid) {
     。。。
    String cmd = String.format("asec create %s %d %s %s %d", id, sizeMb, fstype, key, ownerUid);
    修改为 String cmd = "asec create "+id+" "+ sizeMb+" "+ fstype+" "+ key+" "+ ownerUid;


    47.摄像头在录像界面,使预览画面随录像分辨率变化:

    例如:在media_profiles.xml文件中,分别设置了720p和480p的录像分辨率:

    <EncoderProfile quality="720p" fileFormat="mp4" duration="30">
                <Video codec="h264"
                       bitRate="3000000"
                       width="1280"
                       height="720"
                       frameRate="30" />
                
                <Audio codec="aac"
                       bitRate="128000"
                       sampleRate="44100"
                       channels="2" />
            </EncoderProfile>
            
            <EncoderProfile quality="480p" fileFormat="mp4" duration="30">
                <Video codec="h264"
                       bitRate="1500000"
                       width="640"
                       height="480"
                       frameRate="25" />

                <Audio codec="aac"
                       bitRate="12200"
                       sampleRate="8000"
                       channels="1" />
            </EncoderProfile>

    在camera.cfg文件中,对应的摄像头配置里面,需根据上面红色字体在
    key_support_preview_size = 添加1280x720,640x480 跟录像设置的分辨率一样的预览支持分辨率



    48、Nexus和Galaxy4动态壁纸的显示问题:

    现象:设置好动态壁纸,切换横竖屏,显示出现问题,被拉伸,或缺失
    解决方法:
    nexus
    
    packages/wallpapers/Basic/src/com/android/wallpaper/nexus/NexusRS.java
    
    69行resize函数
    @Override
        public void resize(int width, int height) {
            super.resize(width, height); // updates mWidth, mHeight
            // android.util.Log.d("NexusRS", String.format("resize(%d, %d)", width, height));
        }
    改成
    @Override
        public void resize(int width, int height) {
            super.resize(width, height); // updates mWidth, mHeight
            createProgramVertex();
            // android.util.Log.d("NexusRS", String.format("resize(%d, %d)", width, height));
        }
    

    galaxy4
    
    packages/wallpapers/Galaxy4/src/com/android/galaxy4/Galaxy4Wallpaper.java
    
    onSurfaceChanged函数改为
    
    @Override
            public void onSurfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
                super.onSurfaceChanged(surfaceHolder, format, width, height);
    
                if (mRenderScript != null) {
                    mRenderScript.setSurface(surfaceHolder, width, height);
                }
    
                if (mWallpaperRS == null) {
                    mWallpaperRS = new GalaxyRS();
                    mWallpaperRS.init(mRenderScript, getResources(), width, height);
                    mWallpaperRS.start();
                } 
    
                 mWallpaperRS.resize(width, height);
            }

    packages/wallpapers/Galaxy4/src/com/android/galaxy4/GalaxyRS.java文件,
    添加如下代码
    
    public void resize(int w,int h) {
            mWidth = w;
            mHeight = h;
            createProgramVertex();
        }


    49、修改System/build.prop看不到相关变化:

    现象:第一次烧录后开机,看不到修改后的信息,要在烧录后第2次打开才能看到修改后的内容
    解决方法:
    原因:是在修改system/build.prop文件后,没有使用make systemimage-nodeps命令
    解决方法:修改文件后,使用make systemimage-nodeps命令后,再pack

    50、修改sys_config.fex,不升级整个固件,就使其生效:

    1. 在android shell中将/dev/block/nanda mount到某个节点:
        mount -t vfat /dev/block/nanda /mnt/nand
    2. 修改sys_config1后build固件,然后在lichee\tools\pack\out\bootfs下找到scrpt.bin和script0.bin
    3. 然后用adb连接后,将scritp.bin和script0.bin推到所mount节点的根目录下,替换原有同名文件:
        adb push script*.bin  /mnt/nand/
    4. 最后sync重启即可
        adb shell
        sync
        reboot

    51.修改浏览器默认浏览模式:

    在android4.0.1/packages/apps/Browser/res/xml/debug_preferences.xml中将
    <ListPreference
     39         android:key="user_agent"
     40         android:title="@string/pref_development_uastring"
     41         android:entries="@array/pref_development_ua_choices"
     42         android:entryValues="@array/pref_development_ua_values"
     43         android:defaultValue="3"/>
    中修改defaultValue的值,对应如下:
    Android  :0
    Desktop :1
    iPhone:2
    iPad :3
    Froyo-N1:4
    Honeycomb-Xoom:5




    52.电源管理不准以及低电不关机:

    现象:v1.0和v1.1中感觉电池电量不准,在低电情况下,系统也没有自动关机
    解决方法:
    需确认sys_config1.fex以下几个地方:
    1. pmu_battery_rdc的值为100
    2. pmu_battery_cap为正确的电池电量
    3. pmu_bat_para的放电曲线校正

    对于低电系统没有自动关机问题,一般尝试修改pmu_battery_cap:
    pmu_bat_para4            = 0
    pmu_bat_para5            = 5

    53.如何单独替换内核:

    现象:有没有办法不升级整个固件,单独替换内核
    解决方法:
    在android shell中将/dev/block/nanda mount到某个节点:
    mount -t vfat /dev/block/nanda /mnt/nand
    然后用adb连接后,将bImage直接push到所mount节点的linux目录下,替换bImage:
    adb push bImage /mnt/nand/linux
    最后sync重启即可
    adb shell
    sync
    reboot

    54.摄像头Zoom功能生效:

    修改packages/apps/Camera/src/com/android/camera/ui/IndicatorControlWheel.java
    
    dispatchTouchEvent函数,第269行
    if ((mZoomControl != null) && (index == 0)) {   改为
     if ((mZoomControl != null) && (index == 0) && mCurrentLevel == 0) {

    55.录象时不能选择分辨率:

    现象:摄像头录像时,选择分辨率的选项没有
    解决实例:
    如果想在720p和480p之间选择,在mediaprofile.xml文件中,按如下设置:
    <CamcorderProfiles>
            
            <EncoderProfile quality="720p" fileFormat="mp4" duration="30">
                <Video codec="h264"
                       bitRate="3000000"
                       width="1280"
                       height="720"
                       frameRate="30" />
                
                <Audio codec="aac"
                       bitRate="128000"
                       sampleRate="44100"
                       channels="2" />
            </EncoderProfile>
            
            <EncoderProfile quality="480p" fileFormat="mp4" duration="30">
                <Video codec="h264"
                       bitRate="1500000"
                       width="640"
                       height="480"
                       frameRate="25" />
                <Audio codec="aac"
                       bitRate="12200"
                       sampleRate="8000"
                       channels="1" />
            </EncoderProfile>
            <EncoderProfile quality="timelapse720p" fileFormat="mp4" duration="30">
                <Video codec="h264"
                       bitRate="3000000"
                       width="1280"
                       height="720"
                       frameRate="30" />
                <!-- audio setting is ignored -->
                <Audio codec="aac"
                       bitRate="128000"
                       sampleRate="44100"
                       channels="2" />
          </EncoderProfile>
          
          <EncoderProfile quality="timelapse480p" fileFormat="mp4" duration="30">
                <Video codec="h264"
                       bitRate="1500000"
                       width="640"
                       height="480"
                       frameRate="25" />
                <Audio codec="aac"
                       bitRate="12200"
                       sampleRate="8000"
                       channels="1" />
            </EncoderProfile> 
    
            <ImageEncoding quality="90" />
            <ImageEncoding quality="80" />
            <ImageEncoding quality="70" />
            <ImageDecoding memCap="20000000" />
            <Camera previewFrameRate="0" />
        </CamcorderProfiles>

    56.修改蓝牙名称:

    如果你想修改默认的名字,可以这么做:
    文件external/bluetooth/bluez/src/main.c
    main_opts.name  = g_strdup("BlueZ");里面的BlueZ换成你想要的名字即可!

    57.为何用UsbManager调用getDeviceList获取设备列表总是空的:

    这个是因为缺少android.hardware.usb.host权限,
    http://www.oschina.net/code/download_src?file=android-4.0.1%2Fdata%2Fetc%2Fandroid.hardware.usb.host.xml
    下载该文件,放在/system/etc/permisson/下,可以解决

    58.低电自动关机重启:

    现象:低电状态下,自动关机后重启,进不了系统,偶尔能进入系统但是触屏没反应。
    解决方法:
    原因在于源不足以支持系统开机,而此时电池又电量太低,导致不能满足整个系统的开机功耗。解决方法是提高开机的门限电和Android关机门限。
     1:boot阶段开机的门限电压设置方法 :
    在sys_config1脚本中
    [boot_extend]
    vol_threshold = 3500
    2:修改Android 低电关机的门限
     BatteryService.java 
         private final void shutdownIfNoPower() {
            // shut down gracefully if our battery is critically low and we are not powered.
            // wait until the system has booted before attempting to display the shutdown dialog.
            if (mBatteryLevel < 5 && (5为5%即可关机修改 为更大的值,具体值可以根据具体情况而定)

    59.修改鼠标的按键定义:

    现象:鼠标插上以后,左键和右键的功能都是左键的,如何将右键修改为返回
    解决方法:
    这个是android的标准做法,如果定制,可以修改frameworks/base/services/input/inputreader.cpp文件中的:
    uint32_t CursorButtonAccumulator::getButtonState() const {
        uint32_t result = 0;
        if (mBtnLeft) {
            result |= AMOTION_EVENT_BUTTON_PRIMARY;
        }
        if (mBtnRight) {
            result |= AMOTION_EVENT_BUTTON_SECONDARY;
        }
        if (mBtnMiddle) {
            result |= AMOTION_EVENT_BUTTON_TERTIARY;
        }
        if (mBtnBack || mBtnSide) {
            result |= AMOTION_EVENT_BUTTON_BACK;
        }
        if (mBtnForward || mBtnExtra) {
            result |= AMOTION_EVENT_BUTTON_FORWARD;
        }
        return result;
    }
    目前因为下面函数
    static bool isPointerDown(int32_t buttonState) {
        return buttonState &
                (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
                        | AMOTION_EVENT_BUTTON_TERTIARY);
    }
     
    将鼠标左右键的功能设置成判断鼠标是否点击的操作,所以功能一致,如果需要修改,这需要改一下上面的getButtonState函数中的标志位即可,比如需要将右键改为后退键,只需要
    函数中:
      if (mBtnRight) {
            result |= AMOTION_EVENT_BUTTON_SECONDARY;
        }
    改为
      if (mBtnRight) {
            result |= AMOTION_EVENT_BUTTON_BACK;
        }
    即可。


    60.修改system分区大小:

    1。修改sys_config.fex中的
        [partition3]
        class_name  = DISK
        name        = system
        size_hi     = 0
        size_lo     = 524288     //此处单位为K
        user_type   = 2
        ro            = 0
    2。修改device对应目录下的BoardConfig.mk中的
        BOARD_SYSTEMIMAGE_PARTITION_SIZE := 536870912  //此处单位为byte























    展开全文
  • USB的挂起和唤醒 (Suspend and Resume)

    万次阅读 2012-02-22 19:09:46
    USB协议的第9章讲到USB可见设备状态[Universal Serial Bus Specification, Section 9.1.1, Pg 239],分为连接(Attached),上电(Powered),默认(Default),地址(Address),配置(Configured)和挂起(Suspended)6个状态...
    USB协议的第9章讲到USB可见设备状态[Universal Serial Bus Specification, Section 9.1.1, Pg 239],分为连接(Attached),上电(Powered),默认(Default),地址(Address),配置(Configured)和挂起(Suspended)6个状态。所谓可见,即USB系统和主机可见的状态,其他状态属于USB设备内部而不可见。其中有关电源的,大致可分下面三类:
    1. 连接状态(Attached):设备连接,但未提供电源。
    2. 上电状态(Powered):设备被复位(Reset),或者说处于地址、配置状态。(参见USB枚举过程,USB Specification, page 241)

    3. 挂起状态(Suspended):3 ms未见总线活动而处于省电状态,设备不可用,但仍然保持原有的USB地址和配置。

    设备的挂起
    我们知道,在USB系统中,正常状态下hub或root hub会一直周期性地发送SOF包(Start Of Frame,全速USB每1ms发送一个,高速USB则是125
    µs发送一个)。根据USB协议,如果USB线上一直处于空闲(Idle)状态超过3ms,设备应该把它当作一个挂起(Suspended)信号,要求设备在10ms内进入挂起状态,并把设备所需的电流大小降到规定的值(对于low-power设备,要求是500 µA,而对于high-power或支持远程唤醒(remote wakeup)功能的设备是2.5mA【Section 7.2.3, Pg176】)。在挂起状态中,设备必须继续向数据项D+/D-的上拉电阻提供电压以维持Idle状态。而对于USB2.0高速设备,还有些额外的要求:
    1. 高速设备在
    收到挂起信号(3ms空闲)后,应在0.125ms内切换到全速状态,也就是说要把终端电阻移除,并在D+数据线上重新挂上1.5k上拉电阻。
    2. 设备在随后的100-875µs内检测数据线上的状态。如果该状态是一个
    Full speed J,那么说明host发下来的是一个挂起信号;如果此时该状态是SE0,说明是host drive数据线D+到0,这是一个复位信号(复位信号会持续至少10ms时间)。
      要注意的是高速设备在挂起状态时处于高速模式,只是所用的是全速信号。一旦从挂起状态恢复回来,会马上进入高速工作状态而无需进行复位操作。


     如上图所示,Host在a点停止发送SOF,系统处于SE0状态,b点是3ms时间点,之后的125µs内,设备移除终端电阻,并挂上1.5k上拉。此时如host发送的是suspend信号,那它就不会不drive D+数据线,导致D+被设备拉高,形成一个Full Speed J状态。在c点之后100-875µs内设备检测此时host行为,发现是suspend信号,设备内部进入低功耗的挂起(suspend)状态。(假如hsot发送的是复位信号,那么当设备在c点挂1.5k电阻之后,由于host对D+线的drive作用,D+线无法被拉高,仍然处于SE0状态,设备在c点之后的检测,发现的还是SE0状态,等到10ms后就可判断这是一个复位信号,进行设备复位操作。)

    设备的唤醒
      设备处于挂起状态时,任何总线上的活动(非空闲信号)都可以把设备唤醒/恢复,从而退出低功耗模式。(同样,设备也可以换醒host,比如电脑待机时通过USB键盘来换醒主机,这种功能称之为“远程唤醒”(remote wakeup),不在本文的讨论范围内。)
      因为设备挂起时处于全速信号,在当host需要把将设备退出suspend状态时,需要先发送一个持续时间超过20ms的Fulll Speed K状态。设备看到K状态结束的1.3us内醒过来,而host需要在3ms内发送uSOF信号以维持正常的高速信号模式,否则设备又将进入suspend。如下图所示:



    本文纯属转载,原文地址:USB的挂起和唤醒


    展开全文
  • usb休眠唤醒相关

    千次阅读 2020-04-30 13:41:13
    如果不支持usb remote wakeup, 则usb控制器, phy都可以进入休眠状态。 关闭相关clock时钟, 甚至断电。 如果需要支持usb remote wakeup, 则不能完全断电, 需要留下部分底电流, 当usb外设发出request wakeup请求后,...

    usb 休眠唤醒包括两种:

    1. system suspend/resume   系统休眠唤醒

         如果不支持usb remote wakeup, 则usb控制器, phy都可以进入休眠状态。 关闭相关clock时钟, 甚至断电。

         如果需要支持usb remote wakeup, 则不能完全断电, 需要留下部分底电流, 当usb外设发出request wakeup请求后, 能通过

     usbphy->usb controller->cpu 将整体系统唤醒。 (常见如个人电脑产品,  基本都支持usb鼠标键盘唤醒)

     

    2. dynamic suspend/resume 动态休眠唤醒, 也叫runtime suspend/resume 或者 selective suspend/resume

    即运行时休眠唤醒和选择性休眠唤醒。

    此种休眠唤醒和系统其它IP, cpu 核心就没有关系了。

    仅和usb 控制器 、phy 及外接设备有关

     

    相关文档可以参考Documents/driver-api/usb/power-management.rst

     

    3. runtime suspend/resume 系统文件

    sysfs文件系统中有关于runtime suspend/resume 控制的一些文件, 位置如下:

    /sys/bus/usb/devices/.../power/''         其中, ...为设备id

    文件:

    - power/wakeup    -- enable/disabled, 代表是否支持remote wakeup功能, 即系统唤醒功能。常见如鼠标, 键盘等HID设备都是支持的。

    - power/control     -- on/auto,  on代表auto suspend/resume是不允许的, 即一直是active状态; auto代表该设备支持auto suspend/resume。  常见如hub, 鼠标, 键盘等都支持auto suspend/resume, 而我手头的U盘等设备并支持。

    - power/autosuspend_delay_ms   -- 默认值是2000, 代表设备在idle状态(总线无数据读写)下2000毫秒后即进入auto suspend状态。0代表 auto suspend as soon as the device becomes idle. 即尽快进入休眠状态。

     

    * echo -1 > power/auto_suspend_delay_ms和 echo "on" > power/control 是同样的作用,  即防止设备进入auto suspend状态。

     

    4. usb控制器中关于休眠唤醒的寄存器

    查看intel xhci-1.2协议文档。

    主要是0x420和0x430寄存器, PORTSC  (Port Status and Control Register)

    bit[5:8], 读取的值 0 - U0, 1 - U1, 2 - U2, 3 - U3, 4 - Disabled, 5 - RxDetect, 6 - Inactive,  - Polling, 8 - Recovery, 9 - Hot Reset, 

    10 - Compliance Mode, 11 -  Test Mode, 12 - 14 Reserved, 15 - Resume State

     

    5. 如何修改idle_delay 默认值, 即总线空闲多久进入suspend的默认时间

    usbcore内核模块参数可以控制。

    modprobe usbcore autosuspend=5

    这样总线需要空闲5秒后才进入auto suspend状态

    等价的, 也可以在/etc/modprobe.d中添加 

    options usbcore autosuspend=5 添加内核参数

    如果是buildin的usbcore模块, 则添加

    usbcore.autosuspend=5

    最后, 也可以开机后直接操作sysfs文件系统, 

    echo  5 > /sys/module/usbcore/parameters/autosuspend 即可

     

    6. Warnings

    根据USB协议, 所有的USB设备需要支持电源管理, 但是悲伤的事实是, 很多usb设备对于电源管理的支持都不怎么好...

    比如很多设备休眠后就无法唤醒, 或需要重新初始化等。

    所以Linux内核代码对所有usb设备, 默认都将power/control属性初始化为"On"。 其中除了usb hub设备。

    至少hub设备看起来都能比较好的支持auto suspend/resume。

    所以对于非hub的usb设备, 需要手动echo auto > power/control后, 才能支持auto suspend/resume

    试验了下 手头的惠普鼠标修改power/control后, 可以顺利进入auto susepnd状态。

    但金士顿, 联想, 兰科芯U盘都不行... (主控有慧荣SMI3267AE, 群联PS2251-09等) 其中金士顿DataTraverler 主控未知, ChipGenius_v4_19_0319版本无法识别...

    另外Orico的usb hub 也无法进入suspend状态。

    以上行为都是开发板中的行为 (USB控制器synopsys dwc3)

    后续对比PC产品以判断是开发板问题还是usb外设问题。

     

    7. 编程相关

    :c:type:usb_driver 结构体, 三个方法, 其中reset_resume可选。

    .suspend    --  to warn the driver that the device is going to be suspended.  通常返回成功0, 需要取消所有的outstanding URBs

                           (:c:func: usb_kill_urb), 并且不提交其他任何usb请求块。

    .resume      --  to tell the driver that the device has been resumed and the driver can return to normal operation.

    .reset_resume   -- 可选, to tell the driver that the device ahs been resumed and it also has been reset. 需要重新初始化。

     

    If the device is disconnected or power down while it is suspended, the 'disconnect' method will be called instead of the 'resume' or 'reset_resume' method.

    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

    除了以上suspend/resume等接口,  :c:type:usb_driver结构体中还有个.supports_autosuspend标志。

    以及以下6个接口:

    ›       int  usb_autopm_get_interface(struct usb_interface *intf);                                                                      
    ›       void usb_autopm_put_interface(struct usb_interface *intf);                                                                      
    ›       int  usb_autopm_get_interface_async(struct usb_interface *intf);                                                                
    ›       void usb_autopm_put_interface_async(struct usb_interface *intf);                                                                
    ›       void usb_autopm_get_interface_no_resume(struct usb_interface *intf);                                                            
    ›       void usb_autopm_put_interface_no_suspend(struct usb_interface *intf);  

    内部有个usage_counter, >0 说明总线busy, =0说明总线idle。具体使用中再熟悉吧...

     

    其他函数:

    usb_enable_autosuspend

    usb_disable_autosuspend

    usb_mark_last_busy

    等等, 其实就是操作sysfs的一些文件节点的实际函数动作。

     

    8. 动态电源管理和系统电源管理之间的联系 (Interaction between dynamic PM and system PM)

    1). 当系统休眠时, 可能设备早就auto suspend了... 所以对于该外设就继续保持休眠就可以了, 但唤醒的动作需要定义, 是否要去唤醒该auto suspend设备?? 2.6.37内核定义的策略是在系统唤醒时, 唤醒所有休眠 的设备。 让设备自己去触发auto suspend。

    2). 在系统休眠的过程中, 外设的auto suspend也发生了... 这也是有可能发生的, 因为系统休眠通常需要几秒钟的时间, 在该段时间内总线进idle, 发生了auto suspend当然是合理的...

    同样, 一个remote wakeup事件也可能发生在系统休眠过程中... it can happen...

    不管怎样, 系统休眠和动态休眠都是独立发生的, 可能会互相影响, 具体问题具体分析...

     

    9. xHCI hardware link PM

    hardware link power management.

    L1 - usb2.0 devices

    U1/U2 usb3.0 devices

    关于Link, 即链接, LPM即链接电管管理, (链路层电源管理) 

    可参考

    https://docs.microsoft.com/zh-cn/windows-hardware/drivers/usbcon/link-power-management-in-usb-3-0-hardware

    https://docs.microsoft.com/zh-cn/windows-hardware/drivers/usbcon/usb-3-0-lpm-mechanism-

    https://docs.microsoft.com/zh-tw/windows-hardware/drivers/usbcon/usb-3-0-lpm-mechanism-

    What is a link
    A USB connection exists between two USB ports:
    
    The downstream port (DS port) of a host or a hub.
    The upstream port (US port) of an attached device or hub.
    A link is a pair of DS and US ports; the ports are known as link partners. Each port has two layers. The physical layer transmits or receives sequences of bytes or other control signals. The logical layer manages the physical layer and ensures smooth flow of information between the link partners. The logical layer is also responsible for any buffering that might be required for the information flow.

    大体就是usb phy选择性控制连接的外设进行电源管理。

    xhci 协议中PortSC 寄存器的bit[5:8] 即为Port Link State

    或者dwc3 datasheet中的DSTS寄存器中的Link Status位, 

    enum dwc3_link_state {                                                                                                                                                                                       
    ›       /* In SuperSpeed */                                                                                                                                                                                  
    ›       DWC3_LINK_STATE_U0›     ›       = 0x00, /* in HS, means ON */                                                                                                                                        
    ›       DWC3_LINK_STATE_U1›     ›       = 0x01,                                                                                                                                                              
    ›       DWC3_LINK_STATE_U2›     ›       = 0x02, /* in HS, means SLEEP */                                                                                                                                     
    ›       DWC3_LINK_STATE_U3›     ›       = 0x03, /* in HS, means SUSPEND */                                                                                                                                   
    ›       DWC3_LINK_STATE_SS_DIS› ›       = 0x04,                                                                                                                                                              
    ›       DWC3_LINK_STATE_RX_DET› ›       = 0x05, /* in HS, means Early Suspend */                                                                                                                             
    ›       DWC3_LINK_STATE_SS_INACT›       = 0x06,                                                                                                                                                              
    ›       DWC3_LINK_STATE_POLL›   ›       = 0x07,                                                                                                                                                              
    ›       DWC3_LINK_STATE_RECOV›  ›       = 0x08,                                                                                                                                                              
    ›       DWC3_LINK_STATE_HRESET› ›       = 0x09,                                                                                                                                                              
    ›       DWC3_LINK_STATE_CMPLY›  ›       = 0x0a,                                                                                                                                                              
    ›       DWC3_LINK_STATE_LPBK›   ›       = 0x0b,                                                                                                                                                              
    ›       DWC3_LINK_STATE_RESET›  ›       = 0x0e,                                                                                                                                                              
    ›       DWC3_LINK_STATE_RESUME› ›       = 0x0f,                                                                                                                                                              
    ›       DWC3_LINK_STATE_MASK›   ›       = 0x0f,                                                                                                                                                              
    }; 

    对于usb3.0来说, 有u0, u1, u2, u3等link state状态, 分别对应休眠的等级, 相当于 u0 - 没睡, u1 - 浅睡, u2 - 中睡, u3 - 深睡

    对于usb2.0来说, 状态就少点了, 根据上面描述, 也就u0 - 激活, u2 - sleep, u3 - suspend

    对比前面描述的休眠唤醒, LPM相当于多了些休眠等级。功能之间有些细微的差别。

    且LPM基本不需要软件进行参与, 配置好功能后, usb phy会根据设备状态让其进入相应的Link State。

     

    系统文件目录(/sys/bus/usb/devices/.../power/)中有些控制节点, 比如

    power/usb2_hardware_lpm

    ›       ``power/usb2_hardware_lpm``                                                                                                     
                                                                                                                                            
    ›       ›       When a USB2 device which support LPM is plugged to a                                                                    
    ›       ›       xHCI host root hub which support software LPM, the                                                                      
    ›       ›       host will run a software LPM test for it; if the device                                                                 
    ›       ›       enters L1 state and resume successfully and the host                                                                    
    ›       ›       supports USB2 hardware LPM, this file will show up and                                                                  
    ›       ›       driver will enable hardware LPM›for the device. You                                                                     
    ›       ›       can write y/Y/1 or n/N/0 to the file to›enable/disable                                                                  
    ›       ›       USB2 hardware LPM manually. This is for›test purpose mainly.

    当接入的设备支持usb2.0 LPM且测试通过,  该文件就是显示。 用户可以控制该文件来enable/disable USB2 hardware LPM功能。

     

    power/usb3_hardware_lpm_u1

    power/usb3_hardware_lpm_u2

    ›       ``power/usb3_hardware_lpm_u1``                                                                                                  
    ›       ``power/usb3_hardware_lpm_u2``                                                                                                  
                                                                                                                                            
    ›       ›       When a USB 3.0 lpm-capable device is plugged in to a                                                                    
    ›       ›       xHCI host which supports link PM, it will check if U1                                                                   
    ›       ›       and U2 exit latencies have been set in the BOS                                                                          
    ›       ›       descriptor; if the check is passed and the host                                                                         
    ›       ›       supports USB3 hardware LPM, USB3 hardware LPM will be                                                                   
    ›       ›       enabled for the device and these files will be created.                                                                 
    ›       ›       The files hold a string value (enable or disable)                                                                       
    ›       ›       indicating whether or not USB3 hardware LPM U1 or U2                                                                    
    ›       ›       is enabled for the device. 

    字面意思, 当支持usb3.0 LPM的设备插入后, 会检查U1, U2的exit latencies, 是否被设置在BOS描述信息中。

    如果检查通过,  且xhci控制器支持USB3 LPM功能, 则usb3 lpm功能则会被使能,  且这些文件会被创建。

    用户可以通过写入字符串enable/disable 去控制usb3 hardare lpm功能的开启和关闭。

     

    10. USB Port Power Control (usb端口电源管理相关)

    主机供电,  显然该功能是控制对应端口的供电, 以控制usb外设供电。

    相关函数:

    Set/ClearPortFeature(PORT_POWER)   >>>> 发送该请求给hub (单独hub或控制器root hub)

    如此, root hub 或者 platform-internal hub (内部集成hub) 会进行对应端口电源管理控制。

    比如xhci控制器的PortSC寄存器的Port Power(PP)位, 就可以控制端口的供电。

    ClearPortFeature(PORT_POWER) 请求一个usb端口逻辑关闭。则可能会触发实际的VBUS断电。

    vbus也有可能继续维持, 这个看具体集线器的设计和行为。参看文档描述:

    USB Port Power Control                                                                                                                  
    ----------------------                                                                                                                  
                                                                                                                                            
    In addition to suspending endpoint devices and enabling hardware                                                                        
    controlled link power management, the USB subsystem also has the                                                                        
    capability to disable power to ports under some conditions.  Power is                                                                   
    controlled through ``Set/ClearPortFeature(PORT_POWER)`` requests to a hub.                                                              
    In the case of a root or platform-internal hub the host controller                                                                      
    driver translates ``PORT_POWER`` requests into platform firmware (ACPI)                                                                 
    method calls to set the port power state. For more background see the                                                                   
    Linux Plumbers Conference 2012 slides [#f1]_ and video [#f2]_:                                                                          
                                                                                                                                            
    Upon receiving a ``ClearPortFeature(PORT_POWER)`` request a USB port is                                                                 
    logically off, and may trigger the actual loss of VBUS to the port [#f3]_.                                                              
    VBUS may be maintained in the case where a hub gangs multiple ports into                                                                
    a shared power well causing power to remain until all ports in the gang                                                                 
    are turned off.  VBUS may also be maintained by hub ports configured for                                                                
    a charging application.  In any event a logically off port will lose                                                                    
    connection with its device, not respond to hotplug events, and not                                                                      
    respond to remote wakeup events

    不管怎样, logic off肯定导致连接是断开的。

     

    11. User Interface for Port Power Control

    User Interface for Port Power Control                                                                                                   
    -------------------------------------                                                                                                   
                                                                                                                                            
    The port power control mechanism uses the PM runtime system.  Poweroff is                                                               
    requested by clearing the ``power/pm_qos_no_power_off`` flag of the port device                                                         
    (defaults to 1).  If the port is disconnected it will immediately receive a                                                             
    ``ClearPortFeature(PORT_POWER)`` request.  Otherwise, it will honor the pm                                                              
    runtime rules and require the attached child device and all descendants to be                                                           
    suspended. This mechanism is dependent on the hub advertising port power                                                                
    switching in its hub descriptor (wHubCharacteristics logical power switching                                                            
    mode field).                                                                                                                            
                                                                                                                                            
    Note, some interface devices/drivers do not support autosuspend.  Userspace may                                                         
    need to unbind the interface drivers before the :c:type:`usb_device` will                                                               
    suspend.  An unbound interface device is suspended by default.  When unbinding,                                                         
    be careful to unbind interface drivers, not the driver of the parent usb                                                                
    device.  Also, leave hub interface drivers bound.  If the driver for the usb                                                            
    device (not interface) is unbound the kernel is no longer able to resume the                                                            
    device.  If a hub interface driver is unbound, control of its child ports is                                                            
    lost and all attached child-devices will disconnect.  A good rule of thumb is                                                           
    that if the 'driver/module' link for a device points to                                                                                 
    ``/sys/module/usbcore`` then unbinding it will interfere with port power                                                                
    control.

     

    12. Suggested Userspace Port Power Policy

    As noted above userspace needs to be careful and deliberate about what                                                                  
    ports are enabled for poweroff.                                                                                                         
                                                                                                                                            
    The default configuration is that all ports start with                                                                                  
    ``power/pm_qos_no_power_off`` set to ``1`` causing ports to always remain                                                               
    active.                                                                                                                                 
                                                                                                                                            
    Given confidence in the platform firmware's description of the ports                                                                    
    (ACPI _PLD record for a port populates 'connect_type') userspace can                                                                    
    clear pm_qos_no_power_off for all 'not used' ports.  The same can be                                                                    
    done for 'hardwired' ports provided poweroff is coordinated with any                                                                    
    connection switch for the port.                                                                                                         
                                                                                                                                            
    A more aggressive userspace policy is to enable USB port power off for                                                                  
    all ports (set ``<hubdev-portX>/power/pm_qos_no_power_off`` to ``0``) when                                                              
    some external factor indicates the user has stopped interacting with the                                                                
    system.  For example, a distro may want to enable power off all USB                                                                     
    ports when the screen blanks, and re-power them when the screen becomes                                                                 
    active.  Smart phones and tablets may want to power off USB ports when                                                                  
    the user pushes the power button.

     

    端口电源管理部分还不够完善, 具体遇到再理解添加。

    以上所以基本参考内核文档:

    Documents/driver-api/usb/power-management.rst

     

    总结下, 相关知识点:

    1. 系统休眠唤醒

    2. 动态/运行时/可选择休眠唤醒

    3. LPM (U0, U1, U2, U3) 链路层电源管理

    4. PPM (Port Power Management) 端口电源管理

    5. Remote Wakeup, 设备/硬件唤醒 系统

    展开全文
  • 问题描述:拔出usb线后usb没有进入lpm模式,导致系统无法休眠 / # cat /proc/cmdline cat /proc/cmdline noinitrd ro console=NULL androidboot.hardware=qcom ehci-hcd.park=3 msm_rtb.filter=0x37 lpm_levels....
    问题描述:拔出usb线后usb没有进入lpm模式,导致系统无法休眠
    / # cat /proc/cmdline
    cat /proc/cmdline
    noinitrd ro console=NULL androidboot.hardware=qcom ehci-hcd.park=3 msm_rtb.filter=0x37 lpm_levels.sleep_disabled=1 early
    con=msm_hsl_uart,0x78b1000 androidboot.serialno=3b9980 androidboot.authorized_kernel=true androidboot.baseband=msm rootf
    stype=ubifs rootflags=bulk_read root=ubi0:rootfs ubi.mtd=14 custapp=/dev/ubi2_0
    此时执行休眠提示
    sh: write error: Device or resource busy
    ************************************************************
    去掉lpm_levels.sleep_disabled=1后,设置 # echo off > /sys/power/autosleep (或者去掉CONFIG_PM_AUTOSLEEP
    执行休眠结果
    /sys/devices/virtual/android_usb/android0 # echo mem > /sys/power/state 
    [  471.726138] PM: suspend entry 1980-01-06 00:07:54.413190146 UTC
    [  471.731040] PM: Syncing filesystems ... done.
    [  471.761237] Freezing user space processes ... 
    [  471.777456] Error: returning -512 value
    [  471.783461] mbim_read: Waiting failed
    [  471.791890] (elapsed 0.016 seconds) done.
    [  471.794883] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
    [  471.804475] Suspending console(s) (use no_console_suspend to debug)
    [  471.824526] msm_otg 78d9000.usb: Abort PM suspend!! (USB is outside LPM)
    [  471.824574] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -16
    [  471.824600] PM: Device 78d9000.usb failed to suspend: error -16
    [  471.824621] PM: Some devices failed to suspend, or early wake event detected
    [  471.837781] PM: resume of devices complete after 13.111 msecs
    [  471.870450] Restarting tasks ... done.
    [  471.896264] cpufreq: Frequency violation fixed for CPU0
    [  471.900527] Abort: Some devices failed to suspend, or early wake event detected
    [  471.914510] PM: suspend exit 1980-01-06 00:07:54.601557125 UTC
    sh: write error: Device or resource busy
    /sys/devices/virtual/android_usb/android0 # 
     
    ********************************************************************************************
    去掉dts里hsic相关的配置,去掉vbus_otg-supply = <&smb358_otg_vreg>及smb的配置
    /sys/power # echo off > autosleep 
    /sys/power # echo mem > state 
    [  123.758308] PM: suspend entry 1980-01-06 01:37:37.417375487 UTC
    [  123.763212] PM: Syncing filesystems ... done.
    [  123.790947] Freezing user space processes ... 
    [  123.810440] mbim_read: Waiting failed
    [  123.818858] (elapsed 0.013 seconds) done.
    [  123.821852] Freezing remaining freezable tasks ... (elapsed 0.002 seconds) done.
    [  123.831426] Suspending console(s) (use no_console_suspend to debug)
    [  123.852721] msm_otg 78d9000.usb: Abort PM suspend!! (USB is outside LPM)
    [  123.852770] dpm_run_callback(): platform_pm_suspend+0x0/0x54 returns -16
    [  123.852796] PM: Device 78d9000.usb failed to suspend: error -16
    [  123.852818] PM: Some devices failed to suspend, or early wake event detected
    [  123.865932] PM: resume of devices complete after 13.065 msecs
    [  123.898676] Restarting tasks ... 
    [  123.905102] msm_otg 78d9000.usb: ep_set_halt: Unable to halt EP while suspended
    [  123.911576] msm_otg 78d9000.usb: ep_set_halt: Unable to halt EP while suspended
    [  123.934291] done.
    [  123.946347] cpufreq: Frequency violation fixed for CPU0
    [  123.950615] Abort: Some devices failed to suspend, or early wake event detected
    [  123.965856] PM: suspend exit 1980-01-06 01:37:37.624923612 UTC
    sh: write error: Device or resource busy
     
    ***********************************************************************************************************
    可以使用这个指令打印usb状态机的log:echo file phy-msm-usb.c +p > /sys/kernel/debug/dynamic_debug/control
     
    考虑LPM对usb的控制,特别是vbus部分,由于没有采用smb芯片,应配置成pmic引脚监测vbus的方式
    参考文档 MDM9x07\BSP\PMIC\80_NH740_69_VBUS_DETECTION_USING_PMIC.pdf
    主要有3点修改:
    1. deconfig文件增加CONFIG_GPIO_USB_DETECT=y
    2. dts增加pmic的mpp引脚监测
    /* MPP pin 2 config for VBUS_DETECT interrupt line */
    &pm8019_mpps {
    mpp@a100 {
    qcom,mode = <0>;     /* Digital input */
    qcom,vin-sel = <3>;  /* 1.8V (L11) */
    qcom,src-sel = <0>;  /*  QPNP_PIN_SEL_FUNC_CONSTANT */
    qcom,pull = <1>;              /* No Pull */
    qcom,master-en = <1>; /*Enable GPIO*/
    status = "ok";
    };
    };
    3.dts禁掉smb358-charger,启用usb_detect
    smb358_otg_vreg: smb358-charger@57 {
    status = "disabled";
    };
    usb_detect { 
    compatible = "qcom,gpio-usbdetect"; 
    interrupt-parent = <&spmi_bus>; 
    interrupts = <0x0 0xA1 0x0>; /* PMD9607 MPP 2 */ 
    interrupt-names = "vbus_det_irq"; 
    }; 
     
    执行结果
    /sys/power # [  940.576199] msm_otg 78d9000.usb: phy_reset: success
    [  940.686731] msm_otg 78d9000.usb: USB exited from low power mode
    [  940.698794] msm_hsusb msm_hsusb: CI13XXX_CONTROLLER_RESET_EVENT received
    [  940.704699] msm_hsusb msm_hsusb: CI13XXX_CONTROLLER_CONNECT_EVENT received
    [  940.918915] udc_irq: USB reset interrupt is delayed
    [  940.922874] msm_otg 78d9000.usb: Avail curr from USB = 100
    [  940.929077] android_work: android_work: did not send uevent (0 0 00000000)
    [  941.008406] android_work: android_work: sent uevent USB_STATE=CONNECTED
    [  941.024581] android_work: android_work: sent uevent USB_STATE=DISCONNECTED
    [  941.122982] android_work: android_work: sent uevent USB_STATE=CONNECTED
    [  941.164584] android_usb gadget: high-speed config #1: 86000c8.android_usb
    [  941.170432] diag: USB channel diag connected
    [  941.175045] msm_otg 78d9000.usb: Avail curr from USB = 500
    [  941.182885] gbam_connect_work: gbam_connect_work: Bam channel is not ready
    [  941.234697] android_work: android_work: sent uevent USB_STATE=CONFIGURED
     
    /sys/power # 
    /sys/power # [  945.770367] gser_suspend: Un-supported transport: TTY
    [  945.774456] msm_otg 78d9000.usb: Avail curr from USB = 2
    [  945.779715] msm_hsusb msm_hsusb: CI13XXX_CONTROLLER_SUSPEND_EVENT received
    [  945.786985] diag: USB channel diag disconnected
    [  945.792630] gbam_disconnect_work: gbam_disconnect_work: Bam channel is not opened
    [  945.802721] android_work: android_work: sent uevent USB_STATE=DISCONNECTED
    [  945.844687] msm_hsusb msm_hsusb: CI13XXX_CONTROLLER_DISCONNECT_EVENT received
    [  945.858531] msm_otg 78d9000.usb: Avail curr from USB = 0
    [  947.019999] msm_otg 78d9000.usb: USB in low power mode
     
    usb拔掉后可以正常转入DISCONNECTED态





    转载于:https://www.cnblogs.com/chenyidong/p/6774428.html

    展开全文
  • 概述 当谈到Linux系统的挂起/休眠时, 我们指的是以下三种受支持的Linux系统休眠状态:...STR(Suspend To RAM)提供了显著的功耗节省,因为系统中除了内存之外的所有东西都进入了低功耗状态。应将内存置于自刷新模式以..
  • USB的挂起和唤醒(Suspend and Resume)

    千次阅读 2014-05-07 21:01:25
    USB协议的第9章讲到USB可见设备状态[Universal Serial Bus Specification, Section 9.1.1, Pg 239],分为连接(Attached),上电(Powered),默认(Default),地址(Address),配置(Configured)和挂起(Suspended)6个状态...
  • Linux下USB suspend/resume源码分析

    万次阅读 2009-02-23 14:56:00
    Linux下USBsuspend/resume源码分析Author:aaron 本文主要从自己开发的一个USB驱动的例子来深入讲解linux内核是如何支持USB设备的休眠和唤醒的, 最近我在为我们公司的一个模块写linux下的驱动, 其中之一就是要支持...
  • usb suspend

    千次阅读 2016-10-08 17:03:32
    host停止一切传输(包括SOF token),在总线上的每一个usb device看到usb bus上空闲状态超过3ms,就会进入suspend状态。selective suspend usb总线通过向hub的某个port发送SetPortFeature(PORT_SUSPEND),这样,这个...
  • USB2.0之Suspend/Resume

    千次阅读 2017-05-29 23:38:40
    USB2.0只Suspend/Resume最近因工作需要学习了USBSuspend/Resume。 因为比较懒,这里仅把参考资料的详细位置写出来吧。参考资料USB2.0协议: 7.1.7.6 7.1.7.7 9.1.6 10.2.7 10.5.4.5linux中对USB Suspend/...
  • 解决了USBsuspend和resume的一个问题

    千次阅读 2010-03-14 20:05:00
    我们公司GSM部门有个双模智能手机的项目。MTK平台和EVDO平台通过USB进行通信。...即设备进入suspend之后无法被唤醒。刚开始MTK认为是我们的问题。我们自己验证发现,该功能没有问题。于是让对方换PC做HOST验证。但是
  • win10 turn on/off usb device selective suspend

    千次阅读 2018-12-20 19:03:47
    Keyboard or mouse not working after your PC wake up from ... When you’re charging your phone through an USB port, putting your PC into sleep mode will turn off the power to USB ports, and your phon...
  • USB 2.0 suspend resume

    千次阅读 2013-10-25 20:06:46
    suspend/resume时代 USB2.0在定义最初就支持suspend/resume 看一看见,退出suspend的时间要求是大于20ms。同时也可以看出D+, D-信号反转一下,既是...随后USB org认为这个简单的suspend/resume不能优化USB的功耗
  • USB2.0的挂起和唤醒 (Suspend and Resume) USB2.0协议的第9章讲到USB可见设备状态[Universal Serial Bus Specification, Section 9.1.1, Pg 239],分为连接(Attached),上电(Powered),默认(Default),地址(Address...
  • USB驱动Suspend&Resume 调用流程分析

    千次阅读 2010-02-04 21:29:00
    在6.0中,驱动通过USBDFunction类的成员函数SuspendDevice()来调用suspend功能,代码如下所示: 在SuspendDevice函数内部,通过USBD接口函数指针来调用到USBD内的函数中,在USBD内部的suspend功能实现,代码如下...
  • 首先,需要明白四个概念:挂起(suspend)、恢复(resume)、空闲(idle)和唤醒(wakeup)。
  • 系统没有进入suspend,主要的原因是因为系统有锁导致.锁一般分为:APP透过PowerManager拿锁,以及kernel wakelock.分析上层持锁的问题:目前PowerManagerService的log 默认不会打开,可以通过修改: /frameworks/...
  • User Space Entry: 1 : sys file system Path: /sys/power 2 : Find out what power management state the system support cat /sys/power/state 3 : Made system enter into t
  • 最近在做STM32F105的U盘升级功能,其中bootloader中的FLASH写入,APP跳转等均参考了...在移植好USB Host 功能后(F1的usb打算后续专门写一篇,这里就不介绍移植的工作了),移植FATFS文件系统,然后测试能够成功识别...
  • USB协议的第9章讲到USB可见设备状态[Universal Serial Bus Specification, Section 9.1.1, Pg 239],分为连接(Attached),上电(Powered),默认(Default),地址(Address),配置(Configured)和挂起(Suspended)6个状态...
  • suspend状态(sleep mode)下,为了降低功耗,当系统做完需要做的事情,处于idle状态时会进入睡眠模式(用户将手机空置一段时间系统会自动sleep,或者按下power key强制系统进入sleep mode),此时系统时钟会由26M...
  • 转自:...USB协议的第9章讲到USB可见设备状态[Universal Serial Bus Specification, Section 9.1.1, Pg 239],分为连接(Attached),上电(Powered),默认(Default),地址(Ad...
  • Linux下USB suspend/resume源码分析 Author:aaron   本文主要从自己开发的一个USB驱动的例子来深入讲解linux内核是如何支持USB设备的休眠和唤醒的, 最近我在为我们公司的一个模块写linux下的驱动, 其中之一...
  • USB1.1规范之硬件篇

    千次阅读 2006-04-19 11:55:00
    ConnectorsAll devices have an upstream connection to the host and all hosts have a downstream connection to the device. Upstream and downstream connectors are not mechanically interchangeable, thus

空空如也

1 2 3 4 5 ... 20
收藏数 6,328
精华内容 2,531
关键字:

usb 进入suspend