Commit 76f2f54a by lihuaikun

add:添加两个调试窗口 帮助测试人员提供数据给开发

parent c6d6da5f
......@@ -4,10 +4,8 @@
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<compositeConfiguration>
<compositeBuild compositeDefinitionSource="SCRIPT" />
</compositeConfiguration>
<option name="delegatedBuild" value="false" />
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
......@@ -18,7 +16,6 @@
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="testRunner" value="PLATFORM" />
</GradleProjectSettings>
</option>
</component>
......
......@@ -104,7 +104,7 @@ ext {
GITHUB_REPO_PATH = "../../androidlibrary"
PUBLISH_GROUP_ID = 'cn.dankal.android'
PUBLISH_ARTIFACT_ID = 'launcher'
PUBLISH_VERSION = '1.3.8'
PUBLISH_VERSION = '1.3.9'
}
uploadArchives {
......
......@@ -49,6 +49,7 @@
android:label="@string/permlab_write_settings"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signatureOrSystem" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
......@@ -180,6 +181,12 @@
android:name=".HelpActivity"
android:screenOrientation="portrait"></activity>
<activity
android:name=".debug.DebugInfoActivity"
android:screenOrientation="portrait"></activity>
<activity android:name=".debug.SearchAppCanUseActivity"
android:screenOrientation="portrait"></activity>
<!--
Should point to the content provider which can be used to dump Launcher3 compatible
worspace configuration to the dump's file descriptor by using launcher_dump.proto
......
......@@ -25,6 +25,7 @@ import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
import static com.android.launcher3.logging.LoggerUtils.newTarget;
import static com.android.launcher3.model.PackageUpdatedTask.OP_UPDATE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
......@@ -115,6 +116,7 @@ import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.logging.UserEventDispatcher.UserEventDelegate;
import com.android.launcher3.manager.Constants;
import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.model.PackageUpdatedTask;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
......@@ -289,14 +291,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
case Constants.ACTION_UPDATE_ICON:
String packageName = intent.getStringExtra(Constants.EXTRA_PACKAGE);
if (mModel != null) {
PackageUserKey packageUserKey = new PackageUserKey(packageName, Process.myUserHandle());
refreshAndBindWidgetsForPackageUser(packageUserKey);
mModel.enqueueModelUpdateTask(new PackageUpdatedTask(OP_UPDATE, Process.myUserHandle(), packageName));
needRefresh = true;
Logger.e(TAG, "ACTION_UPDATE_ICON\t" + packageName);
}
break;
}
}
......@@ -2410,12 +2407,12 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
long itemId = LauncherSettings.Settings.call(cr, LauncherSettings.Settings.METHOD_NEW_ITEM_ID).getLong(LauncherSettings.Settings.EXTRA_VALUE);
if (finded) {
// 最后一屏找到可以安放的空间
shortcutInfo.cellX = cell[0];
shortcutInfo.cellY = cell[1];
} else {
// 将图标放在下一屏
lastScreenId = LauncherSettings.Settings.call(cr,
LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
.getLong(LauncherSettings.Settings.EXTRA_VALUE);
......
......@@ -84,7 +84,7 @@ import java.util.concurrent.Executor;
*/
public class LauncherModel extends BroadcastReceiver
implements LauncherAppsCompat.OnAppsChangedCallbackCompat {
private static final boolean DEBUG_RECEIVER = false;
private static final boolean DEBUG_RECEIVER = true;
static final String TAG = "Launcher.Model";
......@@ -350,22 +350,34 @@ public class LauncherModel extends BroadcastReceiver
@Override
public void onPackageChanged(String packageName, UserHandle user) {
int op = PackageUpdatedTask.OP_UPDATE;
if (DEBUG_RECEIVER) {
Logger.e(TAG, "onPackageChanged\t" + packageName);
}
enqueueModelUpdateTask(new PackageUpdatedTask(op, user, packageName));
}
@Override
public void onPackageRemoved(String packageName, UserHandle user) {
if (DEBUG_RECEIVER) {
Logger.e(TAG, "onPackageRemoved\t" + packageName);
}
onPackagesRemoved(user, packageName);
}
public void onPackagesRemoved(UserHandle user, String... packages) {
int op = PackageUpdatedTask.OP_REMOVE;
if (DEBUG_RECEIVER) {
Logger.e(TAG, "onPackagesRemoved\t" + packages.toString());
}
enqueueModelUpdateTask(new PackageUpdatedTask(op, user, packages));
}
@Override
public void onPackageAdded(String packageName, UserHandle user) {
int op = PackageUpdatedTask.OP_ADD;
if (DEBUG_RECEIVER) {
Logger.e(TAG, "onPackageAdded\t" + packageName);
}
enqueueModelUpdateTask(new PackageUpdatedTask(op, user, packageName));
}
......
......@@ -280,6 +280,7 @@ public abstract class BaseAutoGetPermission {
}
}
gotoBatteryOptimize();
showToastLong("请点击【允许/确定】");
sleep();
return;
}
......@@ -488,19 +489,6 @@ public abstract class BaseAutoGetPermission {
}
}
if (!result && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Rect bounds = new Rect();
accessibilityNodeInfo1.getBoundsInScreen(bounds);
result = AccessibilityNodeOperateUtil.click(service, bounds);
Logger.e(TAG, "android o genture\t" + result);
// if (result) {
// dismissToast();
// return result;
// }
}
}
return result;
......
......@@ -11,6 +11,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import com.android.launcher3.accessibility.PermissionOpenAccessiblityService;
import com.android.launcher3.auto_get_permission.BaseAutoGetPermission;
import com.android.launcher3.util.Logger;
import com.android.launcher3.util.PermissionUtil;
import com.android.launcher3.util.SystemUtils;
import java.util.List;
......@@ -74,17 +75,11 @@ public class HonorAutoPermissionGetter extends BaseAutoGetPermission {
showToastLong("请点击【启用/激活此设备管理员】");
return;
}
}
}
@Override
public void reqeustAutoStartUp(AccessibilityEvent event) {
}
@Override
public void requestBatteryOptimize(AccessibilityEvent event) {
AccessibilityNodeInfo sourceNode = event.getSource();
if ("com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity".equals(event.getClassName())) {
......@@ -157,6 +152,7 @@ public class HonorAutoPermissionGetter extends BaseAutoGetPermission {
sleepShort();
}
}
PermissionUtil.isAutoStartUp=true;
//
// performGlobalAction(GLOBAL_ACTION_BACK);
// sleep();
......@@ -219,8 +215,7 @@ public class HonorAutoPermissionGetter extends BaseAutoGetPermission {
// PermissionUtil.isIgnoreBatteryOptimize = true;
// resetStep();
gotoBatteryOptimizeOnlyHUAWEI();
sleep();
PermissionUtil.isAutoStartUp=true;
}
......@@ -228,6 +223,11 @@ public class HonorAutoPermissionGetter extends BaseAutoGetPermission {
}
}
}
@Override
public void requestBatteryOptimize(AccessibilityEvent event) {
AccessibilityNodeInfo sourceNode=event.getSource();
long time2 = System.currentTimeMillis();
if ("com.android.settings.Settings$HighPowerApplicationsActivity".equals(event.getClassName())) {
......
......@@ -97,7 +97,7 @@ public class HuaweiAutoPermissionGetter extends BaseAutoGetPermission {
if (switcherNodes != null && switcherNodes.size() > 0) {
if (switcherNodes.get(0).isChecked()) {
if (switcherNodes.get(0).isCheckable()&&performAction(switcherNodes.get(0),AccessibilityNodeInfo.ACTION_CLICK)) {
if (switcherNodes.get(0).isCheckable() && performAction(switcherNodes.get(0), AccessibilityNodeInfo.ACTION_CLICK)) {
sleep();
} else {
showToastLong("请找到【" + appName + "】并点击右侧的按钮");
......@@ -128,8 +128,8 @@ public class HuaweiAutoPermissionGetter extends BaseAutoGetPermission {
} else {
showToastLong("请找到【" + appName + "】并点击右侧的按钮");
}
} else {
showToastLong("请找到【" + appName + "】并点击右侧的按钮");
}
}
......@@ -144,6 +144,7 @@ public class HuaweiAutoPermissionGetter extends BaseAutoGetPermission {
sleepShort();
}
}
PermissionUtil.isAutoStartUp = true;
//
// performGlobalAction(GLOBAL_ACTION_BACK);
// sleep();
......@@ -205,10 +206,7 @@ public class HuaweiAutoPermissionGetter extends BaseAutoGetPermission {
// PermissionUtil.isIgnoreBatteryOptimize = true;
// resetStep();
gotoBatteryOptimizeOnlyHUAWEI();
sleep();
PermissionUtil.isAutoStartUp = true;
}
......@@ -416,20 +414,19 @@ public class HuaweiAutoPermissionGetter extends BaseAutoGetPermission {
if ("com.android.settings.SubSettings".equals(event.getClassName()) && event.getText() != null && (event.getText().toString().contains("使用情况访问权限") || event.getText().toString().contains("使用记录访问权限") || event.getText().toString().contains("使用量数据访问"))) {
AccessibilityNodeInfo textViewNode = getChildNodeByIdEqualText(sourceNode, "android:id/title", "允许访问使用记录");
if (textViewNode != null && textViewNode.getParent() != null) {
if (performAction(textViewNode, AccessibilityNodeInfo.ACTION_CLICK)) {
resetStep();
} else {
showToastLong("请点击【允许访问使用记录】并返回上一页");
return;
}
if (performAction(textViewNode, AccessibilityNodeInfo.ACTION_CLICK)) {
resetStep();
} else if (textViewNode != null) {
showToastLong("请点击【允许访问使用记录右侧按钮】并返回上一页");
return;
} else {
textViewNode = getChildNodeByIdEqualText(sourceNode, "android:id/title", "允许查看使用情况");
if (performAction(textViewNode, AccessibilityNodeInfo.ACTION_CLICK)) {
resetStep();
} else {
showToastLong("请点击【允许查看使用情况】并返回上一页");
showToastLong("请点击【允许查看使用情况右侧按钮】并返回上一页");
return;
}
}
......@@ -473,7 +470,7 @@ public class HuaweiAutoPermissionGetter extends BaseAutoGetPermission {
resetStep();
} else {
showToastLong("请点击【USB 调试】按钮");
showToastLong("请点击【USB 调试】按钮 并返回上一页");
}
}
......
package com.android.launcher3.debug;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.R;
import com.android.launcher3.debug.adapter.TimeAdapter;
import com.android.launcher3.debug.adapter.WorkModeAdapter;
import com.android.launcher3.manager.ColumnDef;
import com.android.launcher3.manager.LauncherManager;
import com.android.launcher3.manager.ManagementInfo;
import com.android.launcher3.manager.TimeModeManager;
import com.android.launcher3.model.TimeConfig;
import com.android.launcher3.util.Logger;
import java.sql.Time;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* 显示管控信息
*/
public class DebugInfoActivity extends BaseActivity implements View.OnClickListener {
ImageView iv_back;
Button btn_change_exit_state;
TextView tv_exit_status;
Button btn_intercept_system_settings;
TextView tv_intercept_system_settings;
TextView tv_current_work_mode;
RecyclerView rv_work_mode;
RecyclerView rv_app_manage_info;
private WorkModeAdapter workModeAdapter;
private TimeAdapter timeAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_debug_info);
iv_back = findViewById(R.id.iv_back);
btn_change_exit_state = findViewById(R.id.btn_change_exit_state);
tv_exit_status = findViewById(R.id.tv_exit_status);
btn_intercept_system_settings = findViewById(R.id.btn_intercept_system_settings);
tv_intercept_system_settings = findViewById(R.id.tv_intercept_system_settings);
tv_current_work_mode = findViewById(R.id.tv_current_work_mode);
rv_work_mode = findViewById(R.id.rv_work_mode);
rv_app_manage_info = findViewById(R.id.rv_app_manage_info);
iv_back.setOnClickListener(this);
btn_change_exit_state.setOnClickListener(this);
btn_intercept_system_settings.setOnClickListener(this);
workModeAdapter = new WorkModeAdapter();
rv_work_mode.setLayoutManager(new LinearLayoutManager(this));
rv_work_mode.setAdapter(workModeAdapter);
timeAdapter = new TimeAdapter();
rv_app_manage_info.setLayoutManager(new LinearLayoutManager(this));
rv_app_manage_info.setAdapter(timeAdapter);
loadWorkMode();
loadAppInfo();
update();
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.iv_back) {
finish();
} else if (id == R.id.btn_change_exit_state) {
LauncherManager.getInstance().changeExitState(!LauncherManager.getInstance().getExitState());
update();
} else if (id == R.id.btn_intercept_system_settings) {
LauncherManager.getInstance().setInterceptSystemSetting(!LauncherManager.getInstance().isInterceptSystemSetting());
update();
}
}
private void update() {
if (LauncherManager.getInstance().getExitState()) {
btn_change_exit_state.setText("进入管制");
tv_exit_status.setText("当前未进入管制状态,所有规则均不生效");
tv_exit_status.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
} else {
btn_change_exit_state.setText("退出管制");
tv_exit_status.setText("当前已进入管制状态,所有规则已生效");
tv_exit_status.setTextColor(getResources().getColor(android.R.color.black));
}
if (LauncherManager.getInstance().isInterceptSystemSetting()) {
btn_intercept_system_settings.setText("关闭拦截系统设置");
tv_intercept_system_settings.setText("当前已开启拦截系统设置");
tv_intercept_system_settings.setTextColor(getResources().getColor(android.R.color.black));
} else {
btn_intercept_system_settings.setText("开启拦截系统设置");
tv_intercept_system_settings.setText("当前已关闭拦截系统设置");
tv_intercept_system_settings.setTextColor(getResources().getColor(android.R.color.holo_red_dark));
}
}
public void loadWorkMode() {
switch (TimeModeManager.getInstance(getApplicationContext()).getCurrentWorkModel()) {
case ColumnDef.TimeManager.HOLIDAY_MODE:
tv_current_work_mode.setText("当前模式:假期模式");
break;
case ColumnDef.TimeManager.WEEK_RESET:
tv_current_work_mode.setText("当前模式:周末模式");
break;
case ColumnDef.TimeManager.WORK_DAY:
tv_current_work_mode.setText("当前模式:工作日模式");
break;
default:
tv_current_work_mode.setText("当前模式:未设置模式");
}
if (TimeModeManager.getInstance(getApplicationContext()).getConfigMap() != null) {
Iterator<Map.Entry<Integer, TimeConfig>> iterator = TimeModeManager.getInstance(getApplicationContext()).getConfigMap().entrySet().iterator();
List<TimeConfig> timeConfigs = new ArrayList<>();
while (iterator.hasNext()) {
Map.Entry<Integer, TimeConfig> entry = iterator.next();
timeConfigs.add(entry.getValue());
}
workModeAdapter.setTimeConfigs(timeConfigs);
workModeAdapter.notifyDataSetChanged();
}
}
public void loadAppInfo() {
Logger.e("loadAppInfo", "loadAppInfo\t" + LauncherManager.getInstance().getAppInfo().size());
if (LauncherManager.getInstance().getAppInfo() != null) {
Iterator<Map.Entry<String, ManagementInfo>> iterator = LauncherManager.getInstance().getAppInfo().entrySet().iterator();
List<ManagementInfo> timeConfigs = new ArrayList<>();
while (iterator.hasNext()) {
Map.Entry<String, ManagementInfo> entry = iterator.next();
timeConfigs.add(entry.getValue());
}
timeAdapter.setManagementInfos(timeConfigs);
timeAdapter.notifyDataSetChanged();
}
}
}
package com.android.launcher3.debug;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.R;
import com.android.launcher3.manager.ColumnDef;
import com.android.launcher3.manager.LauncherManager;
import com.android.launcher3.manager.ManagementInfo;
import com.android.launcher3.manager.TimeModeManager;
import com.android.launcher3.model.AppTimeConfig;
import com.android.launcher3.model.AppUseData;
import com.android.launcher3.model.TimeConfig;
import com.android.launcher3.model.TimeRegion;
import com.android.launcher3.util.Logger;
import com.android.launcher3.util.PermissionUtil;
import com.android.launcher3.util.TimeUtils;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import androidx.annotation.Nullable;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
/**
* 查询应用是否可以使用
*/
public class SearchAppCanUseActivity extends BaseActivity implements View.OnClickListener {
private ImageView ivBack;
private Button btn_confirm;
private EditText et_package;
private TextView tv_reason;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_app_can_use);
ivBack = findViewById(R.id.iv_back);
btn_confirm = findViewById(R.id.btn_confirm);
et_package = findViewById(R.id.et_package);
tv_reason = findViewById(R.id.tv_reason);
ivBack.setOnClickListener(this);
btn_confirm.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.iv_back) {
finish();
} else if (id == R.id.btn_confirm) {
if (TextUtils.isEmpty(et_package.getText().toString().trim())) {
Toast.makeText(getApplicationContext(), "请输入包名", Toast.LENGTH_SHORT).show();
return;
}
search(et_package.getText().toString().trim());
}
}
private void search(String packageName) {
ManagementInfo managementInfo = LauncherManager.getInstance().getManageAppInfo(packageName);
if (managementInfo == null) {
tv_reason.setText("应用未分类不可使用");
return;
}
if (managementInfo.getUseType() == ColumnDef.AppUseType.UNCLASS_TYPE) {
tv_reason.setText("应用未分类不可使用");
return;
}
if (managementInfo.getUseType() == ColumnDef.AppUseType.LEARN_TYPE || managementInfo.getUseType() == ColumnDef.AppUseType.SAFE_TYPE) {
tv_reason.setText("无需管控类或学习类可以正常使用");
return;
}
Observable.just(packageName).subscribeOn(Schedulers.computation()).observeOn(AndroidSchedulers.mainThread()).map(new Function<String, String>() {
@Override
public String apply(String s) throws Exception {
return canUse(s);
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable d) {
Toast.makeText(getApplicationContext(), "正在查询请稍后", Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(String s) {
tv_reason.setText(s);
}
@Override
public void onError(Throwable e) {
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete() {
}
});
}
/**
* 判断应用是否可以使用
*
* @param packageName
* @return
*/
public String canUse(String packageName) {
ManagementInfo info = LauncherManager.getInstance().getManageAppInfo(packageName);
int currentWorkModel = TimeModeManager.getInstance(this).getCurrentWorkModel();
TimeConfig config = TimeModeManager.getInstance(this).getTimeConfig(TimeModeManager.getInstance(this).getCurrentWorkModel());
Map<Integer, TimeConfig> configMap = TimeModeManager.getInstance(this).getConfigMap();
if (config == null) {
return "没有设置工作模式 App不可使用";
}
if (info.getLock() != ColumnDef.LockApp.LOCKED) {
if (includeTimeRegion(config.getRegionList())) {
// 判断金币是否充足
if (LauncherManager.getInstance().getCoinNum() <= 0) {
return "金币不足 App不可使用";
}
long canUseTime = 0;
// 获取某个应用类别下的使用时间
if (currentWorkModel == ColumnDef.TimeManager.HOLIDAY_MODE) {
canUseTime = getUseTimeByAppType(config.getAppTimeConfigs(), info.getUseType());
} else {
if (TimeUtils.isWeekend()) {
currentWorkModel = ColumnDef.TimeManager.WEEK_RESET;
canUseTime = getUseTimeByAppType(configMap.get(ColumnDef.TimeManager.WEEK_RESET).getAppTimeConfigs(), info.getUseType());
} else {
currentWorkModel = ColumnDef.TimeManager.WORK_DAY;
canUseTime = getUseTimeByAppType(configMap.get(ColumnDef.TimeManager.WORK_DAY).getAppTimeConfigs(), info.getUseType());
}
}
HashMap<Integer, Long> useTimestamp = getAppUseTimeStamp(this);
long totalUseTimeByType = useTimestamp.get(info.getUseType());
if (totalUseTimeByType > canUseTime) {
return "当前应用所属的分类时长已使用完毕\t" + "该分类下已使用的总时长\n" + totalUseTimeByType + "\t" + "该分类下可使用的总时长\n" + canUseTime;
}
// app自身的设置使用时长优先级更高
if (info.getUseEndTimeStamp() > 0) {
// 应用本身的使用时间
canUseTime = Math.min(canUseTime, info.getUseEndTimeStamp());
}
long hadUseTime = getAppUseTimeStampDay(this, packageName);
if (canUseTime > 0 && hadUseTime > canUseTime) {
return "应用无法使用\t" + "该分类下已使用的总时长 =" + totalUseTimeByType + "\t" + "该分类下可使用的总时长=" + canUseTime + "\t应用自身的可使用时长=" + info.getUseEndTimeStamp() + "\t应用当天已使用时长=" + hadUseTime;
}
return "应用可以正常使用\t" + "该分类下已使用的总时长 =" + totalUseTimeByType + "\t" + "该分类下可使用的总时长=" + canUseTime + "\t应用自身的可使用时长=" + info.getUseEndTimeStamp() + "\t应用当天已使用时长=" + hadUseTime;
}
} else {
return "应用已锁定 无法使用";
}
return "应用可以正常使用";
}
/**
* 获取某个app当天的已使用时长
*
* @param context
* @param packageName
* @return
*/
private long getAppUseTimeStampDay(Context context, String packageName) {
long totalUseTimeStampDaliy = 0;
if (PermissionUtil.checkAppUsagePermission(context)) {
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
Calendar beginCal = Calendar.getInstance();
beginCal.set(Calendar.HOUR_OF_DAY, 0);
beginCal.set(Calendar.MINUTE, 0);
beginCal.set(Calendar.SECOND, 0);
Calendar endCal = Calendar.getInstance();
UsageEvents events = usageStatsManager.queryEvents(beginCal.getTimeInMillis(), endCal.getTimeInMillis());
UsageEvents.Event event = new UsageEvents.Event();
long startTime = beginCal.getTimeInMillis();
boolean isForegounding = false;
while (events.hasNextEvent()) {
events.getNextEvent(event);
int eventType = event.getEventType();
long eventTime = event.getTimeStamp();
String eventPackage = event.getPackageName();
if (eventPackage.equals(packageName)) {
if (eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
startTime = eventTime;
isForegounding = true;
}
if (eventType == UsageEvents.Event.MOVE_TO_BACKGROUND) {
isForegounding = false;
totalUseTimeStampDaliy += eventTime - startTime;
}
}
}
if (isForegounding) {
totalUseTimeStampDaliy += System.currentTimeMillis() - startTime;
}
}
return totalUseTimeStampDaliy / 1000;
}
/**
* 判断当前时间是否在选中的时间范围内
*
* @param regionList
* @return
*/
public boolean includeTimeRegion(List<TimeRegion> regionList) {
if (regionList == null)
return false;
if (regionList.isEmpty())
return false;
long time = (System.currentTimeMillis() - TimeUtils.getTimeZeroClock()) / 1000;
for (TimeRegion region : regionList) {
if (region.containTime(time)) {
return true;
}
}
return false;
}
public long getUseTimeByAppType(List<AppTimeConfig> timeConfigs, @ColumnDef.AppUseType.UseTypeMode int appType) {
if (timeConfigs == null)
return 0;
for (AppTimeConfig timeConfig : timeConfigs) {
if (timeConfig.appType == appType) {
return timeConfig.appUseTimeSecond;
}
}
return 0;
}
/**
* 获取各个分类的所有app下当天已使用的时长
*
* @return
*/
public HashMap<Integer, Long> getAppUseTimeStamp(Context context) {
ArrayMap<String, ManagementInfo> appInfo = LauncherManager.getInstance().getAppInfo();
HashMap<Integer, Long> timeStamp = new HashMap<>();
HashSet<String> usedPackaged = new HashSet<>();
List<AppUseData> data = new ArrayList<>();
if (PermissionUtil.checkAppUsagePermission(context)) {
UsageStatsManager usageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
// 计算当天使用过的应用
if (usageStatsManager != null) {
Calendar beginCal = Calendar.getInstance();
beginCal.set(Calendar.HOUR_OF_DAY, 0);
beginCal.set(Calendar.MINUTE, 0);
beginCal.set(Calendar.SECOND, 0);
Calendar endCal = Calendar.getInstance();
UsageEvents events = usageStatsManager.queryEvents(beginCal.getTimeInMillis(), endCal.getTimeInMillis());
UsageEvents.Event event = new UsageEvents.Event();
while (events.hasNextEvent()) {
events.getNextEvent(event);
if (event.getEventType() == UsageEvents.Event.MOVE_TO_BACKGROUND || event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
String eventPackage = event.getPackageName();
usedPackaged.add(eventPackage);
}
}
}
}
Iterator<String> iterator = usedPackaged.iterator();
//计算当天使用过的应用 使用时长
while (iterator.hasNext()) {
String packageName = iterator.next();
long useTimeStamp = getAppUseTimeStampDay(context, packageName);
data.add(new AppUseData(packageName, useTimeStamp));
}
long totalUseTimeStampDaliyLearnType = 0;
long totalUseTimeStampDaliyGameType = 0;
long totalUseTimeStampDaliyUnclassType = 0;
long totalUseTimeStampDaliySafeType = 0;
if (data.size() > 0) {
for (AppUseData useData : data) {
long useTimestamp = useData.mUsageTime;
ManagementInfo info = appInfo.get(useData.mPackageName);
if (LauncherManager.getInstance().isSafePackageName(useData.mPackageName)) {
totalUseTimeStampDaliySafeType += useTimestamp;
} else {
if (info != null) {
switch (info.getUseType()) {
case ColumnDef.AppUseType.LEARN_TYPE:
totalUseTimeStampDaliyLearnType += useTimestamp;
break;
case ColumnDef.AppUseType.GAME_LOCK_TYPE:
totalUseTimeStampDaliyGameType += useTimestamp;
break;
case ColumnDef.AppUseType.SAFE_TYPE:
totalUseTimeStampDaliySafeType += useTimestamp;
break;
}
} else {
totalUseTimeStampDaliyUnclassType += useTimestamp;
}
}
}
}
timeStamp.put(ColumnDef.AppUseType.LEARN_TYPE, totalUseTimeStampDaliyLearnType);
timeStamp.put(ColumnDef.AppUseType.GAME_LOCK_TYPE, totalUseTimeStampDaliyGameType);
timeStamp.put(ColumnDef.AppUseType.SAFE_TYPE, totalUseTimeStampDaliySafeType);
timeStamp.put(ColumnDef.AppUseType.UNCLASS_TYPE, totalUseTimeStampDaliyUnclassType);
return timeStamp;
}
}
package com.android.launcher3.debug.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.launcher3.R;
import com.android.launcher3.manager.ColumnDef;
import com.android.launcher3.manager.ManagementInfo;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class TimeAdapter extends RecyclerView.Adapter<TimeAdapter.ViewHolder> {
private LayoutInflater mInflater;
private List<ManagementInfo> managementInfos;
public void setManagementInfos(List<ManagementInfo> managementInfos) {
this.managementInfos = managementInfos;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (mInflater == null) {
mInflater = LayoutInflater.from(parent.getContext());
}
return new ViewHolder(mInflater.inflate(R.layout.adapter_app_manager_info, null));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bindData(managementInfos.get(position));
}
@Override
public int getItemCount() {
return managementInfos == null ? 0 : managementInfos.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView tv_package_info;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv_package_info = itemView.findViewById(R.id.tv_package_info);
}
public void bindData(ManagementInfo managementInfo) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(managementInfo.getPackageName()).append("\t");
switch (managementInfo.getUseType()) {
case ColumnDef.AppUseType.GAME_LOCK_TYPE:
stringBuilder.append("游戏类");
break;
case ColumnDef.AppUseType.LEARN_TYPE:
stringBuilder.append("学习类");
break;
case ColumnDef.AppUseType.SAFE_TYPE:
stringBuilder.append("无需管控类");
break;
case ColumnDef.AppUseType.UNCLASS_TYPE:
stringBuilder.append("未分类");
break;
}
stringBuilder.append("\t");
stringBuilder.append("应用可使用时长" + managementInfo.getUseEndTimeStamp() + "秒\n");
stringBuilder.append(managementInfo.getLock() == ColumnDef.LockApp.LOCKED ? "应用已锁定" : "未锁定");
tv_package_info.setText(stringBuilder.toString());
}
}
}
package com.android.launcher3.debug.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.android.launcher3.R;
import com.android.launcher3.manager.ColumnDef;
import com.android.launcher3.manager.TimeModeManager;
import com.android.launcher3.model.AppTimeConfig;
import com.android.launcher3.model.TimeConfig;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class WorkModeAdapter extends RecyclerView.Adapter<WorkModeAdapter.ViewHolder> {
private List<TimeConfig> timeConfigs;
private LayoutInflater mInflater;
public void setTimeConfigs(List<TimeConfig> timeConfigs) {
this.timeConfigs = timeConfigs;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (mInflater == null) {
mInflater = LayoutInflater.from(parent.getContext());
}
return new ViewHolder(mInflater.inflate(R.layout.adapter_work_mode_item, null));
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bindData(timeConfigs.get(position));
}
@Override
public int getItemCount() {
return timeConfigs == null ? 0 : timeConfigs.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private TextView tv_mode_name;
private TextView tv_mode_use_time;
private TextView tv_mode_rest_time;
private TextView tv_mode_game;
private TextView tv_app_type_limit_time;
public ViewHolder(@NonNull View itemView) {
super(itemView);
tv_mode_name=itemView.findViewById(R.id.tv_mode_name);
tv_mode_use_time=itemView.findViewById(R.id.tv_mode_use_time);
tv_mode_rest_time=itemView.findViewById(R.id.tv_mode_rest_time);
tv_mode_game=itemView.findViewById(R.id.tv_mode_game);
tv_app_type_limit_time=itemView.findViewById(R.id.tv_app_type_limit_time);
}
public void bindData(TimeConfig config) {
switch (config.getWorkMode()) {
case ColumnDef.TimeManager.HOLIDAY_MODE:
tv_mode_name.setText("假期模式");
break;
case ColumnDef.TimeManager.WEEK_RESET:
tv_mode_name.setText("周末模式");
break;
case ColumnDef.TimeManager.WORK_DAY:
tv_mode_name.setText("工作日模式");
break;
default:
tv_mode_name.setText("未设置模式");
}
tv_mode_use_time.setText(config.getRegionList().size()+"\t可使用时间段"+config.getUseTimeRegion());
tv_mode_rest_time.setText(config.getRegionList().size()+"\t休息时间段"+config.getRestTimeRegion());
tv_mode_game.setText("游戏使用时间:"+config.getGameUseTimestamp()+"秒");
if (config.getAppTimeConfigs()!=null){
StringBuilder stringBuilder=new StringBuilder();
for (AppTimeConfig appTimeConfig:config.getAppTimeConfigs()){
switch (appTimeConfig.appType){
case ColumnDef.AppUseType.GAME_LOCK_TYPE:
stringBuilder.append("游戏类使用时长"+appTimeConfig.appUseTimeSecond+"秒\n");
break;
case ColumnDef.AppUseType.LEARN_TYPE:
stringBuilder.append("学习类使用时长"+appTimeConfig.appUseTimeSecond+"秒\n");
break;
case ColumnDef.AppUseType.SAFE_TYPE:
stringBuilder.append("无需管控类使用时长"+appTimeConfig.appUseTimeSecond+"秒\n");
break;
case ColumnDef.AppUseType.UNCLASS_TYPE:
stringBuilder.append("未分类使用时长"+appTimeConfig.appUseTimeSecond+"秒\n");
break;
}
}
tv_app_type_limit_time.setText(stringBuilder.toString());
}else {
tv_app_type_limit_time.setText("无");
}
}
}
}
......@@ -27,6 +27,8 @@ import com.android.launcher3.LockScreenActivity;
import com.android.launcher3.LockScreenInterface;
import com.android.launcher3.accessibility.FloatWindowService;
import com.android.launcher3.accessibility.ListenerAppService;
import com.android.launcher3.debug.DebugInfoActivity;
import com.android.launcher3.debug.SearchAppCanUseActivity;
import com.android.launcher3.model.ConfigManager;
import com.android.launcher3.model.TimeConfig;
import com.android.launcher3.provider.DBManager;
......@@ -284,6 +286,10 @@ public class LauncherManager {
}
/**
* 状态更新发广播给桌面(Launcher)处理
* @param packageName
*/
private void refreshLauncherIconWidget(String packageName) {
Intent intent = new Intent(Constants.ACTION_UPDATE_ICON);
......@@ -863,4 +869,16 @@ public class LauncherManager {
public void setCoinNum(int mCoinNum) {
this.mCoinNum = mCoinNum;
}
public void jumpDebugInfo(Context context){
Intent intent=new Intent(context, DebugInfoActivity.class);
context.startActivity(intent);
}
public void jumpSearchAppCanUse(Context context){
Intent intent=new Intent(context, SearchAppCanUseActivity.class);
context.startActivity(intent);
}
}
......@@ -198,6 +198,10 @@ public class TimeModeManager {
}
/**
* 获取各个分类的所有app下当天已使用的时长
* @return
*/
public HashMap<Integer, Long> getAppUseTimeStamp() {
Logger.e(TAG, "getAppUseTimeStamp start\t" + System.currentTimeMillis());
ArrayMap<String, ManagementInfo> appInfo = LauncherManager.getInstance().getAppInfo();
......@@ -518,4 +522,8 @@ public class TimeModeManager {
'}';
}
}
public Map<Integer, TimeConfig> getConfigMap() {
return configMap;
}
}
......@@ -25,7 +25,6 @@ import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;
import com.android.launcher3.BuildConfig;
import com.android.launcher3.accessibility.AppManagerAccessiblityService;
import com.android.launcher3.accessibility.DeviceReceiver;
import com.android.launcher3.compat.LauncherAppsCompat;
......@@ -41,8 +40,10 @@ public class PermissionUtil {
private static final String TAG = "PermissionUtil";
public static boolean isAdminDevice = false;
//临时变量 判断电量优化
public static boolean isBatterySaveClose = false;
// 临时变量 判断自启动
public static boolean isAutoStartUp=false;
public static boolean isAccessibilitySettingsOn(Context mContext) {
int accessibilityEnabled = 0;
......@@ -176,19 +177,7 @@ public class PermissionUtil {
* @return
*/
public static boolean checkAutoStartUp(Context context) {
PackageManager pm=context.getPackageManager();
boolean haveStartup = false;
try {
PackageInfo pkgInfo = pm
.getPackageInfo(context.getPackageName(), PackageManager.GET_RECEIVERS
| PackageManager.GET_META_DATA);// 通过包名,返回包信息
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
haveStartup = pm.checkPermission(
"android.permission.RECEIVE_BOOT_COMPLETED", context.getPackageName()) == PackageManager.PERMISSION_GRANTED;
return haveStartup;
return isAutoStartUp;
}
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:id="@+id/iv_back"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="18dp"
android:src="@drawable/ic_back_black"></ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="此页面仅调试用"
android:textColor="@android:color/black"
android:textSize="18sp"></TextView>
</RelativeLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<Button
android:id="@+id/btn_change_exit_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
<TextView
android:id="@+id/tv_exit_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textSize="14sp"></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<Button
android:id="@+id/btn_intercept_system_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></Button>
<TextView
android:id="@+id/tv_intercept_system_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textSize="14sp"></TextView>
</LinearLayout>
<TextView
android:id="@+id/tv_current_work_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_marginTop="10dp"
android:textColor="@android:color/black"
></TextView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_work_mode"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:layout_marginTop="10dp"
android:textColor="@android:color/black"
android:text="App 管理信息"
></TextView>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_app_manage_info"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
</ScrollView>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:id="@+id/iv_back"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="18dp"
android:src="@drawable/ic_back_black"></ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="查询app是否可使用"
android:textColor="@android:color/black"
android:textSize="18sp"></TextView>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/btn_confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="查询"></Button>
<EditText
android:id="@+id/et_package"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/btn_confirm"
android:hint="输入包名例如:cn.dankal.bzshchild"></EditText>
</RelativeLayout>
<TextView
android:id="@+id/tv_reason"
android:layout_width="wrap_content"
android:textSize="14sp"
android:layout_marginTop="10dp"
android:textColor="@android:color/holo_red_dark"
android:layout_height="wrap_content"></TextView>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_package_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="14sp"></TextView>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_mode_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="14sp"></TextView>
<TextView
android:id="@+id/tv_mode_use_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="@android:color/black"
android:textSize="14sp"></TextView>
<TextView
android:id="@+id/tv_mode_rest_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="@android:color/black"
android:textSize="14sp"></TextView>
<TextView
android:id="@+id/tv_mode_game"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="@android:color/black"
android:textSize="14sp"></TextView>
<TextView
android:id="@+id/tv_app_type_limit_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textColor="@android:color/black"
android:textSize="14sp"></TextView>
</LinearLayout>
\ No newline at end of file
......@@ -6,5 +6,6 @@
android:canRetrieveWindowContent="true"
android:description="@string/app_manager_accessibility_service_description"
android:canRequestFilterKeyEvents="true"
android:settingsActivity="com.dankal.dankal_launcher.PackageManageActivity"
android:canPerformGestures="true"
android:notificationTimeout="100" />
\ No newline at end of file
......@@ -139,6 +139,9 @@ public class PackageManageActivity extends Activity {
//
//
// LauncherManager.getInstance().setCurrentWorkMode(ColumnDef.TimeManager.WORK_DAY);
// handler.sendEmptyMessageDelayed(2,2000);
LauncherManager.getInstance().jumpDebugInfo(PackageManageActivity.this);
}
});
......@@ -178,7 +181,7 @@ public class PackageManageActivity extends Activity {
// LauncherManager.getInstance().forceLockScreenForever(PackageManageActivity.this);
// handler.sendEmptyMessageDelayed(1,1000*15);
// PermissionUtil.setDefaultL(getApplicationContext());
PermissionUtil.gotoAppUsagePermission(getApplicationContext());
LauncherManager.getInstance().jumpSearchAppCanUse(PackageManageActivity.this);
}
});
......@@ -196,16 +199,11 @@ public class PackageManageActivity extends Activity {
new Thread(new Runnable() {
@Override
public void run() {
<<<<<<< HEAD
/* LauncherManager.getInstance().changeExitState(true);
LauncherManager.getInstance().setInterceptSystemSetting(false);*/
PermissionUtil.gotoBatteryOptimize(getApplicationContext());
// handler.sendEmptyMessage(3);
=======
// PermissionUtil.gotoBatteryOptimize(getApplicationContext());
LauncherManager.getInstance().changeExitState(true);
LauncherManager.getInstance().setInterceptSystemSetting(false);
>>>>>>> 1
}
}).start();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment