定制framework 接口,并添加白名單

在framework中定制接口;
1.添加接口

└── xxx
  └── xxx
    └── xxx
        ├── xxx.java
        ├── xxx.java
        ├── xxx.java
        ├── xxx.java
        ├── xxx.java
        └── xxx.java

2.在package_allowed_list.txt中加入打包規(guī)則

build/soong/scripts/check_boot_jars/package_allowed_list.txt
+
+###################################################
+# framework.jar coustom java
+komect\.aisoho\.cloudcomputer
+komect\.aisoho\.cloudcomputer\..*
\ No newline at end of file

3.系統(tǒng)解決hidden api調(diào)用

Accessing hidden method Lxxx/xxx/xxx/xxx;->getBatteryStatus()I (blocked, linking, denied)

具體代碼可以看這里: base/core/java/android/content/pm/ApplicationInfo.java

    private boolean isAllowedToUseHiddenApis() {
        if (isSignedWithPlatformKey()) {
            return true;
        } else if (isSystemApp() || isUpdatedSystemApp()) {
            return usesNonSdkApi() || isPackageWhitelistedForHiddenApis();
        } else {
            return false;
        }
    }

這個系統(tǒng)應(yīng)用白名單所在位置frameworks/base/data/etc/hiddenapi-package-whitelist.xml

<?xml version="1.0" encoding="utf-8"?>
<config>
  <hidden-api-whitelisted-app package="android.ext.services" />
  <hidden-api-whitelisted-app package="com.android.apps.tag" />
  ..........

  <!-- TODO: Remove NetworkStack whitelisting -->
  <hidden-api-whitelisted-app package="com.android.networkstack" />
  <hidden-api-whitelisted-app package="cm.komect.aqb.android.ccsdk" />
  <hidden-api-whitelisted-app package="cm.komect.aqb.android.launcher" />
  <hidden-api-whitelisted-app package="cm.komect.aqb.android.hjqbind" />
  <hidden-api-whitelisted-app package="cm.komect.aqb.android.cloudcomputerpad" />
</config>

4.處理獲取mac地址的問題

