Revert "Add Test cases for app shortcut, managedapps"
[profile/tv/apps/dotnet/home.git] / TVApps / TVApps / ViewModels / AppsHolder.cs
old mode 100644 (file)
new mode 100755 (executable)
index cc06d74..68acc45
@@ -18,22 +18,57 @@ using LibTVRefCommonPortable.DataModels;
 using LibTVRefCommonPortable.Utils;
 using System.Collections.Generic;
 using System.Linq;
+using System.Threading;
 using System.Threading.Tasks;
 using Xamarin.Forms;
 
 namespace TVApps.ViewModels
 {
+    /// <summary>
+    /// A class contains installed, pinned application list.
+    /// The MainPageViewModel changes state of application item by AppsHolder's API
+    /// </summary>
     internal class AppsHolder
     {
+        /// <summary>
+        /// The interface for interaction with view model
+        /// </summary>
         IAppsViewModel ViewModel;
 
+        /// <summary>
+        /// A flag indicates how to sort InstalledApps
+        /// </summary>
+        /// <see cref="SortingOptions"/>
         public SortingOptions SortingOption;
 
+        /// <summary>
+        /// A list contains AppShortcutInfo about installed applications
+        /// </summary>
+        /// <see cref="AppShortcutInfo"/>
         public List<AppShortcutInfo> InstalledApps;
 
+        /// <summary>
+        /// A dictionary contains ID of pinned applications
+        /// </summary>
         public Dictionary<string, string> PinnedApps;
 
+        /// <summary>
+        /// A name of pinned application
+        /// </summary>
+        public string PinnedAppName;
 
+        /// <summary>
+        /// A name of unpinned application
+        /// </summary>
+        public string UnpinnedAppName;
+
+        public bool IsSelectedExceeds;
+
+        /// <summary>
+        /// A constructor
+        /// Initializes installed and pinned app list
+        /// </summary>
+        /// <param name="ViewModel">The instance of MainPageViewModel</param>
         public AppsHolder(IAppsViewModel ViewModel)
         {
             this.ViewModel = ViewModel;
@@ -48,15 +83,19 @@ namespace TVApps.ViewModels
 
             App.SetAppUninstalledListener((s, e) =>
             {
-                // TODO : find apps by package id
-                // TODO : remove all apps from pinned app list
-
                 SetApps();
             });
+            SynchronizationContext.Current.Post((o) =>
+            {
+                SetApps();
+            }, "");
 
-            SetApps();
         }
 
+        /// <summary>
+        /// A method gets installed, pinned application information from AppShortcutController.
+        /// And adds state descriptions about pin, delete, long press state
+        /// </summary>
         private async void SetApps()
         {
             var pinnedAppsGettingTask = TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs();
@@ -65,6 +104,8 @@ namespace TVApps.ViewModels
             await Task.WhenAll(pinnedAppsGettingTask, installedAppsGettingTask);
 
             PinnedApps = pinnedAppsGettingTask.Result;
+            ViewModel.OnPropertyChanged("SumOfCheckedApp");
+
             var installedApps = installedAppsGettingTask.Result;
 
             foreach (AppShortcutInfo item in installedApps)
@@ -75,55 +116,61 @@ namespace TVApps.ViewModels
                     continue;
                 }
 
-                item.SetPinned(PinnedApps.ContainsKey(item.AppID));
+                item.IsPinned = PinnedApps.ContainsKey(item.AppID);
+
+                CommandAction pinAction = new CommandAction()
+                {
+                    NextStateDescription = AppsStatus.Pin.ToString().ToLower(),
+                    CommandParameter = item.AppID
+                };
+                pinAction.Command += new System.EventHandler<string>((s, arg) =>
+                {
+                    PinToggle(arg);
+                });
 
                 var pinStateDescription = new StateDescription()
                 {
                     Label = item.CurrentStateDescription.Label,
                     IconPath = item.CurrentStateDescription.IconPath,
-                    Action = new CommandAction()
-                    {
-                        NextStateDescription = AppsStatus.Pin.ToString().ToLower(),
-                        Command = new Command<string>((key) =>
-                        {
-                            PinToggle(key);
-                        }),
-                        CommandParameter = item.AppID
-                    }
+                    Action = pinAction,
                 };
 
                 item.StateDescriptions.Add(AppsStatus.Pin.ToString().ToLower(), pinStateDescription);
 
+                CommandAction checkDeleteAction = new CommandAction()
+                {
+                    NextStateDescription = AppsStatus.Delete.ToString().ToLower(),
+                    CommandParameter = item.AppID
+                };
+                checkDeleteAction.Command += new System.EventHandler<string>((s, arg) =>
+                {
+                    CheckDeleteApp(arg);
+                });
+
                 var deleteStateDescription = new StateDescription()
                 {
                     Label = item.CurrentStateDescription.Label,
                     IconPath = item.CurrentStateDescription.IconPath,
-                    Action = new CommandAction()
-                    {
-                        NextStateDescription = AppsStatus.Delete.ToString().ToLower(),
-                        Command = new Command<string>((key) =>
-                        {
-                            DeleteApp(key);
-                        }),
-                        CommandParameter = item.AppID
-                    }
+                    Action = checkDeleteAction,
                 };
 
                 item.StateDescriptions.Add(AppsStatus.Delete.ToString().ToLower(), deleteStateDescription);
 
+                CommandAction longPressAction = new CommandAction()
+                {
+                    NextStateDescription = AppsStatus.LongPress.ToString().ToLower(),
+                    CommandParameter = item.AppID
+                };
+                pinAction.Command += new System.EventHandler<string>((s, arg) =>
+                {
+                    LongPressApp(arg);
+                });
+
                 var longPressStateDescription = new StateDescription()
                 {
                     Label = item.CurrentStateDescription.Label,
                     IconPath = item.CurrentStateDescription.IconPath,
-                    Action = new CommandAction()
-                    {
-                        NextStateDescription = AppsStatus.LongPress.ToString().ToLower(),
-                        Command = new Command<string>((key) =>
-                        {
-                            LongPressApp(key);
-                        }),
-                        CommandParameter = item.AppID
-                    }
+                    Action = longPressAction,
                 };
                 item.StateDescriptions.Add(AppsStatus.LongPress.ToString().ToLower(), longPressStateDescription);
             }
@@ -133,43 +180,166 @@ namespace TVApps.ViewModels
             UpdateStateDescription(ViewModel.CurrentStatus);
         }
 
-        private void PinToggle(string key)
+        /// <summary>
+        /// A method changes pin state of AppShortcutInfo
+        /// And adds or removes application ID in PinnedApps
+        /// </summary>
+        /// <param name="appID">The ID of application for changing pin state</param>
+        private void PinToggle(string appID)
         {
-            if (PinnedApps.ContainsKey(key))
+            AppShortcutInfo selectedApp = InstalledApps.FirstOrDefault(a => a.AppID == appID);
+            if (selectedApp == null)
             {
-                DebuggingUtils.Dbg("UnPin!");
-                InstalledApps.FirstOrDefault(a => a.AppID == key).SetChecked(false);
-                InstalledApps.FirstOrDefault(a => a.AppID == key).SetPinned(false);
-                PinnedApps.Remove(key);
+                DebuggingUtils.Err("Failed to Pin!!!, Nothing selected, AppID = " + appID);
+                return;
+            }
+
+            if (PinnedApps.ContainsKey(appID))
+            {
+                DebuggingUtils.Dbg("UnPin! : " + selectedApp);
+                selectedApp.IsChecked = false;
+                selectedApp.IsPinned = false;
+                PinnedApps.Remove(appID);
+                UnpinnedAppName = selectedApp.CurrentStateDescription.Label;
+                ViewModel.OnPropertyChanged("UnpinnedAppName");
             }
             else
             {
-                DebuggingUtils.Dbg("Pin!");
-                InstalledApps.FirstOrDefault(a => a.AppID == key).SetChecked(true);
-                InstalledApps.FirstOrDefault(a => a.AppID == key).SetPinned(true);
-                PinnedApps.Add(key, key);
+                if (PinnedApps.Count >= 10)
+                {
+                    IsSelectedExceeds = true;
+                    ViewModel.OnPropertyChanged("IsSelectedExceeds");
+                    return;
+                }
+
+                DebuggingUtils.Dbg("Pin! : " + selectedApp);
+                selectedApp.IsChecked = true;
+                selectedApp.IsPinned = true;
+                PinnedApps.Add(appID, appID);
+                PinnedAppName = selectedApp.CurrentStateDescription.Label;
+                ViewModel.OnPropertyChanged("PinnedAppName");
+            }
+
+            UpdatePinnedApps();
+            ViewModel.OnPropertyChanged("SumOfCheckedApp");
+        }
+
+        /// <summary>
+        /// A method changes pin state of AppShortcutInfo by the Option Menu Pin/Unpin button
+        /// And adds or removes application ID in PinnedApps
+        /// </summary>
+        /// <param name="appID">The ID of application for changing pin state</param>
+        public void OptionMenuPinToggle(string appID)
+        {
+            AppShortcutInfo SelectedApp = InstalledApps.FirstOrDefault(a => a.AppID.Equals(appID));
+            if (SelectedApp == null)
+            {
+                DebuggingUtils.Err("Failed to get selected app : " + appID);
+                return;
+            }
+
+            if (PinnedApps.ContainsKey(appID))
+            {
+                DebuggingUtils.Dbg("Unpin : " + appID);
+                SelectedApp.IsPinned = false;
+                PinnedApps.Remove(appID);
+            }
+            else
+            {
+                DebuggingUtils.Dbg("Pin : " + appID);
+                SelectedApp.IsPinned = true;
+                PinnedApps.Add(appID, appID);
+            }
+
+            ViewModel.OnPropertyChanged("SumOfCheckedApp");
+
+            this.UpdatePinnedApps();
+            ViewModel.ChangeCurrentStatus(AppsStatus.Default);
+        }
+
+        /// <summary>
+        /// A method for changing status of applications to Default
+        /// </summary>
+        public void ChangeToDefaultStatus()
+        {
+            ViewModel.ChangeCurrentStatus(AppsStatus.Default);
+        }
+
+        /// <summary>
+        /// Removes the pinned app by app ID
+        /// </summary>
+        /// <param name="removableAppsList">The apps list to remove at the pinned app list</param>
+        public void RemovePinnedApp(List<string> removableAppsList)
+        {
+            foreach (string app in removableAppsList)
+            {
+                if (PinnedApps.ContainsKey(app))
+                {
+                    DebuggingUtils.Dbg("UnPin! : " + app);
+
+                    PinnedApps.Remove(app);
+                }
+            }
+
+            UpdatePinnedApps();
+        }
+
+        /// <summary>
+        /// A method for checking the application is removable
+        /// If the application is removable, show Delete Popup
+        /// </summary>
+        /// <param name="appID">The ID of application for checking</param>
+        public void CheckDeleteApp(string appID)
+        {
+            DebuggingUtils.Dbg("check that the app( " + appID + ") can be deleted");
+
+            if (!ApplicationManagerUtils.Instance.GetAppInfoRemovable(appID))
+            {
+                DebuggingUtils.Dbg("This app is not removable : " + appID);
+                return;
+            }
+
+            string appLabel = null;
+            if (ApplicationManagerUtils.Instance.GetInstalledApplication(appID).TryGetValue("Label", out appLabel))
+            {
+                ViewModel.ShowDeletePopup(appLabel);
             }
         }
 
