【干货】Android系统定制基础篇:第八部分(增加以太网设置菜单、支持多摄像头、替换默认签名)

news2024/11/17 20:41:53

一、增加以太网设置菜单

Android 系统设置默认并没有以太网相关设置项,但以太网功能是支持的,因此我们仅仅需要增加设置界面即可。以太网设置界面如下:
在这里插入图片描述
修改

diff --git a/packages/apps/Settings/AndroidManifest.xml b/packages/apps/Settings/AndroidManifest.xml
old mode 100644
new mode 100755
index b216bc5..85b1fd9
--- a/packages/apps/Settings/AndroidManifest.xml
+++ b/packages/apps/Settings/AndroidManifest.xml
@@ -479,6 +479,30 @@
                 android:value="com.android.settings.TetherSettings" />
         </activity-alias>
 
+        <activity android:name="Settings$EthernetSettingsActivity"
+                android:label="@string/ethernet_settings_title"
+                android:icon="@drawable/ic_settings_wireless"
+                android:taskAffinity="">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE_LAUNCH" />
+                <category android:name="com.android.settings.SHORTCUT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.EthernetSettings" />
+        </activity>
+        
+        <!-- Keep compatibility with old shortcuts. -->
+         <activity-alias android:name=".EthernetSettings"
+                android:label="@string/ethernet_settings"
+                android:clearTaskOnLaunch="true"
+                android:targetActivity="Settings$EthernetSettingsActivity"
+                android:exported="true">
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                android:value="com.android.settings.EthernetSettings" />
+         </activity-alias>
+
         <activity android:name="Settings$WifiP2pSettingsActivity"
                 android:taskAffinity="com.android.settings"
                 android:parentActivityName="Settings$WifiSettingsActivity">
diff --git a/packages/apps/Settings/res/drawable/ic_ethernet.xml b/packages/apps/Settings/res/drawable/ic_ethernet.xml
new file mode 100755
index 0000000..25a2438
--- /dev/null
+++ b/packages/apps/Settings/res/drawable/ic_ethernet.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2016 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorControlNormal">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M7.77,6.76L6.23,5.48 0.82,12l5.41,6.52 1.54,-1.28L3.42,12l4.35,-5.24zM7,13h2v-2L7,11v2zM17,11h-2v2h2v-2zM11,13h2v-2h-2v2zM17.77,5.48l-1.54,1.28L20.58,12l-4.35,5.24 1.54,1.28L23.18,12l-5.41,-6.52z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/apps/Settings/res/layout/static_ip_dialog.xml b/packages/apps/Settings/res/layout/static_ip_dialog.xml
new file mode 100755
index 0000000..5623a05
--- /dev/null
+++ b/packages/apps/Settings/res/layout/static_ip_dialog.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+     Copyright (C) 2010 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:fadeScrollbars="false">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:paddingBottom="8dip">
+
+        <LinearLayout
+            android:id="@+id/wifi_advanced_fields"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <LinearLayout
+                android:id="@+id/proxy_fields"
+                style="@style/wifi_section"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+
+                <LinearLayout
+                    android:id="@+id/static_ip"
+                    style="@style/wifi_section"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content">
+
+                    <LinearLayout
+                        style="@style/wifi_item"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            style="@style/wifi_item_label"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="@string/ethernet_ip_addr" />
+
+                        <EditText
+                            android:id="@+id/edt_ip"
+                            style="@style/wifi_item_edit_content"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:hint="@string/ethernet_ip_hint"
+                            android:inputType="textNoSuggestions"
+                            android:singleLine="true" />
+                    </LinearLayout>
+
+                    <LinearLayout
+                        style="@style/wifi_item"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            style="@style/wifi_item_label"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="@string/ethernet_gateway" />
+
+                        <EditText
+                            android:id="@+id/edt_gateway"
+                            style="@style/wifi_item_edit_content"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:hint="@string/ethernet_gateway_hint"
+                            android:inputType="textNoSuggestions"
+                            android:singleLine="true" />
+                    </LinearLayout>
+
+                    <LinearLayout
+                        style="@style/wifi_item"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            style="@style/wifi_item_label"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="@string/ethernet_netmask" />
+
+                        <EditText
+                            android:id="@+id/edt_netmask"
+                            style="@style/wifi_item_edit_content"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:hint="@string/ethernet_netmask_hint"
+                            android:inputType="textNoSuggestions"
+                            android:singleLine="true" />
+                    </LinearLayout>
+
+                    <LinearLayout
+                        style="@style/wifi_item"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            style="@style/wifi_item_label"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="@string/ethernet_dns1" />
+
+                        <EditText
+                            android:id="@+id/edt_dns1"
+                            style="@style/wifi_item_edit_content"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:hint="@string/ethernet_dns1_hint"
+                            android:inputType="textNoSuggestions"
+                            android:singleLine="true" />
+                    </LinearLayout>
+
+                    <LinearLayout
+                        style="@style/wifi_item"
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content">
+
+                        <TextView
+                            style="@style/wifi_item_label"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="@string/ethernet_dns2" />
+
+                        <EditText
+                            android:id="@+id/edt_dns2"
+                            style="@style/wifi_item_edit_content"
+                            android:layout_width="match_parent"
+                            android:layout_height="wrap_content"
+                            android:hint="@string/ethernet_dns2_hint"
+                            android:inputType="textNoSuggestions"
+                            android:singleLine="true" />
+                    </LinearLayout>
+                </LinearLayout>
+            </LinearLayout>
+        </LinearLayout>
+    </LinearLayout>
+
+</ScrollView>
\ No newline at end of file
diff --git a/packages/apps/Settings/res/values-en-rGB/strings.xml b/packages/apps/Settings/res/values-en-rGB/strings.xml
old mode 100644
new mode 100755
index 54dcc39..389d059
--- a/packages/apps/Settings/res/values-en-rGB/strings.xml
+++ b/packages/apps/Settings/res/values-en-rGB/strings.xml
@@ -1346,7 +1346,8 @@
     <string name="reset_network_confirm_title" msgid="1759888886976962773">"Reset?"</string>
     <string name="network_reset_not_available" msgid="7188610385577164676">"Network reset is not available for this user"</string>
     <string name="reset_network_complete_toast" msgid="787829973559541880">"Network settings have been reset"</string>
     <string name="master_clear_title" msgid="3531267871084279512">"Erase all data (factory reset)"</string>
+    <string name="ethernet_settings_title">"Ehernet"</string>
     <string name="master_clear_desc" product="tablet" msgid="9146059417023157222">"This will erase all data from your tablet\'s "<b>"internal storage"</b>", including:\n\n"<li>"Your Google account"</li>\n<li>"System and app data and settings"</li>\n<li>"Downloaded apps"</li></string>
     <string name="master_clear_desc" product="default" msgid="4800386183314202571">"This will erase all data from your phone\'s "<b>"internal storage"</b>", including:\n\n"<li>"Your Google account"</li>\n<li>"System and app data and settings"</li>\n<li>"Downloaded apps"</li></string>
     <string name="master_clear_accounts" product="default" msgid="6412857499147999073">\n\n"You are currently signed in to the following accounts:\n"</string>
diff --git a/packages/apps/Settings/res/values-en-rIN/strings.xml b/packages/apps/Settings/res/values-en-rIN/strings.xml
old mode 100644
new mode 100755
index 54dcc39..389d059
--- a/packages/apps/Settings/res/values-en-rIN/strings.xml
+++ b/packages/apps/Settings/res/values-en-rIN/strings.xml
@@ -1346,7 +1346,8 @@
     <string name="reset_network_confirm_title" msgid="1759888886976962773">"Reset?"</string>
     <string name="network_reset_not_available" msgid="7188610385577164676">"Network reset is not available for this user"</string>
     <string name="reset_network_complete_toast" msgid="787829973559541880">"Network settings have been reset"</string>
     <string name="master_clear_title" msgid="3531267871084279512">"Erase all data (factory reset)"</string>
+    <string name="ethernet_settings_title">"Ehernet"</string>
     <string name="master_clear_desc" product="tablet" msgid="9146059417023157222">"This will erase all data from your tablet\'s "<b>"internal storage"</b>", including:\n\n"<li>"Your Google account"</li>\n<li>"System and app data and settings"</li>\n<li>"Downloaded apps"</li></string>
     <string name="master_clear_desc" product="default" msgid="4800386183314202571">"This will erase all data from your phone\'s "<b>"internal storage"</b>", including:\n\n"<li>"Your Google account"</li>\n<li>"System and app data and settings"</li>\n<li>"Downloaded apps"</li></string>
     <string name="master_clear_accounts" product="default" msgid="6412857499147999073">\n\n"You are currently signed in to the following accounts:\n"</string>
diff --git a/packages/apps/Settings/res/values/arrays.xml b/packages/apps/Settings/res/values/arrays.xml
old mode 100644
new mode 100755
index 8ead532..2be86f0
--- a/packages/apps/Settings/res/values/arrays.xml
+++ b/packages/apps/Settings/res/values/arrays.xml
@@ -1070,4 +1115,14 @@
         <item>sdcard</item>
         <item>usb</item>
     </string-array>
+
+    <!--ethernet mode select -->    
+    <string-array name="ethernet_mode_location">
+        <item>@string/ethernet_static</item>
+        <item>@string/ethernet_dhcp</item>
+    </string-array>
+    <string-array name="ethernet_mode_values">
+        <item>StaticIP</item>
+        <item>DHCP</item>
+    </string-array>
 </resources>
diff --git a/packages/apps/Settings/res/values/strings.xml b/packages/apps/Settings/res/values/strings.xml
old mode 100644
new mode 100755
index 0f95516..f8c1741
--- a/packages/apps/Settings/res/values/strings.xml
+++ b/packages/apps/Settings/res/values/strings.xml
@@ -2386,8 +2386,10 @@
     <string name="accelerometer_summary_off" product="default">Switch orientation automatically when rotating phone</string>
     <!-- Sound & display settings screen, setting option name to change brightness level -->
     <string name="brightness">Brightness level</string>
     <string name="brightness_ext">Extern Brightness level</string>
     <!-- Sound & display settings screen, setting option name to change brightness level [CHAR LIMIT=30] -->
     <string name="brightness_title">Brightness</string>
     <string name="brightness_ext_title">Extern Brightness</string>
     <!-- Sound & display settings screen, setting option summary to change brightness level -->
     <string name="brightness_summary">Adjust the brightness of the screen</string>
     <!-- Sound & display settings screen, setting option name to enable adaptive brightness [CHAR LIMIT=30] -->
@@ -2639,6 +2641,9 @@
     <string name="build_number">Build number</string>
     <!-- About phone screen,  setting option name  [CHAR LIMIT=40] -->
     <string name="selinux_status">SELinux status</string>
     <string name="tb_firmware_version">Firmware version</string>
     <string name="tb_rom_version">ROM version</string>
     <string name="tb_hardware_version">Hardware version</string>
 
     <!-- About phone screen, show when a value of some status item is unavailable. -->
     <string name="device_info_not_available">Not available</string>
@@ -3156,6 +3161,29 @@
     <!-- Reset settings complete toast text [CHAR LIMIT=75] -->
     <string name="reset_network_complete_toast">Network settings have been reset</string>
 
+    <!-- Ethernet Settings -->
+    <string name="ethernet_ip_hint" translatable="false"> 192.168.0.100</string>
+    <string name="ethernet_gateway_hint" translatable="false"> 192.168.0.1</string>
+    <string name="ethernet_netmask_hint" translatable="false"> 255.255.255.0</string>
+    <string name="ethernet_dns1_hint" translatable="false"> 0.0.0.0</string>
+    <string name="ethernet_dns2_hint" translatable="false"> 0.0.0.0</string>
+
+    <string name="ethernet_mac">MAC</string>
+    <string name="ethernet_ip_addr">IP Address</string>
+    <string name="ethernet_netmask">Network Mask</string>
+    <string name="ethernet_gateway">Gateway</string>
+    <string name="ethernet_dns1">DNS 1</string>
+    <string name="ethernet_dns2">DNS 2</string>
+
+    <string name="ethernet_settings_title">Ethernet</string>
+    <string name="ethernet_settings">Ethernet</string>
+    <string name="ethernet_connect">Connect</string>
+    <string name="ethernet_cancel">Cancel</string>
+    <string name="ethernet_dhcp">DHCP</string>
+    <string name="ethernet_static">Static</string>
+    <string name="ethernet_mode_title">Ethernet IP Mode</string>
+    <string name="ethernet_info_getting">Getting IP…</string>
+
     <!-- Master Clear -->
     <!-- Button title to factory data reset the entire device -->
     <string name="master_clear_title">Erase all data (factory reset)</string>
diff --git a/packages/apps/Settings/res/xml/ethernet_settings.xml b/packages/apps/Settings/res/xml/ethernet_settings.xml
new file mode 100755
index 0000000..5394734
--- /dev/null
+++ b/packages/apps/Settings/res/xml/ethernet_settings.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+    android:title="@string/ethernet_settings">
+
+    <!--ethernet mac-->
+    <Preference
+        style="?android:preferenceInformationStyle"
+        android:key="ethernet_mac"
+        android:summary="@string/device_info_default"
+        android:title="@string/ethernet_mac" />
+
+    <!-- ethernet ip address -->
+    <Preference
+        style="?android:preferenceInformationStyle"
+        android:key="ethernet_ip_addr"
+        android:summary="@string/device_info_default"
+        android:title="@string/ethernet_ip_addr" />
+
+    <!-- ethernet netmask -->
+    <Preference
+        style="?android:preferenceInformationStyle"
+        android:key="ethernet_netmask"
+        android:summary="@string/device_info_default"
+        android:title="@string/ethernet_netmask" />
+
+    <!-- ethernet mGatewayEdt -->
+    <Preference
+        style="?android:preferenceInformationStyle"
+        android:key="ethernet_gateway"
+        android:summary="@string/device_info_default"
+        android:title="@string/ethernet_gateway" />
+
+    <!-- ethernet mDns1Edt -->
+    <Preference
+        style="?android:preferenceInformationStyle"
+        android:key="ethernet_dns1"
+        android:summary="@string/device_info_default"
+        android:title="@string/ethernet_dns1" />
+
+    <!-- ethernet mDns2Edt -->
+    <Preference
+        style="?android:preferenceInformationStyle"
+        android:key="ethernet_dns2"
+        android:summary="@string/device_info_default"
+        android:title="@string/ethernet_dns2" />
+
+    <ListPreference
+        android:entries="@array/ethernet_mode_location"
+        android:entryValues="@array/ethernet_mode_values"
+        android:key="ethernet_mode_select"
+        android:persistent="true"
+        android:title="@string/ethernet_mode_title" />
+
+</PreferenceScreen>
diff --git a/packages/apps/Settings/res/xml/network_and_internet.xml b/packages/apps/Settings/res/xml/network_and_internet.xml
old mode 100644
new mode 100755
index ee25bee..17281fa
--- a/packages/apps/Settings/res/xml/network_and_internet.xml
+++ b/packages/apps/Settings/res/xml/network_and_internet.xml
@@ -85,5 +85,13 @@
         android:fragment="com.android.settings.ProxySelector"
         android:key="proxy_settings"
         android:title="@string/proxy_settings_title"/>
