diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml index 781f2a1..3ad63fc 100644 --- a/AndroidManifest-common.xml +++ b/AndroidManifest-common.xml @@ -19,6 +19,7 @@ --> @@ -176,6 +181,27 @@ + + + + + + + + + + + + + + + + + + + + + - @string/app_name + @string/app_uiui diff --git a/res/values/strings.xml b/res/values/strings.xml index 13e096c..240cb36 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -23,6 +23,8 @@ Launcher3 + UIUIOS + diff --git a/res/xml/network.xml b/res/xml/network.xml new file mode 100644 index 0000000..dca93c0 --- /dev/null +++ b/res/xml/network.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/com/android/uiuios/Launcher.java b/src/com/android/uiuios/Launcher.java index 9eb94be..eba381d 100644 --- a/src/com/android/uiuios/Launcher.java +++ b/src/com/android/uiuios/Launcher.java @@ -30,6 +30,7 @@ import static com.android.uiuios.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD; import static com.android.uiuios.logging.LoggerUtils.newContainerTarget; import static com.android.uiuios.logging.LoggerUtils.newTarget; import static com.android.uiuios.states.RotationHelper.REQUEST_NONE; +import static com.android.uiuios.touch.ItemClickHandler.getInfoFromPackageName; import static com.android.uiuios.util.RaceConditionTracker.ENTER; import static com.android.uiuios.util.RaceConditionTracker.EXIT; @@ -52,6 +53,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentSender; import android.content.SharedPreferences; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Configuration; @@ -66,6 +68,7 @@ import android.os.Parcelable; import android.os.Process; import android.os.StrictMode; import android.text.TextUtils; +import android.text.format.DateUtils; import android.text.method.TextKeyListener; import android.util.Log; import android.util.SparseArray; @@ -82,6 +85,9 @@ import android.view.animation.OvershootInterpolator; import android.widget.Toast; import com.android.uiuios.DropTarget.DragObject; +import com.android.uiuios.Statistics.AppInformation; +import com.android.uiuios.TTUtils.APKUtils; +import com.android.uiuios.TTUtils.Utils; import com.android.uiuios.accessibility.LauncherAccessibilityDelegate; import com.android.uiuios.allapps.AllAppsContainerView; import com.android.uiuios.allapps.AllAppsStore; @@ -108,6 +114,9 @@ import com.android.uiuios.logging.UserEventDispatcher; import com.android.uiuios.logging.UserEventDispatcher.UserEventDelegate; import com.android.uiuios.model.AppLaunchTracker; import com.android.uiuios.model.ModelWriter; +import com.android.uiuios.network.BaseResponse; +import com.android.uiuios.network.NetWorkManager; +import com.android.uiuios.network.api.addAppLog; import com.android.uiuios.notification.NotificationListener; import com.android.uiuios.pageindicators.PageIndicatorDots; import com.android.uiuios.popup.PopupContainerWithArrow; @@ -155,6 +164,7 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -163,6 +173,11 @@ import java.util.function.Predicate; import androidx.annotation.Nullable; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + /** * Default launcher application. */ @@ -216,7 +231,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // How long to wait before the new-shortcut animation automatically pans the workspace private static final int NEW_APPS_PAGE_MOVE_DELAY = 500; private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5; - @Thunk static final int NEW_APPS_ANIMATION_DELAY = 500; + @Thunk + static final int NEW_APPS_ANIMATION_DELAY = 500; private static final int APPS_VIEW_ALPHA_CHANNEL_INDEX = 1; private static final int SCRIM_VIEW_ALPHA_CHANNEL_INDEX = 0; @@ -224,9 +240,11 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, private LauncherAppTransitionManager mAppTransitionManager; private Configuration mOldConfig; - @Thunk Workspace mWorkspace; + @Thunk + Workspace mWorkspace; private View mLauncherView; - @Thunk DragLayer mDragLayer; + @Thunk + DragLayer mDragLayer; private DragController mDragController; private AppWidgetManagerCompat mAppWidgetManager; @@ -234,23 +252,27 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, private final int[] mTmpAddItemCellCoordinates = new int[2]; - @Thunk Hotseat mHotseat; + @Thunk + Hotseat mHotseat; private PageIndicatorDots mPageIndicatorDots; private DropTargetBar mDropTargetBar; // Main container view for the all apps screen. - @Thunk AllAppsContainerView mAppsView; + @Thunk + AllAppsContainerView mAppsView; AllAppsTransitionController mAllAppsController; // Scrim view for the all apps and overview state. - @Thunk ScrimView mScrimView; + @Thunk + ScrimView mScrimView; // UI and state for the overview panel private View mOverviewPanel; - @Thunk boolean mWorkspaceLoading = true; + @Thunk + boolean mWorkspaceLoading = true; private ArrayList mOnResumeCallbacks = new ArrayList<>(); @@ -406,7 +428,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, RaceConditionTracker.onEvent(ON_CREATE_EVT, EXIT); mStateManager.addStateListener(new LauncherStateManager.StateListener() { @Override - public void onStateTransitionStart(LauncherState toState) {} + public void onStateTransitionStart(LauncherState toState) { + } @Override public void onStateTransitionComplete(LauncherState finalState) { @@ -495,19 +518,18 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, registerReceiver(mTimeChangedReceiver, filter); } - private class TimeChangedReceiver extends BroadcastReceiver { + private static class TimeChangedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) { + if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) { Log.e("fht", "TimeChangedReceiver:" + "data changed"); - } else if (intent.getAction().equals(Intent.ACTION_TIME_CHANGED)) { + } else if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { Log.e("fht", "TimeChangedReceiver:" + "time changed"); - } else if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) { + } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { Log.e("fht", "TimeChangedReceiver:" + "timezone changed"); - } else if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) { + } else if (Intent.ACTION_TIME_TICK.equals(intent.getAction())) { Log.e("fht", "TimeChangedReceiver:" + "time tick"); - } } } @@ -894,7 +916,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, - int[] grantResults) { + int[] grantResults) { PendingRequestArgs pendingArgs = mPendingRequestArgs; if (requestCode == REQUEST_PERMISSION_CALL_PHONE && pendingArgs != null && pendingArgs.getRequestCode() == REQUEST_PERMISSION_CALL_PHONE) { @@ -940,7 +962,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } } - @Thunk void completeTwoStageWidgetDrop( + @Thunk + void completeTwoStageWidgetDrop( final int resultCode, final int appWidgetId, final PendingRequestArgs requestArgs) { CellLayout cellLayout = mWorkspace.getScreenWithId(requestArgs.screenId); Runnable onCompleteRunnable = null; @@ -1002,6 +1025,35 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } RaceConditionTracker.onEvent(ON_START_EVT, ENTER); super.onStart(); + + String packagename = MyApplication.getInstance().getAppPackageName(); + Log.e("SendcloseApp", "packagename=" + packagename); + if (packagename != null && packagename.length() > 0) { + SendcloseApp(packagename); +// if (!APKUtils.isSystemApp(this, packagename) && !Arrays.asList(ItemClickHandler.packages).contains(packagename)) { +// try { +// AppInformation app = getInfoFromPackageName(packagename); +// if (app != null) { +// long time = app.getUsedTimebyDay() / 1000; +// Log.e("fht", "返回运行时间: " + DateUtils.formatElapsedTime(time)); +// Log.e("fht", "返回运行时间: " + time); +// +//// if (userInfo != null) { +//// HTTPInterface.sendTimeLog(handler, userInfo, app.getLabel(), 2, time - MyApplication.getInstance().getRunTime()); +//// } else { +//// Log.e("fht", "userInfo = null"); +//// } +// } else { +// Log.e("fht", "app = null" + packagename); +// } +// } catch (Exception e) { +// Log.e("fht", e.getMessage()); +// } +// } +// } else { +// Log.e("packagename", "packagename is null"); + } + if (mLauncherCallbacks != null) { mLauncherCallbacks.onStart(); } @@ -1009,6 +1061,57 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, RaceConditionTracker.onEvent(ON_START_EVT, EXIT); } + private static void SendcloseApp(String packageName) { + PackageManager pm = MyApplication.getInstance().getPackageManager(); + PackageInfo appInfo = null; + try { + appInfo = pm.getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (null != appInfo) { + long appVersionCode; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + appVersionCode = appInfo.getLongVersionCode(); + } else { + appVersionCode = appInfo.versionCode; + } + addAppLog appLog = NetWorkManager.getapplogControl(); + String sn = Utils.getSerial(); + appLog.addLog(sn, packageName, appVersionCode, System.currentTimeMillis() / 1000, 2) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(BaseResponse baseResponse) { + int code = baseResponse.code; + if (code == 200) { + Log.e("SendcloseApp", "onNext:" + code + baseResponse.data); + } else { + Log.e("SendcloseApp", "onNext:" + code + baseResponse.msg); + } + } + + @Override + public void onError(Throwable e) { + Log.e("SendcloseApp", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + + } + }); + } + + } + + private void handleDeferredResume() { if (hasBeenResumed() && !mStateManager.getState().disableInteraction) { getUserEventDispatcher().logActionCommand(Action.Command.RESUME, @@ -1122,6 +1225,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * Called when the launcher is ready to use the overlay + * * @param callbacks A set of callbacks provided by Launcher in relation to the overlay */ void setOverlayCallbacks(LauncherOverlayCallbacks callbacks); @@ -1186,7 +1290,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mWorkspace.initParentViews(mDragLayer); mOverviewPanel = findViewById(R.id.overview_panel); mHotseat = findViewById(R.id.hotseat); - mPageIndicatorDots=findViewById(R.id.page_indicator); + mPageIndicatorDots = findViewById(R.id.page_indicator); mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); @@ -1231,8 +1335,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, * Creates a view representing a shortcut inflated from the specified resource. * * @param parent The group the shortcut belongs to. - * @param info The data structure describing the shortcut. - * + * @param info The data structure describing the shortcut. * @return A View inflated from layoutResId. */ public View createShortcut(ViewGroup parent, WorkspaceItemInfo info) { @@ -1250,7 +1353,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, * @param data The intent describing the shortcut. */ private void completeAddShortcut(Intent data, int container, int screenId, int cellX, - int cellY, PendingRequestArgs args) { + int cellY, PendingRequestArgs args) { if (args.getRequestCode() != REQUEST_CREATE_SHORTCUT || args.getPendingIntent().getComponent() == null) { return; @@ -1334,8 +1437,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, * * @param appWidgetId The app widget id */ - @Thunk void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo, - AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) { + @Thunk + void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo, + AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) { if (appWidgetInfo == null) { appWidgetInfo = mAppWidgetManager.getLauncherAppWidgetInfo(appWidgetId); @@ -1428,7 +1532,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return mHotseat; } - public PageIndicatorDots getIndicatorDots(){ + public PageIndicatorDots getIndicatorDots() { return mPageIndicatorDots; } @@ -1456,7 +1560,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return mSharedPrefs; } - public int getOrientation() { return mOldConfig.orientation; } + public int getOrientation() { + return mOldConfig.orientation; + } @Override protected void onNewIntent(Intent intent) { @@ -1616,7 +1722,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override public void startIntentSenderForResult(IntentSender intent, int requestCode, - Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) { + Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) { if (requestCode != -1) { mPendingActivityRequestCode = requestCode; } @@ -1637,7 +1743,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, */ @Override public void startSearch(String initialQuery, boolean selectInitialQuery, - Bundle appSearchData, boolean globalSearch) { + Bundle appSearchData, boolean globalSearch) { if (appSearchData == null) { appSearchData = new Bundle(); appSearchData.putString("source", "launcher-search"); @@ -1670,7 +1776,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } void addAppWidgetFromDropImpl(int appWidgetId, ItemInfo info, AppWidgetHostView boundWidget, - WidgetAddFlowHandler addFlowHandler) { + WidgetAddFlowHandler addFlowHandler) { if (LOGD) { Log.d(TAG, "Adding widget from drop"); } @@ -1678,7 +1784,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } void addAppWidgetImpl(int appWidgetId, ItemInfo info, - AppWidgetHostView boundWidget, WidgetAddFlowHandler addFlowHandler, int delay) { + AppWidgetHostView boundWidget, WidgetAddFlowHandler addFlowHandler, int delay) { if (!addFlowHandler.startConfigActivity(this, appWidgetId, info, REQUEST_CREATE_APPWIDGET)) { // If the configuration flow was not started, add the widget @@ -1695,7 +1801,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } public void addPendingItem(PendingAddItemInfo info, int container, int screenId, - int[] cell, int spanX, int spanY) { + int[] cell, int spanX, int spanY) { info.container = container; info.screenId = screenId; if (cell != null) { @@ -1715,7 +1821,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, break; default: throw new IllegalStateException("Unknown item type: " + info.itemType); - } + } } /** @@ -1771,7 +1877,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } FolderIcon addFolder(CellLayout layout, int container, final int screenId, int cellX, - int cellY) { + int cellY) { final FolderInfo folderInfo = new FolderInfo(); folderInfo.title = getText(R.string.folder_name); @@ -1790,8 +1896,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * Unbinds the view for the specified item, and removes the item and all its children. * - * @param v the view being removed. - * @param itemInfo the {@link ItemInfo} for this view. + * @param v the view being removed. + * @param itemInfo the {@link ItemInfo} for this view. * @param deleteFromDb whether or not to delete this item from the db. */ public boolean removeItem(View v, final ItemInfo itemInfo, boolean deleteFromDb) { @@ -1828,7 +1934,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } - @Override public boolean dispatchKeyEvent(KeyEvent event) { return (event.getKeyCode() == KeyEvent.KEYCODE_HOME) || super.dispatchKeyEvent(event); @@ -1892,7 +1997,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override public int getCurrentState() { - if(mStateManager.getState() == LauncherState.ALL_APPS) { + if (mStateManager.getState() == LauncherState.ALL_APPS) { return StatsLogUtils.LAUNCHER_STATE_ALLAPPS; } else if (mStateManager.getState() == OVERVIEW) { return StatsLogUtils.LAUNCHER_STATE_OVERVIEW; @@ -1919,7 +2024,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } public boolean startActivitySafely(View v, Intent intent, ItemInfo item, - @Nullable String sourceContainer) { + @Nullable String sourceContainer) { if (TestProtocol.sDebugTracing) { android.util.Log.d(TestProtocol.NO_START_TAG, "startActivitySafely outer"); @@ -2020,7 +2125,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * Refreshes the shortcuts shown on the workspace. - * + *