-        private void DeleteApp(string AppID)
+        /// <summary>
+        /// A method sends application delete request
+        /// If application is pinned, removes in PinnedApps
+        /// </summary>
+        /// <param name="appID">The ID of application for deleting</param>
+        public void DeleteApp(string appID)
         {
-            DebuggingUtils.Dbg("Delete, " + AppID);
+            // if the app to be deleted is pinned, remove the app in the pinned apps list
+            string pkgID = PackageManagerUtils.GetPackageIDByAppID(appID);
+            if (pkgID == null)
+            {
+                DebuggingUtils.Err("Failed to get the package ID by app ID(" + appID + ")");
+
+                return;
+            }
 
-            // TODO : popup
+            List<string> appsList = PackageManagerUtils.GetApplicationsByPkgID(pkgID);
+            if (appsList == null || appsList.Count == 0)
+            {
+                DebuggingUtils.Err("Failed to get the apps list by package ID(" + pkgID + ")");
 
-            // TODO : remove all app of removed package!!!
-            RemovePinnedApp(AppID);
+                return;
+            }
 
             ViewModel.ChangeCurrentStatus(AppsStatus.Default);
 
-            if (PackageManagerUtils.UninstallPackageByAppID(AppID) == false)
+            if (PackageManagerUtils.UninstallPackageByAppID(appID) == false)
             {
-                DebuggingUtils.Err("App uninstall is failed!!!, " + AppID);
+                DebuggingUtils.Err("App uninstall is failed!!!, " + appID);
             }
             else
             {
                 var removed = from app in InstalledApps
-                              where app.AppID == AppID
+                              where app.AppID == appID
                               select app;
                 InstalledApps.Remove(removed.First());
                 foreach (var item in InstalledApps)
@@ -177,65 +347,117 @@ namespace TVApps.ViewModels
                     DebuggingUtils.Dbg("- " + item.AppID);
                 }
 
+                RemovePinnedApp(appsList);
                 RefreshApps();
             }
         }
 