+
+    <com.android.settingslib.RestrictedPreference
+        android:key="ethernet_settings"
+        android:title="@string/ethernet_settings_title"
+        android:icon="@drawable/ic_ethernet"
+        settings:userRestriction="no_ethernet_settings"
+        settings:useAdminDisabledSummary="true"
+        android:fragment="com.android.settings.ethernet.EthernetSettings" />
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java b/packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java
new file mode 100755
index 0000000..5c966aa
--- /dev/null
+++ b/packages/apps/Settings/src/com/android/settings/ethernet/EthernetSettings.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 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.
+ */
+package com.android.settings.ethernet;
+
+import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.EthernetManager;
+import android.net.IpConfiguration;
+import android.net.IpConfiguration.IpAssignment;
+import android.net.IpConfiguration.ProxySettings;
+import android.net.LinkAddress;
+import android.net.NetworkUtils;
+import android.net.StaticIpConfiguration;
+import android.os.Bundle;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+public class EthernetSettings extends SettingsPreferenceFragment
+        implements DialogInterface.OnClickListener, Preference.OnPreferenceChangeListener {
+    private static final String TAG = "EthernetSettings";
+
+    private static final int CONFIG_STATIC_IP_DIALOG = 0;
+
+    private static final String KEY_ETH_IP_ADDRESS = "ethernet_ip_addr";
+    private static final String KEY_ETH_HW_ADDRESS = "ethernet_mac";
+    private static final String KEY_ETH_NET_MASK = "ethernet_netmask";
+    private static final String KEY_ETH_GATEWAY = "ethernet_gateway";
+    private static final String KEY_ETH_DNS1 = "ethernet_dns1";
+    private static final String KEY_ETH_DNS2 = "ethernet_dns2";
+    private static final String KEY_ETH_MODE = "ethernet_mode_select";
+
+    private final static String NULL_IP = "0.0.0.0";
+
+    private static String sEthMac = null;
+    private static String sEthIpAddress = null;
+    private static String sEthNetMask = null;
+    private static String sEthGateway = null;
+    private static String sEthDns1 = null;
+    private static String sEthDns2 = null;
+
+    private Context mContext;
+    private ListPreference mEthMode;
+    private IpConfiguration mIpConfiguration;
+    private EthernetManager mEthManager;
+
+    private EthernetStaticIpDialog mStaticIpDialog;
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsEvent.WIFI_TETHER_SETTINGS;
+    }
+
+    @Override
+    public int getDialogMetricsCategory(int dialogId) {
+        switch (dialogId) {
+            case CONFIG_STATIC_IP_DIALOG:
+                return MetricsEvent.WIFI_TETHER_SETTINGS;
+            default:
+                return 0;
+        }
+    }
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (EthernetManager.ETHERNET_STATE_CHANGED_ACTION.equals(action)) {
+                int EtherState = intent.getIntExtra(
+                        EthernetManager.EXTRA_ETHERNET_STATE,
+                        -1);
+                handleEtherStateChange(EtherState);
+            }
+        }
+    };
+
+    private void handleEtherStateChange(int state) {
+        Log.i(TAG, "handleEtherStateChange, state" + state);
+
+        switch (state) {
+            case EthernetManager.ETHER_STATE_DISCONNECTED:
+                sEthIpAddress = NULL_IP;
+                sEthNetMask = NULL_IP;
+                sEthGateway = NULL_IP;
+                sEthDns1 = NULL_IP;
+                sEthDns2 = NULL_IP;
+                break;
+
+            case EthernetManager.ETHER_STATE_CONNECTING:
+                String statusStr = mContext.getString(R.string.ethernet_info_getting);
+                sEthIpAddress = statusStr;
+                sEthNetMask = statusStr;
+                sEthGateway = statusStr;
+                sEthDns1 = statusStr;
+                sEthDns2 = statusStr;
+                break;
+
+            case EthernetManager.ETHER_STATE_CONNECTED:
+                getEthInfo();
+                break;
+        }
+
+        update();
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        addPreferencesFromResource(R.xml.ethernet_settings);
+
+        mEthManager = (EthernetManager) getSystemService(Context.ETHERNET_SERVICE);
+        if (mEthManager == null) {
+            Log.e(TAG, "onCreate, Get ethernet manager failed.");
+            return;
+        }
+
+        sEthMac = getEth0Mac();
+        mContext = this.getActivity().getApplicationContext();
+    }
+
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        if (mEthMode == null) {
+            mEthMode = (ListPreference) findPreference(KEY_ETH_MODE);
+            mEthMode.setOnPreferenceChangeListener(this);
+        }
+
+        handleEtherStateChange(mEthManager.getEthernetConnectState());
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        mContext.registerReceiver(mReceiver, new IntentFilter(
+                EthernetManager.ETHERNET_STATE_CHANGED_ACTION));
+    }
+
+    @Override
+    public void onStop() {
+        mContext.unregisterReceiver(mReceiver);
+
+        super.onStop();
+    }
+
+    private void setStringSummary(String preference, String value) {
+        try {
+            findPreference(preference).setSummary(value);
+        } catch (RuntimeException e) {
+            findPreference(preference).setSummary("");
+        }
+    }
+
+    private String getStringFromPref(String preference) {
+        try {
+            return findPreference(preference).getSummary().toString();
+        } catch (RuntimeException e) {
+            return null;
+        }
+    }
+
+    private void update() {
+        setStringSummary(KEY_ETH_HW_ADDRESS, sEthMac);
+        setStringSummary(KEY_ETH_IP_ADDRESS, sEthIpAddress);
+        setStringSummary(KEY_ETH_NET_MASK, sEthNetMask);
+        setStringSummary(KEY_ETH_GATEWAY, sEthGateway);
+        setStringSummary(KEY_ETH_DNS1, sEthDns1);
+        setStringSummary(KEY_ETH_DNS2, sEthDns2);
+
+        updateEthMode();
+    }
+
+    private void updateEthMode() {
+        if (mEthManager == null) {
+            mEthMode.setSummary("null");
+        } else {
+            if (mEthManager.getConfiguration().ipAssignment == IpAssignment.DHCP) {
+                mEthMode.setValue("DHCP");
+                mEthMode.setSummary(R.string.ethernet_dhcp);
+            } else {
+                mEthMode.setValue("StaticIP");
+                mEthMode.setSummary(R.string.ethernet_static);
+            }
+        }
+    }
+
+    @Override
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        if (preference == mEthMode) {
+            String value = (String) newValue;
+            if (value.equals("DHCP")) {
+                mEthManager.setConfiguration(new IpConfiguration(IpAssignment.DHCP,
+                        ProxySettings.NONE, null, null));
+            } else if (value.equals("StaticIP")) {
+                this.showDialog(CONFIG_STATIC_IP_DIALOG);
+            }
+        }
+        return true;
+    }
+
+    private Inet4Address getIPv4Address(String text) {
+        try {
+            return (Inet4Address) NetworkUtils.numericToInetAddress(text);
+        } catch (IllegalArgumentException | ClassCastException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Convert netmask
+     *
+     * @param prefixLength
+     * @return
+     */
+    private String interMask2String(int prefixLength) {
+        String netMask = null;
+        int inetMask = prefixLength;
+
+        int part = inetMask / 8;
+        int remainder = inetMask % 8;
+        int sum = 0;
+
+        for (int i = 8; i > 8 - remainder; i--) {
+            sum = sum + (int) Math.pow(2, i - 1);
+        }
+
+        if (part == 0) {
+            netMask = sum + ".0.0.0";
+        } else if (part == 1) {
+            netMask = "255." + sum + ".0.0";
+        } else if (part == 2) {
+            netMask = "255.255." + sum + ".0";
+        } else if (part == 3) {
+            netMask = "255.255.255." + sum;
+        } else if (part == 4) {
+            netMask = "255.255.255.255";
+        }
+
+        return netMask;
+    }
+
+    /*
+     * convert subMask string to prefix length
+     */
+    private int maskStr2InetMask(String maskStr) {
+        StringBuffer sb;
+        String str;
+        int inetmask = 0;
+        int count = 0;
+        /*
+         * check the subMask format
+         */
+        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$");
+        if (!pattern.matcher(maskStr).matches()) {
+            Log.e(TAG, "subMask is error");
+            return 0;
+        }
+
+        String[] ipSegment = maskStr.split("\\.");
+        for (int n = 0; n < ipSegment.length; n++) {
+            sb = new StringBuffer(Integer.toBinaryString(Integer.parseInt(ipSegment[n])));
+            str = sb.reverse().toString();
+            count = 0;
+            for (int i = 0; i < str.length(); i++) {
+                i = str.indexOf("1", i);
+                if (i == -1)
+                    break;
+                count++;
+            }
+            inetmask += count;
+        }
+        return inetmask;
+    }
+
+    private boolean setStaticIpConfiguration() {
+        StaticIpConfiguration staticIpConfiguration = new StaticIpConfiguration();
+
+        Inet4Address inet = getIPv4Address(sEthIpAddress);
+        int prefixLength = maskStr2InetMask(sEthNetMask);
+        InetAddress gateway = getIPv4Address(sEthGateway);
+        InetAddress dns = getIPv4Address(sEthDns1);
+
+        if (null == inet || null == gateway || null == dns
+                || inet.getAddress().length <= 0
+                || prefixLength == 0
+                || gateway.toString().isEmpty()
+                || dns.toString().isEmpty()) {
+            Log.e(TAG, "setStaticIpConfiguration, ip, mask or dns is wrong");
+            return false;
+        }
+
+        staticIpConfiguration.ipAddress = new LinkAddress(inet, prefixLength);
+        staticIpConfiguration.gateway = gateway;
+        staticIpConfiguration.dnsServers.add(dns);
+
+        if (!sEthDns2.isEmpty()) {
+            staticIpConfiguration.dnsServers.add(getIPv4Address(sEthDns2));
+        }
+        mIpConfiguration = new IpConfiguration(IpAssignment.STATIC, ProxySettings.NONE, staticIpConfiguration, null);
+
+        return true;
+    }
+
+    private void getEthInfoFromDhcp() {
+        String tempIpInfo;
+
+        tempIpInfo = mEthManager.getIpAddress();
+
+        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
+            sEthIpAddress = tempIpInfo;
+        } else {
+            sEthIpAddress = NULL_IP;
+        }
+
+        tempIpInfo = mEthManager.getNetmask();
+        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
+            sEthNetMask = tempIpInfo;
+        } else {
+            sEthNetMask = NULL_IP;
+        }
+
+        tempIpInfo = mEthManager.getGateway();
+        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
+            sEthGateway = tempIpInfo;
+        } else {
+            sEthGateway = NULL_IP;
+        }
+
+        tempIpInfo = mEthManager.getDns();
+        if ((tempIpInfo != null) && (!tempIpInfo.equals(""))) {
+            String data[] = tempIpInfo.split(",");
+            sEthDns1 = data[0];
+            if (data.length <= 1) {
+                sEthDns2 = NULL_IP;
+            } else {
+                sEthDns2 = data[1];
+            }
+        } else {
+            sEthDns1 = NULL_IP;
+        }
+    }
+
+    private void getEthInfoFromStaticIp() {
+        StaticIpConfiguration staticIpConfiguration = mEthManager.getConfiguration().getStaticIpConfiguration();
+
+        if (staticIpConfiguration == null) {
+            Log.w(TAG, "getEthInfoFromStaticIp, staticIpConfiguration is null");
+            return;
+        }
+
+        LinkAddress ipAddress = staticIpConfiguration.ipAddress;
+        InetAddress gateway = staticIpConfiguration.gateway;
+        ArrayList<InetAddress> dnsServers = staticIpConfiguration.dnsServers;
+
+        if (ipAddress != null) {
+            sEthIpAddress = ipAddress.getAddress().getHostAddress();
+            sEthNetMask = interMask2String(ipAddress.getPrefixLength());
+        }
+
+        if (gateway != null) {
+            sEthGateway = gateway.getHostAddress();
+        }
+
+        sEthDns1 = dnsServers.get(0).getHostAddress();
+        if (dnsServers.size() > 1) {
+            sEthDns2 = dnsServers.get(1).getHostAddress();
+        }
+    }
+
+    private void getEthInfo() {
+        IpAssignment mode = mEthManager.getConfiguration().getIpAssignment();
+        if (mode == IpAssignment.DHCP) {
+            getEthInfoFromDhcp();
+        } else if (mode == IpAssignment.STATIC) {
+            getEthInfoFromStaticIp();
+        }
+    }
+
+    private static String getEth0Mac() {
+        if (TextUtils.isEmpty(sEthMac)) {
+            try {
+                int numRead = 0;
+                char[] buf = new char[1024];
+                StringBuffer strBuf = new StringBuffer(1000);
+                BufferedReader reader = new BufferedReader(new FileReader(
+                        "/sys/class/net/eth0/address"));
+                while ((numRead = reader.read(buf)) != -1) {
+                    String readData = String.valueOf(buf, 0, numRead);
+                    strBuf.append(readData);
+                }
+                sEthMac = strBuf.toString().replaceAll("\r|\n", "");
+                reader.close();
+            } catch (IOException ex) {
+                Log.w(TAG, "eth0 mac not exist");
+            }
+        }
+        return sEthMac;
+    }
+
+    @Override
+    public void onClick(DialogInterface dialogInterface, int button) {
+        if (button == EthernetStaticIpDialog.BUTTON_SUBMIT) {
+            mStaticIpDialog.saveIpSettingInfo();
+            if (setStaticIpConfiguration()) {
+                mEthManager.setConfiguration(mIpConfiguration);
+            } else {
+                Log.e(TAG, "Set configuration failed: " + mIpConfiguration.toString());
+            }
+        }
+        updateEthMode();
+    }
+
+    @Override
+    public Dialog onCreateDialog(int dialogId) {
+        switch (dialogId) {
+            case CONFIG_STATIC_IP_DIALOG:
+                mStaticIpDialog = new EthernetStaticIpDialog(getActivity(),
+                        false, this, mStaticIpListener);
+                return mStaticIpDialog;
+        }
+        return super.onCreateDialog(dialogId);
+    }
+
+    private IStaticIpListener mStaticIpListener = new IStaticIpListener() {
+
+        public boolean getStaticIp(String ipAddr) {
+            sEthIpAddress = ipAddr;
+
+            Log.i(TAG, "getStaticIp, ipAddr: " + ipAddr);
+            return true;
+        }
+
+        public boolean getStaticNetMask(String netMask) {
+            sEthNetMask = netMask;
+
+            Log.i(TAG, "getStaticNetMask, netMask: " + netMask);
+            return true;
+        }
+
+        public boolean getStaticGateway(String gateway) {
+            sEthGateway = gateway;
+
+            Log.i(TAG, "getStaticGateway, mGatewayEdt: " + gateway);
+            return true;
+        }
+
+        public boolean getStaticDns1(String dns1) {
+            sEthDns1 = dns1;
+
+            Log.i(TAG, "getStaticDns1, mDns1Edt: " + dns1);
+            return true;
+        }
+
+        public boolean getStaticDns2(String dns2) {
+            sEthDns2 = dns2;
+
+            Log.i(TAG, "getStaticDns2, mDns2Edt: " + dns2);
+            return true;
+        }
+    };
+}
\ No newline at end of file
diff --git a/packages/apps/Settings/src/com/android/settings/ethernet/EthernetStaticIpDialog.java b/packages/apps/Settings/src/com/android/settings/ethernet/EthernetStaticIpDialog.java
new file mode 100755
index 0000000..4a98651
--- /dev/null
+++ b/packages/apps/Settings/src/com/android/settings/ethernet/EthernetStaticIpDialog.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+package com.android.settings.ethernet;
+
+import android.annotation.SuppressLint;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.EthernetManager;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+
+import com.android.settings.R;
+
+import java.util.regex.Pattern;
+
+class EthernetStaticIpDialog extends AlertDialog implements TextWatcher {
+
+    private IStaticIpListener mStaticIpListener;
+    private EditText mIpEdt;
+    private EditText mGatewayEdt;
+    private EditText mNetmaskEdt;
+    private EditText mDns1Edt;
+    private EditText mDns2Edt;
+
+    @SuppressLint("InlinedApi")
+    static final int BUTTON_SUBMIT = DialogInterface.BUTTON_POSITIVE;
+    @SuppressLint("InlinedApi")
+    static final int BUTTON_FORGET = DialogInterface.BUTTON_NEUTRAL;
+
+    private final static String NULL_IP = "0.0.0.0";
+
+    private Context mContext;
+    private EthernetManager mEthManager;
+    private DialogInterface.OnClickListener mListener;
+
+    EthernetStaticIpDialog(Context context, boolean cancelable,
+                           DialogInterface.OnClickListener listener, IStaticIpListener staticIpListener) {
+        super(context);
+        mContext = context;
+        mListener = listener;
+        mStaticIpListener = staticIpListener;
+    }
+
+    protected EthernetStaticIpDialog(Context context) {
+        super(context);
+    }
+
+    protected EthernetStaticIpDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
+        super(context, cancelable, cancelListener);
+    }
+
+    protected EthernetStaticIpDialog(Context context, int themeResId) {
+        super(context, themeResId);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        View view = getLayoutInflater().inflate(R.layout.static_ip_dialog, null);
+        setView(view);
+        setInverseBackgroundForced(true);
+
+        mIpEdt = (EditText) view.findViewById(R.id.edt_ip);
+        mNetmaskEdt = (EditText) view.findViewById(R.id.edt_netmask);
+        mGatewayEdt = (EditText) view.findViewById(R.id.edt_gateway);
+        mDns1Edt = (EditText) view.findViewById(R.id.edt_dns1);
+        mDns2Edt = (EditText) view.findViewById(R.id.edt_dns2);
+
+        mIpEdt.addTextChangedListener(this);
+        mNetmaskEdt.addTextChangedListener(this);
+        mGatewayEdt.addTextChangedListener(this);
+        mDns1Edt.addTextChangedListener(this);
+        mDns2Edt.addTextChangedListener(this);
+
+        setButton(BUTTON_SUBMIT, mContext.getString(R.string.ethernet_connect), mListener);
+        setButton(BUTTON_NEGATIVE, mContext.getString(R.string.ethernet_cancel), mListener);
+        setTitle(mContext.getString(R.string.ethernet_settings));
+
+        mEthManager = (EthernetManager) mContext.getSystemService(Context.ETHERNET_SERVICE);
+
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        updateIpSettingsInfo();
+        checkIPValue();
+    }
+
+    private void updateIpSettingsInfo() {
+        String ip = mEthManager.getIpAddress();
+        if (!TextUtils.isEmpty(ip)) {
+            mIpEdt.setText(ip);
+        }
+
+        String netMask = mEthManager.getNetmask();
+        if (!TextUtils.isEmpty(netMask)) {
+            mNetmaskEdt.setText(netMask);
+        }
+
+        String gateway = mEthManager.getGateway();
+        if (!TextUtils.isEmpty(gateway)) {
+            mGatewayEdt.setText(gateway);
+        }
+
+        String dns = mEthManager.getDns();
+        String dns1 = NULL_IP;
+        String dns2 = NULL_IP;
+        if (!TextUtils.isEmpty(dns)) {
+            String data[] = dns.split(",");
+            dns1 = data[0];
+            if (data.length > 1)
+                dns2 = data[1];
+        }
+        if (!TextUtils.isEmpty(dns1)) {
+            mDns1Edt.setText(dns1);
+        }
+        if (!TextUtils.isEmpty(dns2)) {
+            mDns2Edt.setText(dns2);
+        }
+    }
+
+    void saveIpSettingInfo() {
+        String ip = mIpEdt.getText().toString();
+        String gateway = mGatewayEdt.getText().toString();
+        String netMask = mNetmaskEdt.getText().toString();
+        String dns1 = mDns1Edt.getText().toString();
+        String dns2 = mDns2Edt.getText().toString();
+
+        mStaticIpListener.getStaticIp(ip);
+        mStaticIpListener.getStaticNetMask(netMask);
+        mStaticIpListener.getStaticGateway(gateway);
+        mStaticIpListener.getStaticDns1(dns1);
+        mStaticIpListener.getStaticDns2(dns2);
+    }
+
+    private boolean isValidIpAddress(String value) {
+        int start = 0;
+        int end = value.indexOf('.');
+        int numBlocks = 0;
+
+        while (start < value.length()) {
+            if (-1 == end) {
+                end = value.length();
+            }
+
+            try {
+                int block = Integer.parseInt(value.substring(start, end));
+                if ((block > 255) || (block < 0)) {
+                    Log.w("EthernetIP",
+                            "isValidIpAddress() : invalid 'block', block = "
+                                    + block);
+                    return false;
+                }
+            } catch (NumberFormatException e) {
+                Log.w("EthernetIP", "isValidIpAddress() : e = " + e);
+                return false;
+            }
+
+            numBlocks++;
+
+            start = end + 1;
+            end = value.indexOf('.', start);
+        }
+        return numBlocks == 4;
+    }
+
+    private void checkIPValue() {
+        boolean enable = false;
+
+        String ip = mIpEdt.getText().toString();
+        String gateway = mGatewayEdt.getText().toString();
+        String dns1 = mDns1Edt.getText().toString();
+        String dns2 = mDns2Edt.getText().toString();
+        String netMask = mNetmaskEdt.getText().toString();
+
+        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$"); /*check subnet mask*/
+        if (isValidIpAddress(ip) && isValidIpAddress(gateway)
+                && isValidIpAddress(dns1) && (pattern.matcher(netMask).matches())) {
+            if (TextUtils.isEmpty(dns2)) {
+                enable = true;
+            } else {
+                enable = isValidIpAddress(dns2);
+            }
+        }
+
+        getButton(BUTTON_SUBMIT).setEnabled(enable);
+
+    }
+
+    @Override
+    public void afterTextChanged(Editable s) {
+        checkIPValue();
+    }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count,
+                                  int after) {
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+}
\ No newline at end of file
diff --git a/packages/apps/Settings/src/com/android/settings/ethernet/IStaticIpListener.java b/packages/apps/Settings/src/com/android/settings/ethernet/IStaticIpListener.java
new file mode 100755
index 0000000..b2b7dfb
--- /dev/null
+++ b/packages/apps/Settings/src/com/android/settings/ethernet/IStaticIpListener.java
@@ -0,0 +1,9 @@
+package com.android.settings.ethernet;
+
+public interface IStaticIpListener {
+	public boolean getStaticIp(String ip);
+	public boolean getStaticNetMask(String netMask);
+	public boolean getStaticGateway(String gateway);
+	public boolean getStaticDns1(String dns1);
+	public boolean getStaticDns2(String dns2);
+}
\ No newline at end of file