Index: packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java
===================================================================
@@ -1168,8 +1168,11 @@
      */
     @Override
     public synchronized boolean setWifiEnabled(String packageName, boolean enable) {
-        if (enforceChangePermission(packageName) != MODE_ALLOWED) {
-            return false;
+        if (packageName !=null && packageName.contains("cm.komect.aqb")) {
+        }else{
+            if (enforceChangePermission(packageName) != MODE_ALLOWED) {
+                return false;
+            }
         }
         int callingUid = Binder.getCallingUid();
         int callingPid = Binder.getCallingPid();
@@ -5532,9 +5535,14 @@
     @Override
     public String[] getFactoryMacAddresses() {
         final int uid = Binder.getCallingUid();
-        if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
-            throw new SecurityException("App not allowed to get Wi-Fi factory MAC address "
-                    + "(uid = " + uid + ")");
+        String packageName = getPackageNameByUid(uid);
+        if (packageName !=null &&  packageName.contains("cm.komect.aqb")) {
+            //杭研的包不做權(quán)限判斷
+        }else{
+            if (!mWifiPermissionsUtil.checkNetworkSettingsPermission(uid)) {
+                throw new SecurityException("App not allowed to get Wi-Fi factory MAC address "
+                        + "(uid = " + uid + ")");
+            }
         }
         String result = mWifiThreadRunner.call(
                 () -> mActiveModeWarden.getPrimaryClientModeManager().getFactoryMacAddress(),
@@ -5548,6 +5556,14 @@
         return new String[]{result};
     }
 
+    private String getPackageNameByUid(int uid) {
+        String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+        if (packageNames != null && packageNames.length > 0) {
+            return packageNames[0]; // 返回找到的第一個包名
+        }
+        return null; // 如果沒有找到包名绞呈,則返回null
+    }
+
     /**
      * Sets the current device mobility state.
      * @param state the new device mobility state

CloudComputerAgent.java


Index: frameworks/base/core/java/komect/aisoho/cloudcomputer/CloudComputerAgent.java
===================================================================
@@ -0,0 +1,27 @@
+package komect.aisoho.cloudcomputer;
+
+import android.content.Context;
+
+public class CloudComputerAgent {
+    private Context mContext;
+
+    public CloudComputerAgent(Context context) {
+        this.mContext = context;
+    }
+
+    public PackageManager getPackageManager() {
+        return new PackageManager(this.mContext);
+    }
+
+    public PowerManager getPowerManager() {
+        return new PowerManager(this.mContext);
+    }
+
+    public InfoManager getInfoManager() {
+        return new InfoManager(this.mContext);
+    }
+
+    public SettingManager getSettingManager() {
+        return new SettingManager(this.mContext);
+    }
+}

InfoManager.java

Index: frameworks/base/core/java/komect/aisoho/cloudcomputer/InfoManager.java
===================================================================
@@ -0,0 +1,519 @@
+package komect.aisoho.cloudcomputer;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
+import android.os.BatteryManager;
+import android.provider.SettingsStringUtil;
+import android.telephony.CellSignalStrengthWcdma;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+import com.android.internal.accessibility.common.ShortcutConstants;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
+import org.json.JSONException;
+import org.json.JSONObject;
+import android.os.Build;
+import static android.content.Context.TELEPHONY_SERVICE;
+import static android.content.Context.STORAGE_STATS_SERVICE;
+import android.app.usage.StorageStatsManager;
+import android.os.storage.StorageManager;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Method;
+import android.app.ActivityManager;
+import android.provider.Settings;
+
+public class InfoManager {
+    private static final String TAG = "InfoManager";
+    private Context mContext;
+    private int mBatteryStatus = 3;
+    private WifiManager mWifiManager;
+    private static final boolean DEBUG = false;
+    private BroadcastReceiver receiver = new BroadcastReceiver() { 
+        @Override 
+        public void onReceive(Context context, Intent intent) {
+            if(DEBUG) Log.e(InfoManager.TAG, "BroadcastReceiver   mBatteryStatus=" + InfoManager.this.mBatteryStatus);
+            if (intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)) {
+                intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
+                int status = intent.getIntExtra("status", 1);
+                if (status == 1) {
+                    InfoManager.this.mBatteryStatus = 0;
+                } else if (status != 2) {
+                    if (status == 3) {
+                        InfoManager.this.mBatteryStatus = 3;
+                    } else if (status == 4) {
+                        InfoManager.this.mBatteryStatus = 4;
+                    } else if (status == 5) {
+                        InfoManager.this.mBatteryStatus = 5;
+                    }
+                }
+                InfoManager.this.mBatteryStatus = 2;
+            }
+            if(DEBUG) Log.e(InfoManager.TAG, "BroadcastReceiver 97  mBatteryStatus=" + InfoManager.this.mBatteryStatus);
+        }
+    };
+
+    public InfoManager(Context context) {
+        this.mContext = context;
+        IntentFilter localIntentFilter = new IntentFilter();
+        localIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
+        context.registerReceiver(this.receiver, localIntentFilter);
+        mWifiManager = (WifiManager) this.mContext.getSystemService(WifiManager.class);
+        mWifiManager.setWifiEnabled(true);
+    }
+
+    public int getBatteryScale() {
+        return 100;
+    }
+
+    public int getBatteryLevel() {
+        BatteryManager bm = (BatteryManager) this.mContext.getSystemService(Context.BATTERY_SERVICE);
+        int batLevel = bm.getIntProperty(4);
+        if(DEBUG) Log.e(TAG, "getBatteryLevel batLevel=" + batLevel);
+        return batLevel;
+    }
+
+    public int getBatteryStatus() {
+        return this.mBatteryStatus;
+    }
+
+    public String getMemorySize() {
+        if(DEBUG) Log.e(TAG, "InfoManager  90");
+        return totalStorage();
+    }
+
+    public String getDiskSize() {
+        if(DEBUG) Log.e(TAG, "InfoManager  95");
+        return totalMemory();
+    }
+
+    public String getProtocolVersion() {
+        return getSystemProperty("ro.sys.protocol.version");
+        //return "V1.0-SE";
+    }
+
+    public String getSoftwareVersion() {
+        try {
+            android.content.pm.PackageManager packageManager = this.mContext.getPackageManager();
+            PackageInfo packInfo = packageManager.getPackageInfo("cm.komect.aqb.android.launcher", 0);
+            if (packInfo != null) {
+                return packInfo.versionName;
+            }
+            return "";
+        } catch (PackageManager.NameNotFoundException e) {
+            if(DEBUG) Log.e(TAG, " getSoftwareVersion error e=" + e);
+            return getOSVersion();
+        }
+    }
+
+    public String getFirmwareVersion() {
+        //return getSystemProperty("ro.kte.display.fireware.id");
+        return  Build.DISPLAY;
+    }
+
+    public String getSn() {
+        String sn = getSystemProperty("ro.serialno");
+        if (!TextUtils.isEmpty(sn)) {
+            int index = sn.indexOf(" ");
+            if (index > 0 && sn.length() >= 10) {
+                sn = sn.substring(0, index);
+            }
+            Log.d(TAG, "getSn() SN :" + sn + "index=" + index);
+        }
+        return sn;
+    }
+
+    public static String getSystemProperty(String key) {
+        try {
+            String value = (String) Class.forName("android.os.SystemProperties").getMethod("get", String.class).invoke(null, key);
+            return value;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    public String getVersionName(String packageName) {
+        String versionName = "0.0";
+        try {
+            versionName = this.mContext.getPackageManager().getPackageInfo(packageName, 0).versionName;
+        } catch (Exception var4) {
+            Log.e(TAG, "獲取 " + packageName + " 的版本號失斏枇!");
+            var4.printStackTrace();
+        }
+        return "V" + versionName;
+    }
+
+    public String getVersionName(Context context, String packageName) throws Exception {
+        android.content.pm.PackageManager packageManager = context.getPackageManager();
+        PackageInfo packInfo = packageManager.getPackageInfo(packageName, 0);
+        String version = packInfo.versionName;
+        return version;
+    }
+
+    public void apkInfo(String absPath, Context context) {
+        android.content.pm.PackageManager pm = context.getPackageManager();
+        PackageInfo pkgInfo = pm.getPackageArchiveInfo(absPath, 1);
+        if (pkgInfo != null) {
+            ApplicationInfo appInfo = pkgInfo.applicationInfo;
+            appInfo.sourceDir = absPath;
+            appInfo.publicSourceDir = absPath;
+            String appName = pm.getApplicationLabel(appInfo).toString();
+            String packageName = appInfo.packageName;
+            String version = pkgInfo.versionName;
+            pm.getApplicationIcon(appInfo);
+            appInfo.loadIcon(pm);
+            String pkgInfoStr = String.format("PackageName:%s, Vesion: %s, AppName: %s", packageName, version, appName);
+            if(DEBUG) Log.i(TAG, String.format("PkgInfo: %s", pkgInfoStr));
+        }
+    }
+
+    public String getCmei() {
+        String cmei = "";
+        try {
+            TelephonyManager tm = (TelephonyManager) mContext.getSystemService(TELEPHONY_SERVICE);
+            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+                cmei = tm.getDeviceId();
+            } else {
+                Method method = tm.getClass().getMethod("getImei");
+                cmei = (String) method.invoke(tm);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        if(DEBUG) Log.e(TAG, "getCmei deviceId=" + cmei);
+        return cmei;
+    }
+
+
+    public String getString(String key) {
+        String value=Settings.System.getString(mContext.getContentResolver(), key);
+        return value+"";
+    }
+
+    public String getMac() {
+        WifiManager mWifiManager = (WifiManager) this.mContext.getSystemService(WifiManager.class);
+        mWifiManager.setWifiEnabled(true);
+        String[] macAddresses = mWifiManager.getFactoryMacAddresses();
+        if (macAddresses == null || macAddresses.length <= 0) {
+            return null;
+        }
+        String macAddress = macAddresses[0];
+        if(DEBUG) Log.e(TAG, "242  getMac macAddress=" + ((String) macAddress));
+        /*String macAddress = getString("ro_wifimac");
+        Log.e(TAG, "242  getMac macAddress=" + ((String) macAddress));*/
+        return macAddress;
+    }
+
+    public String getFormatMacFromHardware() {
+        String strMacAddr = null;
+        try {
+            InetAddress ip = getLocalInetAddress();
+            byte[] b = NetworkInterface.getByInetAddress(ip).getHardwareAddress();
+            StringBuffer buffer = new StringBuffer();
+            for (int i = 0; i < b.length; i++) {
+                if (i != 0) {
+                    buffer.append(ShortcutConstants.SERVICES_SEPARATOR);
+                }
+                String str = Integer.toHexString(b[i] & 255);
+                buffer.append(str.length() == 1 ? 0 + str : str);
+            }
+            strMacAddr = buffer.toString().toUpperCase();
+        } catch (Exception e) {
+        }
+        if(DEBUG) Log.e(TAG, "getMac strMacAddr=" + strMacAddr);
+        if (strMacAddr != null && strMacAddr.length() > 1) {
+            return strMacAddr.replace(SettingsStringUtil.DELIMITER, "").toUpperCase();
+        }
+        return strMacAddr;
+        /*String macAddress = getString("ro_wifimac");
+        Log.e(TAG, "242  getMac macAddress=" + ((String) macAddress));
+        return macAddress;*/
+    }
+
+    private InetAddress getLocalInetAddress() {
+        InetAddress ip = null;
+        try {
+            Enumeration<NetworkInterface> en_netInterface = NetworkInterface.getNetworkInterfaces();
+            while (en_netInterface.hasMoreElements()) {
+                NetworkInterface ni = en_netInterface.nextElement();
+                Enumeration<InetAddress> en_ip = ni.getInetAddresses();
+                while (en_ip.hasMoreElements()) {
+                    ip = en_ip.nextElement();
+                    if (ip.isLoopbackAddress() || ip.getHostAddress().indexOf(SettingsStringUtil.DELIMITER) != -1) {
+                        ip = null;
+                    }
+                }
+                if (ip != null) {
+                    break;
+                }
+            }
+        } catch (SocketException e) {
+            e.printStackTrace();
+        }
+        if(DEBUG) Log.e(TAG, "getLocalInetAddress ip=" + ip);
+        return ip;
+    }
+
+    public String getIpFromHardware() {
+        WifiManager mWifiManager = (WifiManager) this.mContext.getSystemService(WifiManager.class);
+        mWifiManager.setWifiEnabled(true);
+        String theIP = "0.0.0.0";
+        InetAddress ipAddress = getLocalInetAddress();
+        if (ipAddress != null && (theIP = ipAddress.toString()) != null && theIP.length() > 1) {
+            theIP = theIP.replace("/", "");
+        }
+        if(DEBUG) Log.e(TAG, "getIpFromHardware theIP=" + theIP);
+        return theIP;
+    }
+
+    public String getDeviceType() {
+        return getSystemProperty("ro.sys.dj.device_type");
+        // return "590698";
+    }
+
+    public String getDeviceFactory() {
+        return Build.BRAND;
+    }
+
+    public String getConnectedType() {
+        ConnectivityManager mConnectivityManager = (ConnectivityManager) this.mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
+        if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
+            int networkType = mNetworkInfo.getType();
+            if(DEBUG) Log.e(TAG, "345 getConnectedType networkType=" + networkType);
+            if (networkType != 1 && networkType == 0) {
+                TelephonyManager telephonyManager = (TelephonyManager) this.mContext.getSystemService(TELEPHONY_SERVICE);
+                int type = telephonyManager.getNetworkType();
+                if(DEBUG) Log.e(TAG, "375 getConnectedType  type=" + type);
+                if (type == 20) {
+                    return "5G";
+                }
+                int subNetworkType = mNetworkInfo.getSubtype();
+                switch (subNetworkType) {
+                    case 3:
+                    case 5:
+                    case 6:
+                    case 8:
+                    case 9:
+                    case 10:
+                    case 12:
+                    case 14:
+                    case 15:
+                        if(DEBUG) Log.e(TAG, "399 getConnectedType subNetworkType=3G");
+                        return "3G";
+                    case 4:
+                    case 7:
+                    case 11:
+                    default:
+                        if(DEBUG) Log.e(TAG, "408 getConnectedType subNetworkType=5G");
+                        return "5G";
+                    case 13:
+                        if(DEBUG) Log.e(TAG, "402 getConnectedType subNetworkType=4G");
+                        return "4G";
+                }
+            }
+        }
+        return "Wi-Fi";
+    }
+
+
+    public String getOSVersion() {
+        return "android " + Build.VERSION.RELEASE;
+    }
+
+    public String totalStorage() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            StorageStatsManager storageStatsManager = (StorageStatsManager) mContext.getSystemService(STORAGE_STATS_SERVICE);
+            try {
+                long totalBytes = storageStatsManager.getTotalBytes(StorageManager.UUID_DEFAULT); //總空間大小
+                return String.valueOf(totalBytes / 1000 / 1000 / 1000);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return "64";
+    }
+
+    /**
+     * 總內(nèi)存
+     *
+     * @return {@link String}
+     */
+    public String totalMemory() {
+        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
+        am.getMemoryInfo(mi);
+        return String.valueOf((int) Math.ceil((double) mi.totalMem / 1000 / 1000 / 1000))+"";
+    }
+
+    /*
+     * 獲取wifi信號強度
+     * @return int
+     */
+    public int getConnectedWifiRssi() {
+        WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        if (wifiInfo != null) {
+            String ssid = wifiInfo.getSSID();
+            int rssi = wifiInfo.getRssi();
+
+            if (ssid.startsWith("\"") && ssid.endsWith("\"")) {
+                ssid = ssid.substring(1, ssid.length() - 1);
+            }
+            return wifiInfo.getRssi();
+
+        }
+        return -1;
+    }
+
+    public String getCPUModel() {
+        return getSystemProperty("ro.sys.cputype");
+        //return SystemProperties.get("ro.sys.cputype", "unKnown");
+    }
+
+    public String getDmInfo() {
+        JSONObject dmInfoObj = new JSONObject();
+        try {
+            // dmInfoObj.put(ConnectivityManager.EXTRA_DEVICE_TYPE, getDeviceType());
+            dmInfoObj.put("deviceType", getDeviceType());
+            dmInfoObj.put("firmwareVersion", getFirmwareVersion());
+            dmInfoObj.put("softwareVersion", getSoftwareVersion());
+            dmInfoObj.put("cmei", getCmei());
+            dmInfoObj.put("mac", getMac());
+            dmInfoObj.put("sn", getSn());
+            dmInfoObj.put("OS", getOSVersion());
+            dmInfoObj.put("cpuModel", getCPUModel());
+            dmInfoObj.put("romStorageSize", totalStorage());
+            dmInfoObj.put("ramStorageSize", totalMemory());
+            dmInfoObj.put("networkType", "wifi");
+            dmInfoObj.put("deviceVendor", Build.MANUFACTURER);
+            dmInfoObj.put("deviceBrand", Build.BRAND);
+            dmInfoObj.put("deviceModel", Build.MODEL);
+            dmInfoObj.put("wlanMac", getMac());
+            dmInfoObj.put("powerSupplyMode", android.os.PowerManager.SHUTDOWN_LOW_BATTERY);
+            dmInfoObj.put("wifiRssi", getConnectedWifiRssi());
+            dmInfoObj.put("deviceIP", getIpFromHardware());
+            dmInfoObj.put("deviceManageExtInfo", new JSONObject());
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        String dmInfo = dmInfoObj.toString();
+        if(DEBUG) Log.e(TAG, "getDmInfo dmInfo=" + dmInfo);
+        return dmInfo;
+    }
+
+    public String getSelfDetect() {
+        JSONObject curObj = new JSONObject();
+        try {
+            curObj.put("cpuRate", getProcessCpuRate());
+            curObj.put("ramRate", getUsedPercentValue());
+            curObj.put("upLinkType", getConnectedType());
+            curObj.put(CellSignalStrengthWcdma.LEVEL_CALCULATION_METHOD_RSSI, getConnectedWifiRssi());
+        } catch (JSONException e) {
+            if(DEBUG) Log.d(TAG, "doSelfDetect e:" + e.getMessage());
+        }
+        String msg = curObj.toString();
+        if(DEBUG) Log.d(TAG, "doSelfDetect success: " + msg);
+        return msg;
+    }
+
+    public long getAvailableMemory() {
+        ActivityManager mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
+        mActivityManager.getMemoryInfo(mi);
+        return mi.availMem;
+    }
+
+    public int getUsedPercentValue() {
+        String dir = "/proc/meminfo";
+        try {
+            FileReader fr = new FileReader(dir);
+            BufferedReader br = new BufferedReader(fr, 2048);
+            String memoryLine = br.readLine();
+            String subMemoryLine = memoryLine.substring(memoryLine.indexOf("MemTotal:"));
+            br.close();
+            long totalMemorySize = Integer.parseInt(subMemoryLine.replaceAll("\\D+", ""));
+            long availableSize = getAvailableMemory() / 1024;
+            return (int) ((totalMemorySize - availableSize) / (float) totalMemorySize * 100);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return 0;
+
+    }
+
+    public static float getProcessCpuRate() {
+        float totalCpuTime1 = getTotalCpuTime();
+        float processCpuTime1 = getAppCpuTime();
+        try {
+            Thread.sleep(360);  //sleep一段時間
+        } catch (Exception e) {
+        }
+        float totalCpuTime2 = getTotalCpuTime();
+        float processCpuTime2 = getAppCpuTime();
+        float cpuRate = 100 * (processCpuTime2 - processCpuTime1) / (totalCpuTime2 - totalCpuTime1);//百分比
+        return cpuRate;
+    }
+
+    // 獲取系統(tǒng)總CPU使用時間
+    public static long getTotalCpuTime() {
+        String[] cpuInfos = null;
+        try {
+            BufferedReader reader = new BufferedReader(new InputStreamReader(
+                    new FileInputStream("/proc/stat")), 1000);
+            String load = reader.readLine();
+            reader.close();
+            cpuInfos = load.split(" ");
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+        if (cpuInfos != null) {
+            long totalCpu = Long.parseLong(cpuInfos[2])
+                    + Long.parseLong(cpuInfos[3]) + Long.parseLong(cpuInfos[4])
+                    + Long.parseLong(cpuInfos[6]) + Long.parseLong(cpuInfos[5])
+                    + Long.parseLong(cpuInfos[7]) + Long.parseLong(cpuInfos[8]);
+            return totalCpu;
+        } else {
+            return 0;
+        }
+    }
+
+    // 獲取應(yīng)用占用的CPU時間
+    public static long getAppCpuTime() {
+        String[] cpuInfos = null;
+        try {
+            int pid = android.os.Process.myPid();
+            if(DEBUG) Log.d(TAG, "getAppCpuTime pid: " + pid);
+            BufferedReader reader = new BufferedReader(new InputStreamReader(
+                    new FileInputStream("/proc/" + pid + "/stat")), 1000);
+            String load = reader.readLine();
+            reader.close();
+            cpuInfos = load.split(" ");
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+        long appCpuTime = Long.parseLong(cpuInfos[13])
+                + Long.parseLong(cpuInfos[14]) + Long.parseLong(cpuInfos[15])
+                + Long.parseLong(cpuInfos[16]);
+        return appCpuTime;
+    }
+
+}

Index: frameworks/base/core/java/komect/aisoho/cloudcomputer/Installer.java
===================================================================
@@ -0,0 +1,337 @@
+package komect.aisoho.cloudcomputer;
+
+import android.app.ActivityThread;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageInstallerCallback;
+import android.content.pm.IPackageInstallObserver2;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageParser;
+import android.media.AudioSystem;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import android.content.BroadcastReceiver;
+import android.provider.Settings;
+import android.media.MediaScannerConnection;
+import android.os.Build;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+
+public class Installer {
+    private static final boolean DEBUG = false;
+    private static final String BROADCAST_ACTION = "com.android.packageinstaller.ACTION_INSTALL_COMMIT";
+    private static final String BROADCAST_SETTING_ACTION = "com.android.settings.ACTION_INSTALL_COMMIT";
+    private static final String BROADCAST_ACTION_PACKAGE_ADDED = "com.android.packageinstaller.package_add";
+    private static final String EXTRA_ID = "EventResultPersister.EXTRA_ID";
+    private static final int GENERATE_NEW_ID = Integer.MIN_VALUE;
+    private static Uri mPackageURI;
+    public ApplicationInfo mAppInfo;
+    private Context mContext;
+    private int mCounter;
+    private boolean mOpenWhenInstalled;
+    private static Installer mInstaller = null;
+    private static String TAG = "Installer";
+    private int mSessionId = -1;
+    private int mInstallId = Integer.MIN_VALUE;
+    private final Object mLock = new Object();
+    private IntentFilter localIntentFilter;
+
+    private Installer() {
+    }
+
+    public static Installer getInstance() {
+        if (mInstaller == null) {
+            mInstaller = new Installer();
+        }
+        return mInstaller;
+    }
+
+    private boolean createSeesionId() {
+        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+        params.originatingUid = Process.myUid();
+        params.installFlags = 66;
+        File file = new File(mPackageURI.getPath());
+        if(DEBUG) Log.e(TAG, "createSeesionId file.length()=" + file.length());
+        try {
+            PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0);
+            params.setAppPackageName(pkg.packageName);
+            params.setInstallLocation(pkg.installLocation);
+            params.setSize(file.length());
+        } catch (PackageParser.PackageParserException e) {
+            if(DEBUG) Log.e(TAG, "Cannot parse package " + file + ". Assuming defaults.");
+            if(DEBUG) Log.e(TAG, "Cannot calculate installed size " + file + ". Try only apk size.");
+            params.setSize(file.length());
+        }
+        synchronized (this.mLock) {
+            this.mCounter = AudioSystem.DEVICE_IN_COMMUNICATION;
+            int i = this.mCounter + 1;
+            this.mCounter = i;
+            this.mInstallId = i - 1;
+        }
+        try {
+            this.mSessionId = this.mContext.getPackageManager().getPackageInstaller().createSession(params);
+            if(DEBUG) Log.e(TAG, "createSeesionId mSessionId=" + mSessionId);
+            return true;
+        } catch (IOException e3) {
+            return false;
+        }
+    }
+
+    public class InstallingAsyncTask extends AsyncTask<Void, Void, PackageInstaller.Session> {
+        volatile boolean isDone;
+
+        InstallingAsyncTask() {
+        }
+
+        @Override 
+        public PackageInstaller.Session doInBackground(Void... params) {
+            if(DEBUG) Log.e(Installer.TAG, "doInBackground params=" + params);
+            try {
+                PackageInstaller.Session session = Installer.this.mContext.getPackageManager().getPackageInstaller().openSession(Installer.this.mSessionId);
+                session.setStagingProgress(0.0f);
+                try {
+                    File file = new File(Installer.mPackageURI.getPath());
+                    InputStream in = new FileInputStream(file);
+                    long sizeBytes = file.length();
+                    try {
+                        OutputStream out = session.openWrite("base.apk", 0, sizeBytes);
+                        byte[] buffer = new byte[1024 * 1024];
+                        while (true) {
+                            int numRead = in.read(buffer);
+                            //if(DEBUG) Log.e(Installer.TAG, "doInBackground numRead=" + numRead);
+                            if (numRead == -1) {
+                                break;
+                            }
+                            out.write(buffer, 0, numRead);
+                            if (sizeBytes > 0) {
+                                float fraction = numRead / ((float) sizeBytes);
+                                session.addProgress(fraction);
+                                //Log.e(Installer.TAG, "doInBackground fraction=" + fraction);
+                            }
+                        }
+                        session.fsync(out);
+                        //if(DEBUG) Log.e(Installer.TAG, "doInBackground fsync");
+                        if (out != null) {
+                            out.close();
+                        }
+                        in.close();
+                        return session;
+                    } catch (Throwable th) {
+                        try {
+                            in.close();
+                        } catch (Throwable th2) {
+                            th.addSuppressed(th2);
+                        }
+                        throw th;
+                    } finally {
+                        synchronized (this) {
+                            if(DEBUG) Log.e(Installer.TAG, "notifyAll");
+                            notifyAll();
+                        }
+                    }
+                } catch (IOException | SecurityException e) {
+                    if(DEBUG) Log.e(Installer.TAG, "doInBackground 1", e);
+                    session.close();
+                    return null;
+                }
+            } catch (IOException e2) {
+                if(DEBUG) Log.e(Installer.TAG, "doInBackground 2", e2);
+                return null;
+            }
+        }
+
+        @Override 
+        public void onPostExecute(PackageInstaller.Session session) {
+            if (session != null) {//非系統(tǒng)應(yīng)用報錯BroadcastQueue: Permission Denial: broadcasting Intent xxx  is not exported from uid xxx
+                Intent broadcastIntent = new Intent(Installer.BROADCAST_ACTION);
+                String pkgName="com.android.packageinstaller";//Installer.this.mContext.getPackageName();
+                // broadcastIntent.setPackage(Installer.this.mContext.getPackageManager().getPermissionControllerPackageName());
+                broadcastIntent.setPackage(pkgName);
+                if(DEBUG) Log.e(Installer.TAG, "onPostExecute BROADCAST_ACTION=" + pkgName +" mInstallId=" + Installer.this.mInstallId);
+                broadcastIntent.putExtra(Installer.EXTRA_ID, Installer.this.mInstallId);
+                PendingIntent pendingIntent;
+                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
+                    broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+                    pendingIntent = PendingIntent.getBroadcast(Installer.this.mContext, Installer.this.mInstallId, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
+                } else {
+                    broadcastIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    pendingIntent = PendingIntent.getBroadcast(Installer.this.mContext, Installer.this.mInstallId, broadcastIntent, PendingIntent.FLAG_ONE_SHOT);
+                }
+                //PendingIntent pendingIntent = PendingIntent.getBroadcast(Installer.this.mContext, Installer.this.mInstallId, broadcastIntent, Intent.FLAG_RECEIVER_NO_ABORT);
+                session.commit(pendingIntent.getIntentSender());
+                if(DEBUG) Log.e(Installer.TAG, "onPostExecute session commit");
+            }
+        }
+    }
+
+
+    private BroadcastReceiver receiver = new BroadcastReceiver() { 
+        @Override 
+        public void onReceive(Context context, Intent intent) {
+            if(DEBUG) Log.e(Installer.TAG, "BroadcastReceiver   BROADCAST_ACTION_PACKAGE_ADDED" );
+            if (BROADCAST_ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
+                boolean success=intent.getBooleanExtra("success",false);
+                String pkgName=intent.getStringExtra("packageName");
+                if(DEBUG) Log.e(TAG, " onPackageInstalled success=" + success+",pkgName="+pkgName+",mObserver="+mObserver);
+                try {
+                    if (mObserver != null) {
+                        mObserver.onPackageInstalled(pkgName, success?1:0,null,null);
+                    }
+                } catch (RemoteException e) {
+                    e.printStackTrace();
+                    if(DEBUG) Log.e(TAG, " onPackageInstalled e=" + e);
+                }
+                if(DEBUG) Log.e(Installer.TAG, "BroadcastReceiver 97  BROADCAST_ACTION_PACKAGE_ADDED=" +success);
+            }
+        }
+    };
+
+    private IPackageInstallObserver2 mObserver;
+
+    public void silentInstall(Context context, String fileName, boolean openWhenInstalled,IPackageInstallObserver2 observer) {
+        this.mContext = context;
+        this.mOpenWhenInstalled = openWhenInstalled;
+        File file = new File(fileName);
+        if (!file.exists()) {
+            return;
+        }
+        mPackageURI = Uri.fromFile(file);
+        if(true){//非系統(tǒng)應(yīng)用會阻塞在安裝進度80%后不動沒有報錯超時,所以跳轉(zhuǎn)系統(tǒng)應(yīng)用或服務(wù)安裝
+            mObserver=observer;
+            if (localIntentFilter==null) {
+                localIntentFilter = new IntentFilter();
+                localIntentFilter.addAction(BROADCAST_ACTION_PACKAGE_ADDED);
+                mContext.registerReceiver(this.receiver, localIntentFilter);
+            }
+            //COPY文件
+            new Thread(new CopyFileThread()).start();
+        }else{
+            IPackageInstallerCallback sessionCallbackDelegate = new IPackageInstallerCallback.Stub() { 
+                String pkgName = null;
+                @Override 
+                public void onSessionCreated(int sessionId) {
+                    if(DEBUG) Log.e(Installer.TAG, "onSessionCreated sessionId=" + sessionId);
+                    PackageInstaller.SessionInfo ss = null;
+                    try {
+                        ss = ActivityThread.getPackageManager().getPackageInstaller().getSessionInfo(sessionId);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    if (ss != null) {
+                        this.pkgName = ss.appPackageName;
+                    }
+                }
+                @Override 
+                public void onSessionBadgingChanged(int sessionId) {
+                }
+                @Override 
+                public void onSessionActiveChanged(int sessionId, boolean active) {
+                }
+                @Override 
+                public void onSessionProgressChanged(int sessionId, float progress) {
+                }
+                @Override 
+                public void onSessionFinished(int sessionId, boolean success) {
+                    if(DEBUG) Log.e(Installer.TAG, "onSessionFinished=" + success + ",pkgName=" + this.pkgName);
+                    if (success) {
+                        if(DEBUG) Log.e(Installer.TAG, "mOpenWhenInstalled=" + Installer.this.mOpenWhenInstalled);
+                        if (Installer.this.mOpenWhenInstalled) {
+                            Intent intent = Installer.this.mContext.getPackageManager().getLaunchIntentForPackage(this.pkgName);
+                            Installer.this.mContext.startActivity(intent);
+                        }
+                    }
+                    try {
+                        IPackageInstallObserver2 installObserver = observer;
+                        if (installObserver != null) {
+                            installObserver.onPackageInstalled(this.pkgName, success?1:0,null,null);
+                        }
+                    } catch (RemoteException e) {
+                        e.printStackTrace();
+                        if(DEBUG) Log.e(TAG, " onPackageInstalled e=" + e);
+                    }
+                    try {
+                        ActivityThread.getPackageManager().getPackageInstaller().unregisterCallback(this);
+                    } catch (RemoteException e) {
+                        if(DEBUG) Log.e(Installer.TAG, "unregisterCallback filed");
+                    }
+                }
+            };
+            try {
+                if(DEBUG) Log.e(Installer.TAG, "registerCallback getIdentifier ="+Process.myUserHandle().getIdentifier());
+                ActivityThread.getPackageManager().getPackageInstaller().registerCallback(sessionCallbackDelegate, Process.myUserHandle().getIdentifier());
+            } catch (RemoteException e) {
+                if(DEBUG) Log.e(TAG, "registerCallback filed");
+            }
+            if (!createSeesionId()) {
+                return;
+            }
+            new InstallingAsyncTask().execute(new Void[0]);
+
+        }
+        if(DEBUG) Log.e(TAG, "silentInstall start");
+    }
+
+    public class CopyFileThread implements Runnable {
+        @Override
+        public void run() {
+            try {
+                copy();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public void copy() {
+        final String FROMPATH = mPackageURI.getPath();
+        final String TOPATH = "/sdcard/base.apk";
+        InputStream fosfrom = null;
+        OutputStream fosto = null;
+        try {
+            fosfrom = new FileInputStream(FROMPATH);
+            fosto = new FileOutputStream(TOPATH);
+            byte[] bt = new byte[1024];
+            int c;
+            while ((c = fosfrom.read(bt)) > 0) {
+                fosto.write(bt, 0, c);
+            }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            fosfrom.close();
+            fosto.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        updateMedia(mContext,TOPATH);
+        if(DEBUG) Log.d(TAG, "Copy file success");
+        Intent broadcastIntent = new Intent(BROADCAST_SETTING_ACTION);
+        broadcastIntent.putExtra("path",TOPATH);
+        broadcastIntent.putExtra("packageName",mContext.getPackageName());
+        broadcastIntent.setPackage("com.android.settings");
+        Installer.this.mContext.sendBroadcast(broadcastIntent);
+    }
+
+    public static void updateMedia(Context context, String path){
+        MediaScannerConnection.scanFile(context.getApplicationContext(), new String[] {path},null, null);
+    }
+
+
+}

PackageManager.java

Index: frameworks/base/core/java/komect/aisoho/cloudcomputer/PackageManager.java
===================================================================
@@ -0,0 +1,302 @@
+package komect.aisoho.cloudcomputer;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.IIntentReceiver;
+import android.content.IIntentSender;
+import android.content.Intent;
+import android.content.IntentSender;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageInstallObserver2;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInstaller;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Log;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
+import android.content.BroadcastReceiver;
+import android.provider.Settings;
+import android.os.Build;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+public class PackageManager {
+    private final String TAG = "PackageManager";
+    private static final boolean DEBUG = false;
+    private volatile PackageManager instance;
+    private Context mContext;
+
+    public PackageManager(Context context) {
+        this.mContext = context;
+    }
+
+    public PackageManager getInstance(Context context) {
+        if (this.instance == null) {
+            synchronized (PackageManager.class) {
+                if (this.instance == null) {
+                    this.instance = new PackageManager(context.getApplicationContext());
+                }
+            }
+        }
+        return this.instance;
+    }
+
+    public abstract class PackageInstallObserver {
+        public abstract void packageInstalled(String str, int i);
+
+        public PackageInstallObserver() {
+        }
+    }
+
+    public abstract class PackageDeleteObserver {
+        public abstract void packageDeleted(String str, int i);
+
+        public PackageDeleteObserver() {
+        }
+    }
+
+    public class LocalIntentReceiver {
+        private IIntentSender.Stub mLocalSender;
+        private final SynchronousQueue<Intent> mResult;
+
+        private LocalIntentReceiver() {
+            //PackageManager.this = r1;
+            this.mResult = new SynchronousQueue<>();
+            this.mLocalSender = new IIntentSender.Stub() { 
+                @Override 
+                public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
+                    try {
+                        LocalIntentReceiver.this.mResult.offer(intent, 60L, TimeUnit.SECONDS);
+                    } catch (InterruptedException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            };
+        }
+
+        public IntentSender getIntentSender() {
+            return new IntentSender((IIntentSender) this.mLocalSender);
+        }
+
+        public Intent getResult() {
+            try {
+                return this.mResult.take();
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private int createSession(PackageInstaller packageInstaller, PackageInstaller.SessionParams sessionParams) {
+        try {
+            int sessionId = packageInstaller.createSession(sessionParams);
+            return sessionId;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return -1;
+        }
+    }
+
+    private boolean copyInstallFile(PackageInstaller packageInstaller, int sessionId, String apkFilePath) {
+        IOException iOException;
+        InputStream in = null;
+        OutputStream out = null;
+        PackageInstaller.Session session = null;
+        boolean success = false;
+        if(DEBUG) Log.e(TAG, " copyInstallFile apkFilePath=" + apkFilePath);
+        try {
+            try {
+                File apkFile = new File(apkFilePath);
+                session = packageInstaller.openSession(sessionId);
+                out = session.openWrite("base.apk", 0L, apkFile.length());
+                in = new FileInputStream(apkFile);
+                int total = 0;
+                byte[] buffer = new byte[65536];
+                if(DEBUG) Log.e(TAG, " copyInstallFile apkFile=" + apkFile);
+                while (true) {
+                    int c = in.read(buffer);
+                    if (c == -1) {
+                        break;
+                    }
+                    total += c;
+                    out.write(buffer, 0, c);
+                }
+                session.fsync(out);
+                if(DEBUG) Log.e(TAG, "streamed " + total + " bytes");
+                success = true;
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+                try {
+                    in.close();
+                } catch (IOException e2) {
+                    iOException = e2;
+                    IOException e3 = iOException;
+                    e3.printStackTrace();
+                    session.close();
+                    return success;
+                }
+            } catch (Throwable th) {
+                try {
+                    out.close();
+                } catch (IOException e4) {
+                    e4.printStackTrace();
+                }
+                try {
+                    in.close();
+                } catch (IOException e5) {
+                    e5.printStackTrace();
+                }
+                session.close();
+                throw th;
+            }
+        } catch (IOException e6) {
+            e6.printStackTrace();
+            try {
+                out.close();
+            } catch (IOException e7) {
+                e7.printStackTrace();
+            }
+            try {
+                in.close();
+            } catch (IOException e8) {
+                iOException = e8;
+                IOException e32 = iOException;
+                e32.printStackTrace();
+                session.close();
+                return success;
+            }
+        }
+        session.close();
+        return success;
+    }
+
+    private void execInstallCommand(Context context, PackageInstaller packageInstaller, int sessionId, String filePath, PackageInstallObserver observer, String installerPackageName) {
+        PackageInstaller.Session session = null;
+        int success = 0;
+        try {
+            try {
+                if(DEBUG) Log.e(TAG, " execInstallCommand filePath=" + filePath + " installerPackageName=" + installerPackageName + " sessionId=" + sessionId);
+                session = packageInstaller.openSession(sessionId);
+                LocalIntentReceiver localReceiver = new LocalIntentReceiver();
+                session.commit(localReceiver.getIntentSender());
+                Intent result = localReceiver.getResult();
+                if (result != null) {
+                    int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, 1);
+                    if(DEBUG) Log.e(TAG, " execInstallCommand   status=" + status);
+                    if (status == 0) {
+                        success = 1;
+                    }
+                }
+                if (observer != null) {
+                    observer.packageInstalled(installerPackageName, success);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        } finally {
+            session.close();
+        }
+    }
+
+    public void installPackage(Uri packageURI, PackageInstallObserver observer, int flags, String installerPackageName) {
+        if (!ContentResolver.SCHEME_FILE.equals(packageURI.getScheme())) {
+            throw new UnsupportedOperationException("Only file:// URIs are supported");
+        }
+        String originPath = packageURI.getPath();
+        if(DEBUG) Log.e(TAG, " installPackage packageURI=" + packageURI + "  originPath=" + originPath);
+        Installer insObj = Installer.getInstance();
+
+
+        IPackageInstallObserver2 packageInstallObserver = new IPackageInstallObserver2.Stub() { 
+            @Override
+            public void onUserActionRequired(Intent intent) {
+                if(DEBUG) Log.e(TAG, "onUserActionRequired intent=" + intent);
+                //PackageInstallObserver.this.onUserActionRequired(intent);
+            }
+            @Override
+            public void onPackageInstalled(String basePackageName, int returnCode,
+                    String msg, Bundle extras) {
+                if(DEBUG) Log.e(TAG, " onPackageInstalled packageName=" + basePackageName);
+                //PackageInstallObserver.this.onPackageInstalled(basePackageName, returnCode, msg,extras);
+                PackageInstallObserver packageInstallObserver2 = observer;
+                if (packageInstallObserver2 != null) {
+                    packageInstallObserver2.packageInstalled(basePackageName, returnCode);
+                }
+            }
+        };
+
+        insObj.silentInstall(this.mContext, originPath, false,packageInstallObserver);
+    }
+
+
+    private static final String BROADCAST_ACTION_PACKAGE_DELETE = "com.android.packageinstaller.package_delete";
+
+    private BroadcastReceiver receiver = new BroadcastReceiver() { 
+        @Override 
+        public void onReceive(Context context, Intent intent) {
+            if(DEBUG) Log.e(TAG, "BroadcastReceiver   BROADCAST_ACTION_PACKAGE_DELETE" );
+            if (BROADCAST_ACTION_PACKAGE_DELETE.equals(intent.getAction())) {
+                int returnCode=intent.getIntExtra("returnCode",-1);
+                String pkgName=intent.getStringExtra("packageName");
+                if(DEBUG) Log.e(TAG, " packageDeleted success=" + returnCode+",pkgName="+pkgName+",mObserver="+mObserver);
+                if (mObserver != null) {
+                    mObserver.packageDeleted(pkgName, returnCode);
+                }
+            }
+        }
+    };
+
+    private IntentFilter localIntentFilter;
+    private PackageDeleteObserver mObserver;
+    private static final String BROADCAST_SETTING_DELETE_ACTION = "com.android.settings.ACTION_DELETE_COMMIT";
+
+    public void deletePackage(String packageName, final PackageDeleteObserver observer, int flags) {
+        if(DEBUG) Log.e(TAG, " deletePackage packageName=" + packageName);
+        if (true) {//非系統(tǒng)應(yīng)用會阻塞超時
+            mObserver=observer;
+            if (localIntentFilter==null) {
+                localIntentFilter = new IntentFilter();
+                localIntentFilter.addAction(BROADCAST_ACTION_PACKAGE_DELETE);
+                mContext.registerReceiver(this.receiver, localIntentFilter);
+            }
+            Intent broadcastIntent = new Intent(BROADCAST_SETTING_DELETE_ACTION);
+            broadcastIntent.putExtra("packageName",packageName);
+            broadcastIntent.putExtra("fromPkg",mContext.getPackageName());
+            broadcastIntent.setPackage("com.android.settings");
+            PackageManager.this.mContext.sendBroadcast(broadcastIntent);
+            if(DEBUG) Log.e(TAG, " deletePackage sendBroadcast=" + BROADCAST_SETTING_DELETE_ACTION);
+        }else{
+            try {
+                IPackageDeleteObserver packageDeleteObserver = new IPackageDeleteObserver.Stub() { 
+                    @Override 
+                    public void packageDeleted(String packageName2, int returnCode) throws RemoteException {
+                        PackageDeleteObserver packageDeleteObserver2 = observer;
+                        if (packageDeleteObserver2 != null) {
+                            packageDeleteObserver2.packageDeleted(packageName2, returnCode);
+                        }
+                    }
+                };
+                IPackageManager mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+                mPm.deletePackageAsUser(packageName, -1, packageDeleteObserver, UserHandle.myUserId(), 2);
+            } catch (Exception e) {
+                e.printStackTrace();
+                if(DEBUG) Log.e(TAG, " deletePackage e=" + e);
+            }
+        }
+    }
+}

PowerManager.java

Index: frameworks/base/core/java/komect/aisoho/cloudcomputer/PowerManager.java
===================================================================
@@ -0,0 +1,43 @@
+package komect.aisoho.cloudcomputer;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.IBinder;
+import android.util.Log;
+
+public class PowerManager {
+    private static final String TAG = "PowerManager";
+    private static final boolean DEBUG = false;
+    private Context mContext;
+    private static String reason = "userrequested";
+
+    public PowerManager(Context context) {
+        this.mContext = context;
+    }
+
+    public void reboot() {
+        if(DEBUG) Log.d(TAG, "reboot:");
+
+        Intent intent2 = new Intent();
+        intent2.setAction("android.intent.action.KTE_REBOOT");
+        this.mContext.sendBroadcast(intent2);
+    }
+
+    public void shutdown(boolean confirm, boolean wait) {
+        Intent intent2 = new Intent();
+        if (confirm) {
+            intent2.setAction("android.intent.action.KTE_SHUTDOWN_CONFIRM");
+        } else {
+            intent2.setAction("android.intent.action.KTE_SHUTDOWN");
+        }
+        this.mContext.sendBroadcast(intent2);
+    }
+
+    public void goToSleep(long time, int reason, int flags) {
+    }
+}

SettingManager.java

Index: frameworks/base/core/java/komect/aisoho/cloudcomputer/SettingManager.java
===================================================================
@@ -0,0 +1,61 @@
+package komect.aisoho.cloudcomputer;
+
+import android.content.Context;
+import android.content.Intent;
+
+public final class SettingManager {
+    private static final String TAG = "SettingManager";
+    private Context mContext;
+
+    public interface MultiScreenListener {
+        void onMultiScreenChanged(int i, int i2);
+    }
+
+    public SettingManager(Context context) {
+        this.mContext = context;
+    }
+
+    public void openSystemSettings() {
+        Intent newIntent = new Intent();
+        newIntent.setClassName("com.android.settings", "com.android.settings.Settings");
+        newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            this.mContext.startActivity(newIntent);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void openAndLinkBindPage() {
+        Intent newIntent = new Intent();
+        newIntent.setClassName("com.fudaocloud.launcher", "com.fudaocloud.launcher.ui.Main");
+        newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        newIntent.putExtra("isKomect", true);
+        try {
+            this.mContext.startActivity(newIntent);
+            Intent intent2 = new Intent();
+            intent2.setAction("android.intent.action.bind.andlink");
+            intent2.putExtra("bind_status", 0);
+            this.mContext.sendBroadcast(intent2);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void openOtherApp(String packageName) {
+        android.content.pm.PackageManager packageManager = this.mContext.getPackageManager();
+        Intent intent = packageManager.getLaunchIntentForPackage(packageName);
+        this.mContext.startActivity(intent);
+    }
+
+    public int getMultiScreenType() {
+        return 0;
+    }
+
+    public int getMultiScreenPosition() {
+        return 0;
+    }
+
+    public void setMultiScreenListener(MultiScreenListener listener) {
+    }
+}

在systemUi里面定制關(guān)機重啟廣播

Index: frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
===================================================================
@@ -107,9 +107,11 @@
 import android.content.ServiceConnection;
 import android.app.Service;
 import android.os.UserManager;
+import android.os.ServiceManager;
 import com.android.systemui.navigationbar.buttons.ButtonDispatcher;
 import com.android.systemui.navigationbar.NavigationBarView;
 import com.android.systemui.shared.recents.utilities.Utilities;
+import com.android.internal.statusbar.IStatusBarService;
 /**
  * Application class for SystemUI.
  */
@@ -219,6 +221,7 @@
         }
     };
     PowerManager.WakeLock mLock=null;
+    private IStatusBarService mBarService;
     @Override
     public void onCreate() {
         super.onCreate();
@@ -423,6 +426,10 @@
             bootToostFilter.addAction("panda.intent.action.REMOVE_ALL_TASK");
             bootToostFilter.addAction("panda.intent.action.chmod_file");
             bootToostFilter.addAction("com.djgd.andlink.unLock");
+            bootToostFilter.addAction("android.intent.action.KTE_REBOOT");
+            bootToostFilter.addAction("android.intent.action.KTE_SHUTDOWN_CONFIRM");
+            bootToostFilter.addAction("android.intent.action.KTE_SHUTDOWN");
+            mBarService = IStatusBarService.Stub.asInterface(ServiceManager.getService(Context.STATUS_BAR_SERVICE));
             registerReceiver(new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
@@ -591,6 +598,46 @@
                                 }
                             });
                             break;  
+
+                        case "android.intent.action.KTE_REBOOT":
+                            mUIHandler.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    SystemProperties.set("persist.sys.dj.shut", "true");
+                                    try {
+                                        mBarService.reboot(false);
+                                    } catch (RemoteException e) {
+                                    }
+                                }
+                            });
+                            break;
+                        
+                        case "android.intent.action.KTE_SHUTDOWN_CONFIRM":
+                            mUIHandler.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    SystemProperties.set("persist.sys.dj.shut", "false");
+                                    try {
+                                        mBarService.shutdown();
+                                    } catch (RemoteException e) {
+                                    }
+                                }
+                            });
+                            break;  
+
+                        case "android.intent.action.KTE_SHUTDOWN":
+                            mUIHandler.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    SystemProperties.set("persist.sys.dj.shut", "true");
+                                    try {
+                                        mBarService.shutdown();
+                                    } catch (RemoteException e) {
+                                    }
+                                }
+                            });
+                            break;  
+                                          
                     }
                 }
             }, bootToostFilter);