+        /// <summary>
+        /// A method changes long press state of AppShortcutInfo
+        /// </summary>
+        /// <param name="AppID">The ID of application for showing option menu</param>
         private void LongPressApp(string AppID)
         {
-            // TODO:
             DebuggingUtils.Dbg(" +++++ long press app : " + AppID);
         }
 
+        /// <summary>
+        /// A method updates state description of applications
+        /// </summary>
+        /// <param name="status">The state name for updating state description</param>
         public void UpdateStateDescription(AppsStatus status)
         {
             string tag = status.ToString().ToLower();
 
+            if (status == AppsStatus.LongPress)
+            {
+                AppShortcutInfo focuesedApp = InstalledApps.Find(a => a.IsFocused);
+                if (focuesedApp == null)
+                {
+                    DebuggingUtils.Dbg("FocusedApp is not exist. Change app status to default");
+                    ViewModel.ChangeCurrentStatus(AppsStatus.Default);
+                    return;
+                }
+            }
+
             DebuggingUtils.Dbg("AppsListStateUpdate, status = " + status.ToString() + ", tag = " + tag);
             foreach (AppShortcutInfo item in InstalledApps)
             {
                 item.CurrentStateDescription = item.StateDescriptions[tag];
                 switch (status)
                 {
+                    case AppsStatus.Default:
+                        item.IsChecked = false;
+                        item.IsDim = false;
+                        item.IsShowOptions = false;
+                        break;
                     case AppsStatus.Pin:
-                        item.SetChecked(item.IsPinned);
+                        item.IsChecked = item.IsPinned;
+                        break;
+                    case AppsStatus.LongPress:
+                        if (item.IsFocused)
+                        {
+                            item.IsShowOptions = true;
+                        }
+                        else
+                        {
+                            item.IsDim = true;
+                        }
+
                         break;
+                    case AppsStatus.Delete:
+                        if (!item.IsRemovable)
+                        {
+                            item.IsDim = true;
+                        }
 
-                    default:
-                        item.SetChecked(false);
+                        item.IsChecked = false;
                         break;
                 }
 
-                item.SetPinned(PinnedApps.ContainsKey(item.AppID));
+                item.IsPinned = PinnedApps.ContainsKey(item.AppID);
             }
 
             ViewModel.OnPropertyChanged("InstalledAppList");
         }
 