解决修改以太网配置后立即断电配置丢失问题

因为以太网配置结果是保存在本地文件中,当设置完成后立即断电,文件还在缓存中,并未真正写到磁盘,所以会导致配置丢失。这里在修改配置完成后增加磁盘同步,强制文件写入磁盘,从而解决断电配置丢失问题。

commit abdc52ad35ba218c09f7ac4f84b2a653bd6220f5
Author: shenhb <shenhb@topband.com.cn>
Date:   Tue Nov 12 15:02:02 2019 +0800

    【以太网】解决修改以太网配置项后立即断电配置丢失问题

diff --git a/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetConfigStore.java b/frameworks/op
index dad5dea..7d38693 100755
--- a/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetConfigStore.java
+++ b/frameworks/opt/net/ethernet/java/com/android/server/ethernet/EthernetConfigStore.java
@@ -25,6 +25,7 @@ import android.util.SparseArray;
 import android.os.SystemProperties;
 import com.android.server.net.IpConfigStore;
 import java.io.File;
+import java.io.IOException;
 
 /**
  * This class provides an API to store and manage Ethernet network configuration.
@@ -64,5 +65,10 @@ public class EthernetConfigStore extends IpConfigStore {
         SparseArray<IpConfiguration> networks = new SparseArray<IpConfiguration>();
         networks.put(0, config);
         writeIpAndProxyConfigurations(ipConfigFile, networks);
+        try {
+            Runtime.getRuntime().exec("sync");
+        } catch (IOException e) {
+            Log.e(TAG, "writeIpAndProxyConfigurations, sync error: " + e.getMessage());
+        }
     }
 }

二、Android支持多摄像头

某些平台默认只支持2个摄像头,但随着 AI 越来越热门,图像识别应用越来越广泛,我们经常需要用到更多的摄像头。下面修改使 Android 能够支持最多10个摄像头。

commit 840a47894a1160cdc96189113c5e9ba82efbeaab
Author: shenhb <shenhb@topband.com.cn>
Date:   Mon Dec 17 17:09:35 2018 +0800

    【摄像头】支持大于2个摄像头

diff --git a/hardware/rockchip/camera/CameraHal/CameraHal_Module.cpp b/hardware/rockchip/camera/CameraHal/CameraHal_Module.cpp
index 3365339..0f58fa4 100755
--- a/hardware/rockchip/camera/CameraHal/CameraHal_Module.cpp
+++ b/hardware/rockchip/camera/CameraHal/CameraHal_Module.cpp
@@ -787,18 +787,18 @@ int camera_get_number_of_cameras(void)
         	if(profiles->mDevieVector[i]->mIsConnect==1){
     	        rk_sensor_info *pSensorInfo = &(profiles->mDevieVector[i]->mHardInfo.mSensorInfo);
     	        
-    	        camInfoTmp[cam_cnt&0x01].pcam_total_info = profiles->mDevieVector[i];     
-    	        strncpy(camInfoTmp[cam_cnt&0x01].device_path, pSensorInfo->mCamsysDevPath, sizeof(camInfoTmp[cam_cnt&0x01].device_path));
-    	        strncpy(camInfoTmp[cam_cnt&0x01].driver, pSensorInfo->mSensorDriver, sizeof(camInfoTmp[cam_cnt&0x01].driver));
+    	        camInfoTmp[cam_cnt].pcam_total_info = profiles->mDevieVector[i];     
+    	        strncpy(camInfoTmp[cam_cnt].device_path, pSensorInfo->mCamsysDevPath, sizeof(camInfoTmp[cam_cnt].device_path));
+    	        strncpy(camInfoTmp[cam_cnt].driver, pSensorInfo->mSensorDriver, sizeof(camInfoTmp[cam_cnt].driver));
 				unsigned int SensorDrvVersion = profiles->mDevieVector[i]->mLoadSensorInfo.mpI2cInfo->sensor_drv_version;
 				memset(version,0x00,sizeof(version));
     	        sprintf(version,"%d.%d.%d",((SensorDrvVersion&0xff0000)>>16),
 	    	            ((SensorDrvVersion&0xff00)>>8),SensorDrvVersion&0xff);
 						 
     	        if(pSensorInfo->mFacing == RK_CAM_FACING_FRONT){     
-    	            camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT;	    	        
+    	            camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;	    	        
     	        } else {
-    	            camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_BACK;
+    	            camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_BACK;
     	        } 
 
                 memset(sensor_ver,0x00,sizeof(sensor_ver));
@@ -808,7 +808,7 @@ int camera_get_number_of_cameras(void)
                     sprintf(sensor_ver,"%s",pSensorInfo->mSensorName);                
                 property_set(sensor_ver, version);	
                 
-    	        camInfoTmp[cam_cnt&0x01].facing_info.orientation = pSensorInfo->mOrientation;
+    	        camInfoTmp[cam_cnt].facing_info.orientation = pSensorInfo->mOrientation;
     	        cam_cnt++;
 
     			unsigned int CamsysDrvVersion = profiles->mDevieVector[i]->mCamsysVersion.drv_ver;
@@ -842,7 +842,7 @@ int camera_get_number_of_cameras(void)
             fd = open(cam_path, O_RDONLY);
             if (fd < 0) {
                 LOGE("Open %s failed! strr: %s",cam_path,strerror(errno));
-                break;
+                continue;
             } 
             LOGD("Open %s success!",cam_path);
 
@@ -856,31 +856,32 @@ int camera_get_number_of_cameras(void)
         	    LOGD("Video device(%s): video capture not supported.\n",cam_path);
             } else {
             	rk_cam_total_info* pNewCamInfo = new rk_cam_total_info();
-                memset(camInfoTmp[cam_cnt&0x01].device_path,0x00, sizeof(camInfoTmp[cam_cnt&0x01].device_path));
-                strcat(camInfoTmp[cam_cnt&0x01].device_path,cam_path);
-                memset(camInfoTmp[cam_cnt&0x01].fival_list,0x00, sizeof(camInfoTmp[cam_cnt&0x01].fival_list));
-                memcpy(camInfoTmp[cam_cnt&0x01].driver,capability.driver, sizeof(camInfoTmp[cam_cnt&0x01].driver));
-                camInfoTmp[cam_cnt&0x01].version = capability.version;
+                memset(camInfoTmp[cam_cnt].device_path,0x00, sizeof(camInfoTmp[cam_cnt].device_path));
+                strcat(camInfoTmp[cam_cnt].device_path,cam_path);
+                memset(camInfoTmp[cam_cnt].fival_list,0x00, sizeof(camInfoTmp[cam_cnt].fival_list));
+                memcpy(camInfoTmp[cam_cnt].driver,capability.driver, sizeof(camInfoTmp[cam_cnt].driver));
+                camInfoTmp[cam_cnt].version = capability.version;
+
                 if (strstr((char*)&capability.card[0], "front") != NULL) {
-                    camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT;
+                    camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;
 #ifdef LAPTOP
                 } else if (strstr((char*)&capability.card[0], "HP HD") != NULL
                     || strstr((char*)&capability.card[0], "HP IR")) {
-                    camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT;
+                    camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;
                     if (strstr((char*)&capability.card[0], "HP IR"))
                         gCamerasUnavailabled++;
-                    gUsbCameraNames[cam_cnt&0x01] = String8((char*)&capability.card[0]);
-                    LOGD("Camera %d name: %s", (cam_cnt&0x01), gUsbCameraNames[cam_cnt&0x01].string());
+                    gUsbCameraNames[cam_cnt] = String8((char*)&capability.card[0]);
+                    LOGD("Camera %d name: %s", (cam_cnt), gUsbCameraNames[cam_cnt].string());
 #endif
                 } else {
-                    camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_BACK;
+                    camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_BACK;
                 }  
                 ptr = strstr((char*)&capability.card[0],"-");
                 if (ptr != NULL) {
                     ptr++;
-                    camInfoTmp[cam_cnt&0x01].facing_info.orientation = atoi(ptr);
+                    camInfoTmp[cam_cnt].facing_info.orientation = atoi(ptr);
                 } else {
-                    camInfoTmp[cam_cnt&0x01].facing_info.orientation = 0;
+                    camInfoTmp[cam_cnt].facing_info.orientation = 0;
                 }
 
                 memset(version,0x00,sizeof(version));
@@ -1207,17 +1208,17 @@ int camera_get_number_of_cameras(void)
     }
 #endif    
 
-    #if CONFIG_CAMERA_SINGLE_SENSOR_FORCE_BACK_FOR_CTS
+#if CONFIG_CAMERA_SINGLE_SENSOR_FORCE_BACK_FOR_CTS
     if ((gCamerasNumber==1) && (camInfoTmp[0].facing_info.facing==CAMERA_FACING_FRONT)) {
         gCamerasNumber = 2;
         memcpy(&camInfoTmp[1],&camInfoTmp[0], sizeof(rk_cam_info_t));
         camInfoTmp[1].facing_info.facing = CAMERA_FACING_BACK;
     }
-    #endif
+#endif
     
-    memcpy(&gCamInfos[0], &camInfoTmp[0], sizeof(rk_cam_info_t));
-    memcpy(&gCamInfos[1], &camInfoTmp[1], sizeof(rk_cam_info_t));
-
+    for (int i = 0; i < gCamerasNumber; i++) {
+        memcpy(&gCamInfos[i], &camInfoTmp[i], sizeof(rk_cam_info_t));
+    }
 
     property_get("ro.sf.hwrotation", property, "0");
     hwrotation = strtol(property,0,0);
@@ -1294,22 +1295,22 @@ int camera_get_number_of_cameras(void)
         if ((capability.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)) != (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)) {
     	    LOGD("Video device(%s): video capture not supported.\n",cam_path);
         } else {
-            memset(camInfoTmp[cam_cnt&0x01].device_path,0x00, sizeof(camInfoTmp[cam_cnt&0x01].device_path));
-            strcat(camInfoTmp[cam_cnt&0x01].device_path,cam_path);
-            memset(camInfoTmp[cam_cnt&0x01].fival_list,0x00, sizeof(camInfoTmp[cam_cnt&0x01].fival_list));
-            memcpy(camInfoTmp[cam_cnt&0x01].driver,capability.driver, sizeof(camInfoTmp[cam_cnt&0x01].driver));
-            camInfoTmp[cam_cnt&0x01].version = capability.version;
+            memset(camInfoTmp[cam_cnt].device_path,0x00, sizeof(camInfoTmp[cam_cnt].device_path));
+            strcat(camInfoTmp[cam_cnt].device_path,cam_path);
+            memset(camInfoTmp[cam_cnt].fival_list,0x00, sizeof(camInfoTmp[cam_cnt].fival_list));
+            memcpy(camInfoTmp[cam_cnt].driver,capability.driver, sizeof(camInfoTmp[cam_cnt].driver));
+            camInfoTmp[cam_cnt].version = capability.version;
             if (strstr((char*)&capability.card[0], "front") != NULL) {
-                camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_FRONT;
+                camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_FRONT;
             } else {
-                camInfoTmp[cam_cnt&0x01].facing_info.facing = CAMERA_FACING_BACK;
+                camInfoTmp[cam_cnt].facing_info.facing = CAMERA_FACING_BACK;
             }  
             ptr = strstr((char*)&capability.card[0],"-");
             if (ptr != NULL) {
                 ptr++;
-                camInfoTmp[cam_cnt&0x01].facing_info.orientation = atoi(ptr);
+                camInfoTmp[cam_cnt].facing_info.orientation = atoi(ptr);
             } else {
-                camInfoTmp[cam_cnt&0x01].facing_info.orientation = 0;
+                camInfoTmp[cam_cnt].facing_info.orientation = 0;
             }
             cam_cnt++;
 
diff --git a/hardware/rockchip/camera/CameraHal/CameraHal_Module.h b/hardware/rockchip/camera/CameraHal/CameraHal_Module.h
index dc619eb..98f5d8e 100755
--- a/hardware/rockchip/camera/CameraHal/CameraHal_Module.h
+++ b/hardware/rockchip/camera/CameraHal/CameraHal_Module.h
@@ -11,12 +11,8 @@ using namespace android;
 #define CAMERA_DEFAULT_PREVIEW_FPS_MIN    8000        //8 fps
 #define CAMERA_DEFAULT_PREVIEW_FPS_MAX    15000
 #endif
-#define CAMERAS_SUPPORT_MAX             2
-#if 1//defined(TARGET_RK3399)
-    #define CAMERAS_SUPPORTED_SIMUL_MAX     2
-#else
-    #define CAMERAS_SUPPORTED_SIMUL_MAX     1
-#endif
+#define CAMERAS_SUPPORT_MAX             10
+#define CAMERAS_SUPPORTED_SIMUL_MAX     10
 #define CAMERA_DEVICE_NAME              "/dev/video"
 #define CAMERA_MODULE_NAME              "RK29_ICS_CameraHal_Module"
 

三、Android替换默认签名

生成自定义签名
创建签名生成脚本
创建 build/make/target/product/security/mkkey.sh 文件,内容如下:

#/bin/sh!
if [ $# -ne 1 ] ; then
	echo "Create a test certificate key."
	echo "Usage: $0 NAME"
	echo "Will generate NAME.pk8 and NAME.x509.pem"
	echo "/C=CN/ST=Guangdong/L=ShenZhen/O=Company/OU=Team/CN=Company/emailAddress=xxx@gmail.com"
	exit 1
fi

openssl genrsa -3 -out $1.pem 2048

openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 10000 \
    -subj '/C=CN/ST=Guangdong/L=ShenZhen/O=Company/OU=Team/CN=Company/emailAddress=xxx@gmail.com' 

openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -nocrypt

其中 『-subj』参数请替换为自定义值。

生成签名
通过 mkkey.sh,分别生成 media、platform、shared、testkey、verity 相关 key。

./mkkey.sh media
./mkkey.sh platform
./mkkey.sh shared
./mkkey.sh testkey
./mkkey.sh verity

生成文件如下:

.
├── Android.mk
├── media.pem
├── media.pk8
├── media.x509.pem
├── mkkey.sh
├── platform.pem
├── platform.pk8
├── platform.x509.pem
├── README
├── shared.pem
├── shared.pk8
├── shared.x509.pem
├── testkey.pem
├── testkey.pk8
├── testkey.x509.pem
├── verity_key
├── verity.pk8
└── verity.x509.pem

对全部内置应用重新签名
现在已经生成了自定义签名,但原内置的很多预编译应用还是使用的原 Android 默认签名,如果不对这些应用进行重新签名,将无法使用。所以,这里需要对全部预编译应用使用新的签名 key 进行重新签名。
创建批量签名脚本
创建批量签名脚本:vendor/rockchip/common/apps/ApkBatchSign/apksign.sh,内容如下:

#!/bin/bash

usage()
{
    echo "USAGE: [r] [-s source directory] [-k key directory]"
    echo "No ARGS means use default build option"
    echo "WHERE: -s = set source directory"
    echo "       -k = key directory"
    echo "       -r = replace source file"
    echo "       -h = help"
    exit 1
}

CUR_DIR=$PWD
SOURCE=$CUR_DIR
SIGNAPK_JAR=signapk.jar
KEY=$CUR_DIR
REPLACE=false

while getopts "s:k:r" opt
do
    case $opt in
        s)
		SOURCE=$OPTARG
        ;;
		k)
        KEY=$OPTARG
        ;;
		r)
        REPLACE=true
        ;;
        h)
        usage ;;
        ?)
        usage ;;
    esac
done


function sign(){
    for filename in $1/*
    do  
        if [ -d $filename ]
        then 
            sign $filename
        elif [ "${filename##*.}" = "apk" ]; then
            echo "签名: "$filename
		
			tempname=$(dirname $filename)"/"$(basename $filename .apk)"_signed.apk"
			java -jar $KEY/signapk.jar $KEY/platform.x509.pem $KEY/platform.pk8 $filename $tempname
			
			if [ $REPLACE = true ]; then
				rm -rf $filename
				mv -vf $tempname $filename
			fi
        fi  
    done
}

sign $SOURCE

使用批量签名脚本对全部应用签名
参数解释:
● -s 指定 APK 路径,默认会递归子目录查找。
● -k 指定签名 key 路径。需要包含下面三个文件:

.
├── platform.pk8
├── platform.x509.pem
└── signapk.jar

例如:

ApkBatchSign$ ./apksign.sh -s . -k topband_sign -r
签名: ./dir/BooksProvider.apk
‘./dir/BooksProvider_signed.apk’ ->./dir/BooksProvider.apk’
签名: ./RkEbookReader.apk
‘./RkEbookReader_signed.apk’ ->./RkEbookReader.apk’

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/661113.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【第六次】21级计科计算机组成原理课外练习

【第六次】21级计科计算机组成原理课外练习 一、单选题二、多选题三、填空题 一、单选题 2-1 假定某计算机按字节编址&#xff0c;采用小端方式&#xff0c;有一个float型变量x的地址为0xffffc000&#xff0c;x12345678H&#xff0c;则在内存单元0xffffc001中存放的内容是 A.…

计算机网络和Linux网络

计算机网络和Linux网络 计算机网络概论 什么是计算机网络 计算机网络&#xff08;结构上&#xff09; 由节点&#xff08;主机、网络交换设备设备&#xff09;、边&#xff08;通信设备&#xff09;、协议构成协议&#xff1a;对等层的实体在通讯过程中应该遵守的规则的集合&…

软考A计划-网络工程师-易混淆知识汇总

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

chatgpt赋能python:Python编程:如何隐藏输入以保护信息安全?

Python编程&#xff1a;如何隐藏输入以保护信息安全&#xff1f; 随着数字化时代的到来&#xff0c;人们越来越多地依赖于互联网和技术设备进行通信和交易。然而&#xff0c;信息安全成为越来越大的问题&#xff1a;黑客和其他恶意分子通过各种手段获取和利用个人信息。为保障…

【瑞萨RA_FSP】GPT—— PWM功能详解

文章目录 一、GPT比较匹配功能详解1. 锯齿波PWM模式&#xff08;普通PWM模式&#xff09;2. 三角波PWM模式1&#xff08;波谷32位传输&#xff09;3. 三角波PWM模式2&#xff08;波峰和波谷32位传输&#xff09;4. 三角波PWM模式3&#xff08;波谷64位传输&#xff09;5. 设置死…

【随机种子初始化】一个神经网络模型初始化的大坑

1 问题起因和经过 半年前写了一个模型&#xff0c;取得了不错的效果&#xff08;简称项目文件1&#xff09;&#xff0c;于是整理了一番代码&#xff0c;保存为了一个新的项目&#xff08;简称项目文件2&#xff09;。半年后的今天&#xff0c;我重新训练这个整理过的模型&…

【C数据结构】带头双向循环链表_HDList

目录 带头双向循环链表_HDList 【1】链表概念 【2】链表分类 【3】带头双向循环链表 【3.1】带头双向循环链表数据结构与接口定义 【3.2】带头双向循环链表初始化 【3.3】带头双向循环链表开辟节点空间 【3.4】带头双向循环链表销毁 【3.5】带头双向循环链表头插 【3…

【C数据结构】带头单向非循环链表_HList

目录 带头单向非循环链表_HList 【1】链表概念 【2】链表分类 【3】有头单向非循环链表 【3.1】非循环链表数据结构与接口定义 【3.2】带头单向非循环链表初始化 【3.3】带头单向非循环链表释放空间 【3.4】带头单向非循环链表创建节点 【3.5】带头单向非循环链表头插…

HTML学习(二)

视频 <video width"320" height"240" controls> <source src"movie.mp4" type"video/mp4"> <source src"movie.ogg" type"video/ogg"> </video> 音频 <audio controls> <…

C++【AVL树】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 &#x1f307;前言&#x1f3d9;️正文1、认识AVL树1.1、AVL树的定义 2、AVL树的插入操作2.1、抽象图2.2、插入流程…

控制层调用接口的http请求封装

目录 0.碎碎念1.controller层2.util层3.测试3.1中间层调用GET请求3.2中间层调用POST请求 0.碎碎念 因为只是为了写这个帮助类&#xff0c;解耦&#xff0c;不敢拿已经写了一堆的代码改&#xff0c;就单独拆了个项目出来&#xff0c;持久层全是mybatisplus生成的。     所以…

Kafka源码解析之索引

Kafka源码解析之索引 索引结构 Kafka有两种类型的索引&#xff1a; TimeIndex: 根据时间戳索引&#xff0c;可以通过时间查找偏移量所在位置&#xff0c;目录下以.timeindex结尾Index: 根据偏移量索引&#xff0c;.index结尾 构建索引时机 由log.index.interval.bytes 参…

3. redis cluster集群运维与核心原理剖析

分布式缓存技术Redis 1. Redis集群方案比较2. Redis高可用集群搭建 本文是按照自己的理解进行笔记总结&#xff0c;如有不正确的地方&#xff0c;还望大佬多多指点纠正&#xff0c;勿喷。 课程内容&#xff1a; 1、哨兵集群与Redis Cluster架构异同 2、Redis高可用集群快速实…

2023/6/18总结

JS 在document.querySelectorAll(CSS选择器) 选到的集合并没有pop()和push()等数组的方法。是一个伪数组。 如果想要得到里面的每一个对象&#xff0c;需要用for遍历获得 document.getElementById(id名称) 根据id获取一个元素 document.getElementsByTagName(标签名字) 根…

Css面试题:css文字隐藏

文章目录 文字隐藏单行文字隐藏多行文字隐藏基于高度设置多行文字隐藏基于行数设置多行文字隐藏 文字隐藏 单行文字隐藏 主要是通过overflow&#xff0c;text-overflow&#xff0c;white-space三个属性实现。 overflow&#xff1a;visible|hidden|auto|scroll|inherit&#…

【c语言】-- 操作符汇总

&#x1f4d5;博主介绍&#xff1a;目前大一正在学习c语言&#xff0c;数据结构&#xff0c;计算机网络。 c语言学习&#xff0c;是为了更好的学习其他的编程语言&#xff0c;C语言是母体语言&#xff0c;是人机交互接近底层的桥梁。 本章来学习数组。 让我们开启c语言学习之旅…

简单认识web与http协议

文章目录 web基础域名概述DNS&#xff08;Domain Name System域名系统&#xff09; 域名空间结构 域名实际用法 2. 网页的概念2.1 网页&#xff08;HTTP/HTTPS&#xff09;HTML 概述HTML超文本标记语言 HTML文档的结构头标签中常用标签内容标签中常用标签Web概述具体组成web的主…

chatgpt赋能python:Python如何创建窗口——从入门到精通

Python如何创建窗口——从入门到精通 Python是一种高级编程语言&#xff0c;它的易读性和清晰简洁的语法使它成为许多人喜欢学习的编程语言之一。Python的一个主要特色是其丰富的库和模块。在本文中&#xff0c;我们将讨论如何使用Python创建一个窗口&#xff0c;并在其中添加…

【力扣刷题 | 第十一天】

前言&#xff1a; 我将会利用几天把树的经典例题都刷完&#xff0c;希望我可以坚持下去。 226. 翻转二叉树 - 力扣&#xff08;LeetCode&#xff09; 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 解题思路&#xff1a;我们交换每一…

C语言之运算符用法(补充前面运算符中的不足)

设定&#xff1a;int X20,Y10 1、算术运算符 注&#xff1a;自增和自减运算符只能用于变量&#xff0c;不可用于常量或表达式。另&#xff0c;X与X是不同的(–亦同)。以语句a[x]100;为例&#xff1a; a[X]100;执行之后得到&#xff1a;a[20] 100、X 21。//即&#xff0c;先执行…