* Implementation of the method from LauncherModel.Callbacks. */ public void startBinding() { @@ -2089,7 +2194,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override public void bindAppsAdded(IntArray newScreens, ArrayList addNotAnimated, - ArrayList addAnimated) { + ArrayList addAnimated) { // Add the new screens if (newScreens != null) { bindAddScreens(newScreens); @@ -2110,7 +2215,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * Bind the items start-end from the list. - * + *

* Implementation of the method from LauncherModel.Callbacks. */ @Override @@ -2157,7 +2262,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, throw new RuntimeException("Invalid Item Type"); } - /* + /* * Remove colliding items. */ if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { @@ -2408,7 +2513,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * Callback saying that there aren't any more items to bind. - * + *

* Implementation of the method from LauncherModel.Callbacks. */ public void finishBindingItems(int pageBoundFirst) { @@ -2449,7 +2554,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * Add the icons for all apps. - * + *

* Implementation of the method from LauncherModel.Callbacks. */ public void bindAllApplications(ArrayList apps) { @@ -2467,7 +2572,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * A package was updated. - * + *

* Implementation of the method from LauncherModel.Callbacks. */ @Override @@ -2500,7 +2605,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, /** * Update the state of a package, typically related to install state. - * + *

* Implementation of the method from LauncherModel.Callbacks. */ @Override @@ -2639,8 +2744,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, if (focusedView instanceof BubbleTextView && focusedView.getTag() instanceof ItemInfo && mAccessibilityDelegate.performAction(focusedView, - (ItemInfo) focusedView.getTag(), - LauncherAccessibilityDelegate.DEEP_SHORTCUTS)) { + (ItemInfo) focusedView.getTag(), + LauncherAccessibilityDelegate.DEEP_SHORTCUTS)) { PopupContainerWithArrow.getOpen(this).requestFocus(); return true; } diff --git a/src/com/android/uiuios/MyApplication.java b/src/com/android/uiuios/MyApplication.java new file mode 100644 index 0000000..9fb1a06 --- /dev/null +++ b/src/com/android/uiuios/MyApplication.java @@ -0,0 +1,47 @@ +package com.android.uiuios; + +import android.app.Application; +import android.content.Context; + +public class MyApplication extends Application { + private static MyApplication app; + + public static MyApplication getInstance() { + return app; + } + + @Override + public void onCreate() { + super.onCreate(); + app = this; + + } + + private String appPackageName; + private long runTime = 0; + private long onClickTime = 0; + + public void setOnClickTime(long time) { + this.onClickTime = time; + } + + public long getOnClickTime() { + return onClickTime; + } + + public void setAppPackageName(String name) { + this.appPackageName = name; + } + + public String getAppPackageName() { + return appPackageName; + } + + public void setTime(long time) { + this.runTime = time; + } + + public long getRunTime() { + return runTime; + } +} diff --git a/src/com/android/uiuios/Statistics/AppInformation.java b/src/com/android/uiuios/Statistics/AppInformation.java new file mode 100644 index 0000000..4ee8395 --- /dev/null +++ b/src/com/android/uiuios/Statistics/AppInformation.java @@ -0,0 +1,127 @@ +package com.android.uiuios.Statistics; + +import android.app.usage.UsageStats; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; +import android.os.SystemClock; + + +public class AppInformation { + private UsageStats usageStats; + private String packageName; + private String label; + private Drawable Icon; + private long UsedTimebyDay; //milliseconds + private Context context; + private int times; + + + public AppInformation(UsageStats usageStats, Context context) { + this.usageStats = usageStats; + this.context = context; + + try { + GenerateInfo(); + } catch (PackageManager.NameNotFoundException | IllegalAccessException | NoSuchFieldException e) { + e.printStackTrace(); + } + } + + private void GenerateInfo() throws PackageManager.NameNotFoundException, NoSuchFieldException, IllegalAccessException { + PackageManager packageManager = context.getPackageManager(); + this.packageName = usageStats.getPackageName(); + if (this.packageName != null && !this.packageName.equals("")) { + ApplicationInfo applicationInfo = packageManager.getApplicationInfo(this.packageName, 0); + this.label = (String) packageManager.getApplicationLabel(applicationInfo); + this.UsedTimebyDay = usageStats.getTotalTimeInForeground(); + this.times = (Integer) usageStats.getClass().getDeclaredField("mLaunchCount").get(usageStats); + + if (this.UsedTimebyDay > 0) { + this.Icon = applicationInfo.loadIcon(packageManager); + } + } + } + + public UsageStats getUsageStats() { + return usageStats; + } + + public int getTimes() { + return times; + } + + public void setTimes(int times) { + this.times = times; + } + + public void setUsedTimebyDay(long usedTimebyDay) { + this.UsedTimebyDay = usedTimebyDay; + } + + public Drawable getIcon() { + return Icon; + } + + public long getUsedTimebyDay() { + return UsedTimebyDay; + } + + public String getLabel() { + return label; + } + + public String getPackageName() { + return packageName; + } + + private long timeStampMoveToForeground = -1; + + private long timeStampMoveToBackGround = -1; + + + public void setTimeStampMoveToForeground(long timeStampMoveToForeground) { +// if (timeStampMoveToForeground > bootTime()){ +// timesPlusPlus(); +// } + this.timeStampMoveToForeground = timeStampMoveToForeground; + } + + public void timesPlusPlus(){ + times++; + } + + public void setTimeStampMoveToBackGround(long timeStampMoveToBackGround) { + this.timeStampMoveToBackGround = timeStampMoveToBackGround; + } + + public long getTimeStampMoveToBackGround() { + return timeStampMoveToBackGround; + } + + public long getTimeStampMoveToForeground() { + return timeStampMoveToForeground; + } + + public void calculateRunningTime() { + + if (timeStampMoveToForeground < 0 || timeStampMoveToBackGround < 0) { + return; + } + + if (timeStampMoveToBackGround > timeStampMoveToForeground) { + UsedTimebyDay += (timeStampMoveToBackGround - timeStampMoveToForeground); + timeStampMoveToForeground = -1; + timeStampMoveToBackGround = -1; + } + + } + + + // 返回开机时间,单位微妙 + public static long bootTime() { + return System.currentTimeMillis() - SystemClock.elapsedRealtime(); + } + +} diff --git a/src/com/android/uiuios/Statistics/StatisticsInfo.java b/src/com/android/uiuios/Statistics/StatisticsInfo.java new file mode 100644 index 0000000..afbff76 --- /dev/null +++ b/src/com/android/uiuios/Statistics/StatisticsInfo.java @@ -0,0 +1,274 @@ +package com.android.uiuios.Statistics; + +import android.annotation.TargetApi; +import android.app.usage.UsageEvents; +import android.app.usage.UsageStats; +import android.app.usage.UsageStatsManager; +import android.content.Context; +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; + +import static com.android.uiuios.Statistics.AppInformation.bootTime; + + +public class StatisticsInfo { + + final public static int DAY = 0; + final public static int WEEK = 1; + final public static int MONTH = 2; + final public static int YEAR = 3; + + private ArrayList ShowList; + private ArrayList AppInfoList; + private List result; + private long totalTime; + private int totalTimes; + private int style; + + public StatisticsInfo(Context context) { + try { + this.style = 0; + setUsageStatsList(context); + setShowList(); + + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } + } + + + //将次数和时间为0的应用信息过滤掉 + private void setShowList() { + this.ShowList = new ArrayList<>(); + + totalTime = 0; + + for (int i = 0; i < AppInfoList.size(); i++) { + if (AppInfoList.get(i).getUsedTimebyDay() > 0) { //&& AppInfoList.get(i).getTimes() > 0) { + + this.ShowList.add(AppInfoList.get(i)); + totalTime += AppInfoList.get(i).getUsedTimebyDay(); + totalTimes += AppInfoList.get(i).getTimes(); + } + } + + //将显示列表中的应用按显示顺序排序 + for (int i = 0; i < this.ShowList.size() - 1; i++) { + for (int j = 0; j < this.ShowList.size() - i - 1; j++) { + if (this.ShowList.get(j).getUsedTimebyDay() < this.ShowList.get(j + 1).getUsedTimebyDay()) { + AppInformation temp = this.ShowList.get(j); + this.ShowList.set(j, this.ShowList.get(j + 1)); + this.ShowList.set(j + 1, temp); + } + } + } + } + + + //统计当天的应用使用时间 + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + private void setUsageStatsList(Context context) throws NoSuchFieldException { + UsageStatsManager m = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); + this.AppInfoList = new ArrayList<>(); + if (m != null) { + Calendar calendar = Calendar.getInstance(); + long now = calendar.getTimeInMillis(); + long begintime = getBeginTime(); + if (style == DAY) { + this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_BEST, begintime, now); + AppInfoList = getAccurateDailyStatsList(context, result, m, begintime, now); + } else { + if (style == WEEK) + this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_WEEKLY, begintime, now); + else if (style == MONTH) + this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_MONTHLY, begintime, now); + else if (style == YEAR) + this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_YEARLY, begintime, now); + else { + this.result = m.queryUsageStats(UsageStatsManager.INTERVAL_BEST, begintime, now); + } + + List Mergeresult = MergeList(this.result); + for (UsageStats usageStats : Mergeresult) { + this.AppInfoList.add(new AppInformation(usageStats, context)); + } + calculateLaunchTimesAfterBootOn(context, AppInfoList); + } + } + } + + /** + * 根据UsageEvents来对当天的操作次数和开机后运行时间来进行精确计算 + */ + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private ArrayList getAccurateDailyStatsList(Context context, List result, UsageStatsManager m, long begintime, long now) { + //针对每个packageName建立一个 使用信息 + HashMap mapData = new HashMap<>(); + //得到包名 + for (UsageStats stats : result) { + if (stats.getLastTimeUsed() > begintime && stats.getTotalTimeInForeground() > 0) { + if (mapData.get(stats.getPackageName()) == null) { + AppInformation information = new AppInformation(stats, context); + //重置总运行时间 开机操作次数 + information.setTimes(0); + information.setUsedTimebyDay(0); + mapData.put(stats.getPackageName(), information); + } + } + } + + //这个是相对比较精确的 + long bootTime = bootTime(); + UsageEvents events = m.queryEvents(bootTime, now); + + UsageEvents.Event e = new UsageEvents.Event(); + while (events.hasNextEvent()) { + events.getNextEvent(e); + String packageName = e.getPackageName(); + + AppInformation information = mapData.get(packageName); + if (information == null) { + continue; + } + + //这里在同时计算开机后的操作次数和运行时间,所以如果获取到的时间戳是昨天的话就得过滤掉 continue + + if (e.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) { + information.timesPlusPlus(); + if (e.getTimeStamp() < begintime){ + continue; + } + information.setTimeStampMoveToForeground(e.getTimeStamp()); + } else if (e.getEventType() == UsageEvents.Event.MOVE_TO_BACKGROUND) { + if (e.getTimeStamp() < begintime){ + continue; + } + information.setTimeStampMoveToBackGround(e.getTimeStamp()); + //当前应用是在昨天进入的前台,0点后转入了后台,所以会先得到MOVE_TO_BACKGROUND 的timeStamp + if (information.getTimeStampMoveToForeground() < 0) { + //从今天开始计算即可 + information.setTimeStampMoveToForeground(begintime); + } + } + information.calculateRunningTime(); + } + + //再计算一次当前应用的运行时间,因为当前应用,最后得不到MOVE_TO_BACKGROUND 的timeStamp + AppInformation information = mapData.get(context.getPackageName()); + information.setTimeStampMoveToBackGround(now); + information.calculateRunningTime(); + + return new ArrayList<>(mapData.values()); + } + + /** + * 根据UsageEvents 精确计算APP开机的启动(activity打开的)次数 + */ + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private void calculateLaunchTimesAfterBootOn(Context context, List AppInfoList) { + + UsageStatsManager m = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE); + if (m == null || AppInfoList == null || AppInfoList.size() < 1) { + return; + } + //针对每个packageName建立一个 使用信息 + HashMap mapData = new HashMap<>(); + + UsageEvents events = m.queryEvents(bootTime(), System.currentTimeMillis()); + for (AppInformation information : AppInfoList) { + mapData.put(information.getPackageName(), information); + information.setTimes(0); + } + + UsageEvents.Event e = new UsageEvents.Event(); + while (events.hasNextEvent()) { + events.getNextEvent(e); + String packageName = e.getPackageName(); + AppInformation information = mapData.get(packageName); + if (information == null) { + continue; + } + + if (e.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) { + information.timesPlusPlus(); + } + } + } + + private long getBeginTime() { + Calendar calendar = Calendar.getInstance(); + long begintime; + if (style == WEEK) { + //int weekDay = calendar.get(Calendar.DAY_OF_WEEK); + calendar.add(Calendar.DATE, -7); + begintime = calendar.getTimeInMillis(); + } else if (style == MONTH) { + //int mounthDay = calendar.get(Calendar.DAY_OF_MONTH); + calendar.add(Calendar.DATE, -30); + begintime = calendar.getTimeInMillis(); + } else if (style == YEAR) { + calendar.add(Calendar.YEAR, -1); + begintime = calendar.getTimeInMillis(); + } else { + //剩下的输入均显示当天的数据 + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int minute = calendar.get(Calendar.MINUTE); + int second = calendar.get(Calendar.SECOND); + + calendar.add(Calendar.SECOND, -1 * second); + calendar.add(Calendar.MINUTE, -1 * minute); + calendar.add(Calendar.HOUR, -1 * hour); + begintime = calendar.getTimeInMillis(); + + } + return begintime; + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private List MergeList(List result) { + List Mergeresult = new ArrayList<>(); + long begintime; + begintime = getBeginTime(); + for (int i = 0; i < result.size(); i++) { + if (result.get(i).getLastTimeUsed() > begintime) { + int num = FoundUsageStats(Mergeresult, result.get(i)); + if (num >= 0) { + UsageStats u = Mergeresult.get(num); + u.add(result.get(i)); + Mergeresult.set(num, u); + } else Mergeresult.add(result.get(i)); + } + } + return Mergeresult; + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private int FoundUsageStats(List Mergeresult, UsageStats usageStats) { + for (int i = 0; i < Mergeresult.size(); i++) { + if (Mergeresult.get(i).getPackageName().equals(usageStats.getPackageName())) { + return i; + } + } + return -1; + } + + + public long getTotalTime() { + return totalTime; + } + + public int getTotalTimes() { + return totalTimes; + } + + public ArrayList getShowList() { + return ShowList; + } +} + diff --git a/src/com/android/uiuios/TTUtils/APKUtils.java b/src/com/android/uiuios/TTUtils/APKUtils.java new file mode 100644 index 0000000..585db06 --- /dev/null +++ b/src/com/android/uiuios/TTUtils/APKUtils.java @@ -0,0 +1,31 @@ +package com.android.uiuios.TTUtils; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.util.Log; + +public class APKUtils { + //判断是否为系统应用 + public static boolean isSystemApp(Context context, String pkgName) { + boolean isSystemApp = false; + PackageInfo pi = null; + try { + PackageManager pm = context.getPackageManager(); + pi = pm.getPackageInfo(pkgName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + Log.e("isSystemApp", e.getMessage(), e); + + } + + // 是系统中已安装的应用 + if (pi != null) { + boolean isSysApp = (pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1; + boolean isSysUpd = (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1; + isSystemApp = isSysApp || isSysUpd; + } + return isSystemApp; + } +} diff --git a/src/com/android/uiuios/TTUtils/Utils.java b/src/com/android/uiuios/TTUtils/Utils.java new file mode 100644 index 0000000..2c98359 --- /dev/null +++ b/src/com/android/uiuios/TTUtils/Utils.java @@ -0,0 +1,34 @@ +package com.android.uiuios.TTUtils; + +import android.annotation.SuppressLint; +import android.os.Build; +import android.util.Log; + +import java.lang.reflect.Method; + +public class Utils { + /** + * 获取设备序列号 + * + * @return + */ + @SuppressLint({"MissingPermission", "NewApi"}) + public static String getSerial() { + String serial = "unknow"; + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+ + serial = Build.getSerial(); + } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+ + serial = Build.SERIAL; + } else {//8.0- + Class c = Class.forName("android.os.SystemProperties"); + Method get = c.getMethod("get", String.class); + serial = (String) get.invoke(c, "ro.serialno"); + } + } catch (Exception e) { + e.printStackTrace(); + Log.e("e", "读取设备序列号异常:" + e.toString()); + } + return serial; + } +} diff --git a/src/com/android/uiuios/network/BaseResponse.java b/src/com/android/uiuios/network/BaseResponse.java new file mode 100644 index 0000000..ec7ee97 --- /dev/null +++ b/src/com/android/uiuios/network/BaseResponse.java @@ -0,0 +1,25 @@ +package com.android.uiuios.network; + +import androidx.annotation.NonNull; + +import java.io.Serializable; + + +public class BaseResponse implements Serializable { + + private static final long serialVersionUID = 5468533687801294972L; + + public int code; + public String msg; + public T data; + + @NonNull + @Override + public String toString() { + return "{\n" +// + "\tcode=" + code + "\n" +// + "\tmsg='" + msg + "\'\n" +// + "\tdata=" + data + "\n" +// + '}'; + } +} \ No newline at end of file diff --git a/src/com/android/uiuios/network/NetWorkManager.java b/src/com/android/uiuios/network/NetWorkManager.java new file mode 100644 index 0000000..449cf04 --- /dev/null +++ b/src/com/android/uiuios/network/NetWorkManager.java @@ -0,0 +1,55 @@ +package com.android.uiuios.network; + +import android.os.Environment; + +import com.android.uiuios.network.api.addAppLog; + +import java.io.File; +import java.util.concurrent.TimeUnit; + +import okhttp3.Cache; +import okhttp3.OkHttpClient; +import retrofit2.CallAdapter; +import retrofit2.Converter; +import retrofit2.Retrofit; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; +import retrofit2.converter.gson.GsonConverterFactory; + +public class NetWorkManager { + + private static final String ROOT_URL = URLPath.ROOT_URL; + + private static final long cacheSize = 1024 * 1024 * 20;// 缓存文件最大限制大小20M + private static String cacheDirectory = Environment.getExternalStorageDirectory() + "/okttpcaches"; // 设置缓存文件路径 + private static Cache cache = new Cache(new File(cacheDirectory), cacheSize); // + private static final OkHttpClient client; + + static { + //如果无法生存缓存文件目录,检测权限使用已经加上,检测手机是否把文件读写权限禁止了 + OkHttpClient.Builder builder = new OkHttpClient.Builder(); + builder.connectTimeout(8, TimeUnit.SECONDS); // 设置连接超时时间 + builder.writeTimeout(8, TimeUnit.SECONDS);// 设置写入超时时间 + builder.readTimeout(8, TimeUnit.SECONDS);// 设置读取数据超时时间 + builder.retryOnConnectionFailure(true);// 设置进行连接失败重试 + builder.cache(cache);// 设置缓存 + client = builder.build(); + } + + private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create(); + private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create(); + + private static addAppLog applogControl; + + public static addAppLog getapplogControl() { + if (null == applogControl) { + Retrofit retrofit = new Retrofit.Builder() + .client(client) + .baseUrl(ROOT_URL) + .addConverterFactory(gsonConverterFactory) + .addCallAdapterFactory(rxJavaCallAdapterFactory) + .build(); + applogControl = retrofit.create(addAppLog.class); + } + return applogControl; + } +} diff --git a/src/com/android/uiuios/network/URLPath.java b/src/com/android/uiuios/network/URLPath.java new file mode 100644 index 0000000..3ecfb3c --- /dev/null +++ b/src/com/android/uiuios/network/URLPath.java @@ -0,0 +1,6 @@ +package com.android.uiuios.network; + +public class URLPath { + public static final String ROOT_URL = "http://homework.uiuios.com/android/app/"; + public static final String APP_LOG = ROOT_URL+"addAppLog"; +} diff --git a/src/com/android/uiuios/network/api/addAppLog.java b/src/com/android/uiuios/network/api/addAppLog.java new file mode 100644 index 0000000..ade1f70 --- /dev/null +++ b/src/com/android/uiuios/network/api/addAppLog.java @@ -0,0 +1,21 @@ +package com.android.uiuios.network.api; + +import com.android.uiuios.network.BaseResponse; +import com.android.uiuios.network.URLPath; + +import io.reactivex.Observable; +import retrofit2.http.Field; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.POST; + +public interface addAppLog { + @FormUrlEncoded + @POST(URLPath.APP_LOG) + Observable addLog( + @Field("sn") String sn, + @Field("packageName") String packageName, + @Field("versionCode") long versionCode, + @Field("createTime") long createTime, + @Field("type") long type + ); +} diff --git a/src/com/android/uiuios/touch/ItemClickHandler.java b/src/com/android/uiuios/touch/ItemClickHandler.java index bf92b62..6d53368 100644 --- a/src/com/android/uiuios/touch/ItemClickHandler.java +++ b/src/com/android/uiuios/touch/ItemClickHandler.java @@ -25,9 +25,15 @@ import static com.android.uiuios.Launcher.REQUEST_RECONFIGURE_APPWIDGET; import static com.android.uiuios.model.AppLaunchTracker.CONTAINER_ALL_APPS; import android.app.AlertDialog; +import android.content.Context; import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Process; import android.text.TextUtils; +import android.text.format.DateUtils; +import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; @@ -41,18 +47,34 @@ import com.android.uiuios.ItemInfo; import com.android.uiuios.Launcher; import com.android.uiuios.LauncherAppWidgetInfo; import com.android.uiuios.LauncherAppWidgetProviderInfo; +import com.android.uiuios.MyApplication; import com.android.uiuios.PromiseAppInfo; import com.android.uiuios.R; +import com.android.uiuios.Statistics.AppInformation; +import com.android.uiuios.Statistics.StatisticsInfo; +import com.android.uiuios.TTUtils.APKUtils; +import com.android.uiuios.TTUtils.Utils; import com.android.uiuios.WorkspaceItemInfo; import com.android.uiuios.compat.AppWidgetManagerCompat; import com.android.uiuios.folder.Folder; import com.android.uiuios.folder.FolderIcon; +import com.android.uiuios.network.BaseResponse; +import com.android.uiuios.network.NetWorkManager; +import com.android.uiuios.network.api.addAppLog; import com.android.uiuios.testing.TestProtocol; import com.android.uiuios.util.PackageManagerHelper; import com.android.uiuios.views.FloatingIconView; import com.android.uiuios.widget.PendingAppWidgetHostView; import com.android.uiuios.widget.WidgetAddFlowHandler; +import java.util.Arrays; +import java.util.List; + +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; + /** * Class for handling clicks on workspace and all-apps items */ @@ -94,6 +116,31 @@ public class ItemClickHandler { Object tag = v.getTag(); if (tag instanceof WorkspaceItemInfo) { onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher, sourceContainer); + String packageName = ((WorkspaceItemInfo) tag).getTargetComponent().getPackageName(); + Context context = MyApplication.getInstance().getApplicationContext(); + AppInformation app = null; + try { + app = getInfoFromPackageName(packageName); + } catch (Exception e) { + Log.e("onClick", e.getMessage()); + } + if (app != null) { + Log.e("fht", "运行时间: " + DateUtils.formatElapsedTime(app.getUsedTimebyDay() / 1000)); + Log.e("fht", "运行时间: " + app.getUsedTimebyDay() / 1000); + MyApplication.getInstance().setTime(app.getUsedTimebyDay() / 1000); + + } else { + Log.e("fht", "首次运行:" + "包名:" + packageName); + MyApplication.getInstance().setTime(0); + + } + if (!APKUtils.isSystemApp(context, packageName) && !Arrays.asList(packages).contains(packageName)) { +// HTTPInterface.sendTimeLog(handler, userInfo, ((ShortcutInfo) tag).title.toString(), 1, 0); + SendOpenApp(packageName); + } + + MyApplication.getInstance().setAppPackageName(packageName); + MyApplication.getInstance().setOnClickTime(System.currentTimeMillis()); } else if (tag instanceof FolderInfo) { if (v instanceof FolderIcon) { onClickFolderIcon(v); @@ -104,7 +151,7 @@ public class ItemClickHandler { "onClick 4"); } startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher, - sourceContainer == null ? CONTAINER_ALL_APPS: sourceContainer); + sourceContainer == null ? CONTAINER_ALL_APPS : sourceContainer); } else if (tag instanceof LauncherAppWidgetInfo) { if (v instanceof PendingAppWidgetHostView) { onClickPendingWidget((PendingAppWidgetHostView) v, launcher); @@ -112,6 +159,82 @@ public class ItemClickHandler { } } + + public static String[] packages = { + "com.appstore.uiui", + "com.uiuios.updatetools", + "com.info.sn", + "com.android.uiuios", + "com.easyold.uiuios", + "com.jiaoguanyi.store" + + }; + + public static AppInformation getInfoFromPackageName(String packageName) { + List list; + AppInformation app = null; + StatisticsInfo statisticsInfo = new StatisticsInfo(MyApplication.getInstance().getApplicationContext()); + list = statisticsInfo.getShowList(); + for (AppInformation appInformation : list) { + String name = appInformation.getPackageName(); + if (appInformation.getPackageName().equals(packageName)) { + return appInformation; + } + } + return app; + } + + private static void SendOpenApp(String packageName) { + PackageManager pm = MyApplication.getInstance().getPackageManager(); + PackageInfo appInfo = null; + try { + appInfo = pm.getPackageInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + if (null != appInfo) { + long appVersionCode; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + appVersionCode = appInfo.getLongVersionCode(); + } else { + appVersionCode = appInfo.versionCode; + } + addAppLog appLog = NetWorkManager.getapplogControl(); + String sn = Utils.getSerial(); + appLog.addLog(sn, packageName, appVersionCode, System.currentTimeMillis()/1000, 1) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + + } + + @Override + public void onNext(BaseResponse baseResponse) { + int code = baseResponse.code; + if (code == 200) { + Log.e("SendOpenApp", "onNext:" + code + baseResponse.data); + } else { + Log.e("SendOpenApp", "onNext:" + code + baseResponse.msg); + } + } + + @Override + public void onError(Throwable e) { + Log.e("SendOpenApp", "onError: " + e.getMessage()); + } + + @Override + public void onComplete() { + + } + }); + } + + } + + /** * Event handler for a folder icon click. * @@ -160,7 +283,7 @@ public class ItemClickHandler { } private static void onClickPendingAppItem(View v, Launcher launcher, String packageName, - boolean downloadStarted) { + boolean downloadStarted) { if (downloadStarted) { // If the download has started, simply direct to the market app. startMarketIntentForPackage(v, launcher, packageName); @@ -189,7 +312,7 @@ public class ItemClickHandler { * @param v The view that was clicked. Must be a tagged with a {@link WorkspaceItemInfo}. */ public static void onClickAppShortcut(View v, WorkspaceItemInfo shortcut, Launcher launcher, - @Nullable String sourceContainer) { + @Nullable String sourceContainer) { if (shortcut.isDisabled()) { final int disabledFlags = shortcut.runtimeStatusFlags & WorkspaceItemInfo.FLAG_DISABLED_MASK; @@ -233,7 +356,7 @@ public class ItemClickHandler { } private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher, - @Nullable String sourceContainer) { + @Nullable String sourceContainer) { if (TestProtocol.sDebugTracing) { android.util.Log.d(TestProtocol.NO_START_TAG, "startAppShortcutOrInfoActivity");