-        // Just use to update list view which is binding
+        /// <summary>
+        /// A method refresh InstalledApps
+        /// </summary>
         private void RefreshApps()
         {
+            // Only updating elements of InstalledApps is not update the GUI.
             InstalledApps = new List<AppShortcutInfo>(InstalledApps);
             ViewModel.OnPropertyChanged("InstalledAppList");
         }
 
+        /// <summary>
+        /// A method sorts InstalledApps according to parameter
+        /// </summary>
+        /// <param name="sortOption">The option for sorting InstalledApps</param>
+        /// <see cref="SortingOptions"></see>
         public void SortApps(SortingOptions sortOption)
         {
             AppsListSorter.GetSortedAppsList(sortOption, ref InstalledApps);
             RefreshApps();
         }
 
+        /// <summary>
+        /// A method reloads PinnedApps from AppShortcutController
+        /// </summary>
         public async void ResetPinnedApps()
         {
             PinnedApps = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs();
         }
 
+        /// <summary>
+        /// A method updates list about pinned application to AppShortcutController
+        /// </summary>
         public void UpdatePinnedApps()
         {
             List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>();
             foreach (var item in PinnedApps)
             {
-                DebuggingUtils.Dbg("Pinned App : " + item.Key);
                 pinnedAppList.Add(new AppShortcutInfo()
                 {
                     AppID = item.Key,
@@ -245,78 +467,30 @@ namespace TVApps.ViewModels
             TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList);
         }
 
-        public void RemovePinnedApp(string AppID)
-        {
-            if (PinnedApps.ContainsKey(AppID))
-            {
-                PinnedApps.Remove(AppID);
-                UpdatePinnedApps();
-            }
-        }
-
-        public void HideLongPressedApp(string appId)
-        {
-            InstalledApps = new List<AppShortcutInfo>(InstalledApps);
-            AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
-            if (longPressedApp != null)
-            {
-                DebuggingUtils.Dbg("Hide the app icon : " + longPressedApp.AppID);
-                longPressedApp.SetVisible(false);
-            }
-        }
-
-        public void ShowLongPressedApp(string appId)
-        {
-            InstalledApps = new List<AppShortcutInfo>(InstalledApps);
-            AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
-            if (longPressedApp != null)
-            {
-                DebuggingUtils.Dbg("Show the app icon : " + longPressedApp.AppID);
-                longPressedApp.SetVisible(true);
-            }
-        }
-
-        public void SetAppItemDim(string appId)
-        {
-            InstalledApps = new List<AppShortcutInfo>(InstalledApps);
-            foreach (AppShortcutInfo app in InstalledApps)
-            {
-                if (!app.AppID.Equals(appId))
-                {
-                    app.SetDim(true);
-                }
-            }
-        }
-
-        public void UnsetAppItemDim(string appId)
-        {
-            InstalledApps = new List<AppShortcutInfo>(InstalledApps);
-            foreach (AppShortcutInfo app in InstalledApps)
-            {
-                if (!app.AppID.Equals(appId))
-                {
-                    app.SetDim(false);
-                }
-            }
-        }
-
+        /// <summary>
+        /// A method changes visible state of option menu to true
+        /// </summary>
+        /// <param name="appId">The ID of application for showing option menu</param>
         public void ShowLongPressOption(string appId)
         {
-            InstalledApps = new List<AppShortcutInfo>(InstalledApps);
             AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
             if (longPressedApp != null)
             {
-                longPressedApp.ShowOptions();
+                longPressedApp.IsDim = false;
+                longPressedApp.IsShowOptions = true;
             }
         }
 
+        /// <summary>
+        /// A method changes visible state of option menu to false
+        /// </summary>
+        /// <param name="appId">The ID of application for hiding option menu</param>
         public void HideLongPressOption(string appId)
         {
-            InstalledApps = new List<AppShortcutInfo>(InstalledApps);
             AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
             if (longPressedApp != null)
             {
-                longPressedApp.HideOptions();
+                longPressedApp.IsShowOptions = false;
             }
         }
     }