ShutdownThread.java

Index: frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
===================================================================
@@ -191,7 +191,11 @@
         /// AW: add end
 
         Log.d(TAG, "Notifying thread to start shutdown longPressBehavior=" + longPressBehavior);
-
+        String djShutdown = SystemProperties.get("persist.sys.dj.shut", "false");
+        if (djShutdown.equals("true")) {
+            confirm=false;
+        }
+        Log.e(TAG, "start shutdown djShutdown=" + djShutdown+",confirm="+confirm);
         if (confirm) {
             final CloseDialogReceiver closer = new CloseDialogReceiver(context);
             if (sConfirmDialog != null) {
@@ -437,7 +441,8 @@
         if (SecurityLog.isLoggingEnabled()) {
             SecurityLog.writeEvent(SecurityLog.TAG_OS_SHUTDOWN);
         }
-
+        //關(guān)閉屬性
+        SystemProperties.set("persist.sys.dj.shut", "false");
         // start the thread that initiates shutdown
         sInstance.mHandler = new Handler() {
         };

產(chǎn)品控制,客戶定制版本比較多拣展,不同版本可能并不需要這個接口,為了避免沖突夭问,另外Android.bp里面不好進行宏控制編譯管理,使用粗暴的方式覆蓋替換

Index: Android.bp
===================================================================
@@ -22,6 +22,7 @@
         "android/view/selectiontoolbar/*.aidl",
         "android/view/selectiontoolbar/*.java",
         "com/android/internal/widget/floatingtoolbar/RemoteFloatingToolbarPopup.java",
+        //"komect/**/*.java", //非基座產(chǎn)品要取消該注釋
     ],
     visibility: ["http://frameworks/base"],
 }

#為了方便版本切換是不用每次都手動注釋該注釋,提前copy一份Android.dp 為Android.dp1進行shell 命令覆蓋
Index: device-common.mk
===================================================================
 
 PRODUCT_COPY_FILES += $(PRODUCT_PREBUILT_PATH)/bImage:kernel
-
+#.db文件里面不太好添加宏控制擎淤,直接替換文件
+$(shell cp -f $(PRODUCT_DEVICE_PATH)/Android.bp1 $(LOCAL_PATH)/../../../frameworks/base/core/java/Android.bp)


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卦绣,一起剝皮案震驚了整個濱河市第喳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌校翔,老刑警劉巖唇撬,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異展融,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門告希,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扑浸,“玉大人,你說我怎么就攤上這事燕偶『仍耄” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵指么,是天一觀的道長酝惧。 經(jīng)常有香客問我,道長伯诬,這世上最難降的妖魔是什么晚唇? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮盗似,結(jié)果婚禮上哩陕,老公的妹妹穿的比我還像新娘。我一直安慰自己赫舒,他們只是感情好悍及,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著接癌,像睡著了一般心赶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缺猛,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天缨叫,我揣著相機與錄音,去河邊找鬼枯夜。 笑死弯汰,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的湖雹。 我是一名探鬼主播咏闪,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼摔吏!你這毒婦竟也來了鸽嫂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤征讲,失蹤者是張志新(化名)和其女友劉穎据某,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诗箍,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡癣籽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年瓶籽,在試婚紗的時候發(fā)現(xiàn)自己被綠了严拒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片预鬓。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡顶猜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嚣潜,到底是詐尸還是另有隱情,我是刑警寧澤垮媒,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站抗愁,受9級特大地震影響沫屡,放射性物質(zhì)發(fā)生泄漏勺届。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一紊婉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辑舷,春花似錦喻犁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至歌殃,卻和暖如春乔妈,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背氓皱。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工路召, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留勃刨,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓股淡,卻偏偏與公主長得像身隐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子唯灵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容