在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)