2 * Copyright (c) 2017 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 using LibTVRefCommonPortable.DataModels;
18 using LibTVRefCommonPortable.Utils;
19 using System.Collections.Generic;
21 using System.Threading;
22 using System.Threading.Tasks;
25 namespace TVApps.ViewModels
28 /// A class contains installed, pinned application list.
29 /// The MainPageViewModel changes state of application item by AppsHolder's API
31 internal class AppsHolder
34 /// The interface for interaction with view model
36 IAppsViewModel ViewModel;
39 /// A flag indicates how to sort InstalledApps
41 /// <see cref="SortingOptions"/>
42 public SortingOptions SortingOption;
45 /// A list contains AppShortcutInfo about installed applications
47 /// <see cref="AppShortcutInfo"/>
48 public List<AppShortcutInfo> InstalledApps;
51 /// A dictionary contains ID of pinned applications
53 public Dictionary<string, string> PinnedApps;
56 /// A name of pinned application
58 public string PinnedAppName;
61 /// A name of unpinned application
63 public string UnpinnedAppName;
65 public bool IsSelectedExceeds;
69 /// Initializes installed and pinned app list
71 /// <param name="ViewModel">The instance of MainPageViewModel</param>
72 public AppsHolder(IAppsViewModel ViewModel)
74 this.ViewModel = ViewModel;
76 InstalledApps = new List<AppShortcutInfo>();
77 PinnedApps = new Dictionary<string, string>();
79 App.SetAppInstalledListener((s, e) =>
84 App.SetAppUninstalledListener((s, e) =>
88 SynchronizationContext.Current.Post((o) =>
96 /// A method gets installed, pinned application information from AppShortcutController.
97 /// And adds state descriptions about pin, delete, long press state
99 private async void SetApps()
101 var pinnedAppsGettingTask = TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs();
102 var installedAppsGettingTask = TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetInstalledApps();
104 await Task.WhenAll(pinnedAppsGettingTask, installedAppsGettingTask);
106 PinnedApps = pinnedAppsGettingTask.Result;
107 ViewModel.OnPropertyChanged("SumOfCheckedApp");
109 var installedApps = installedAppsGettingTask.Result;
111 foreach (AppShortcutInfo item in installedApps)
113 if (item.CurrentStateDescription == null)
115 DebuggingUtils.Err("Invalid AppshortcutInfo, " + item.AppID);
119 item.IsPinned = PinnedApps.ContainsKey(item.AppID);
121 CommandAction pinAction = new CommandAction()
123 NextStateDescription = AppsStatus.Pin.ToString().ToLower(),
124 CommandParameter = item.AppID
126 pinAction.Command += new System.EventHandler<string>((s, arg) =>
131 var pinStateDescription = new StateDescription()
133 Label = item.CurrentStateDescription.Label,
134 IconPath = item.CurrentStateDescription.IconPath,
138 item.StateDescriptions.Add(AppsStatus.Pin.ToString().ToLower(), pinStateDescription);
140 CommandAction checkDeleteAction = new CommandAction()
142 NextStateDescription = AppsStatus.Delete.ToString().ToLower(),
143 CommandParameter = item.AppID
145 checkDeleteAction.Command += new System.EventHandler<string>((s, arg) =>
150 var deleteStateDescription = new StateDescription()
152 Label = item.CurrentStateDescription.Label,
153 IconPath = item.CurrentStateDescription.IconPath,
154 Action = checkDeleteAction,
157 item.StateDescriptions.Add(AppsStatus.Delete.ToString().ToLower(), deleteStateDescription);
159 CommandAction longPressAction = new CommandAction()
161 NextStateDescription = AppsStatus.LongPress.ToString().ToLower(),
162 CommandParameter = item.AppID
164 pinAction.Command += new System.EventHandler<string>((s, arg) =>
169 var longPressStateDescription = new StateDescription()
171 Label = item.CurrentStateDescription.Label,
172 IconPath = item.CurrentStateDescription.IconPath,
173 Action = longPressAction,
175 item.StateDescriptions.Add(AppsStatus.LongPress.ToString().ToLower(), longPressStateDescription);
178 InstalledApps = installedApps.ToList();
179 SortApps(SortingOption);
180 UpdateStateDescription(ViewModel.CurrentStatus);
184 /// A method changes pin state of AppShortcutInfo
185 /// And adds or removes application ID in PinnedApps
187 /// <param name="appID">The ID of application for changing pin state</param>
188 private void PinToggle(string appID)
190 AppShortcutInfo selectedApp = InstalledApps.FirstOrDefault(a => a.AppID == appID);
191 if (selectedApp == null)
193 DebuggingUtils.Err("Failed to Pin!!!, Nothing selected, AppID = " + appID);
197 if (PinnedApps.ContainsKey(appID))
199 DebuggingUtils.Dbg("UnPin! : " + selectedApp);
200 selectedApp.IsChecked = false;
201 selectedApp.IsPinned = false;
202 PinnedApps.Remove(appID);
203 UnpinnedAppName = selectedApp.CurrentStateDescription.Label;
204 ViewModel.OnPropertyChanged("UnpinnedAppName");
208 if (PinnedApps.Count >= 10)
210 IsSelectedExceeds = true;
211 ViewModel.OnPropertyChanged("IsSelectedExceeds");
215 DebuggingUtils.Dbg("Pin! : " + selectedApp);
216 selectedApp.IsChecked = true;
217 selectedApp.IsPinned = true;
218 PinnedApps.Add(appID, appID);
219 PinnedAppName = selectedApp.CurrentStateDescription.Label;
220 ViewModel.OnPropertyChanged("PinnedAppName");
224 ViewModel.OnPropertyChanged("SumOfCheckedApp");
228 /// A method changes pin state of AppShortcutInfo by the Option Menu Pin/Unpin button
229 /// And adds or removes application ID in PinnedApps
231 /// <param name="appID">The ID of application for changing pin state</param>
232 public void OptionMenuPinToggle(string appID)
234 AppShortcutInfo SelectedApp = InstalledApps.FirstOrDefault(a => a.AppID.Equals(appID));
235 if (SelectedApp == null)
237 DebuggingUtils.Err("Failed to get selected app : " + appID);
241 if (PinnedApps.ContainsKey(appID))
243 DebuggingUtils.Dbg("Unpin : " + appID);
244 SelectedApp.IsPinned = false;
245 PinnedApps.Remove(appID);
249 DebuggingUtils.Dbg("Pin : " + appID);
250 SelectedApp.IsPinned = true;
251 PinnedApps.Add(appID, appID);
254 ViewModel.OnPropertyChanged("SumOfCheckedApp");
256 this.UpdatePinnedApps();
257 ViewModel.ChangeCurrentStatus(AppsStatus.Default);
261 /// A method for changing status of applications to Default
263 public void ChangeToDefaultStatus()
265 ViewModel.ChangeCurrentStatus(AppsStatus.Default);
269 /// Removes the pinned app by app ID
271 /// <param name="removableAppsList">The apps list to remove at the pinned app list</param>
272 public void RemovePinnedApp(List<string> removableAppsList)
274 foreach (string app in removableAppsList)
276 if (PinnedApps.ContainsKey(app))
278 DebuggingUtils.Dbg("UnPin! : " + app);
280 PinnedApps.Remove(app);
288 /// A method for checking the application is removable
289 /// If the application is removable, show Delete Popup
291 /// <param name="appID">The ID of application for checking</param>
292 public void CheckDeleteApp(string appID)
294 DebuggingUtils.Dbg("check that the app( " + appID + ") can be deleted");
296 if (!ApplicationManagerUtils.Instance.GetAppInfoRemovable(appID))
298 DebuggingUtils.Dbg("This app is not removable : " + appID);
302 string appLabel = null;
303 if (ApplicationManagerUtils.Instance.GetInstalledApplication(appID).TryGetValue("Label", out appLabel))
305 ViewModel.ShowDeletePopup(appLabel);
310 /// A method sends application delete request
311 /// If application is pinned, removes in PinnedApps
313 /// <param name="appID">The ID of application for deleting</param>
314 public void DeleteApp(string appID)
316 // if the app to be deleted is pinned, remove the app in the pinned apps list
317 string pkgID = PackageManagerUtils.GetPackageIDByAppID(appID);
320 DebuggingUtils.Err("Failed to get the package ID by app ID(" + appID + ")");
325 List<string> appsList = PackageManagerUtils.GetApplicationsByPkgID(pkgID);
326 if (appsList == null || appsList.Count == 0)
328 DebuggingUtils.Err("Failed to get the apps list by package ID(" + pkgID + ")");
333 ViewModel.ChangeCurrentStatus(AppsStatus.Default);
335 if (PackageManagerUtils.UninstallPackageByAppID(appID) == false)
337 DebuggingUtils.Err("App uninstall is failed!!!, " + appID);
341 var removed = from app in InstalledApps
342 where app.AppID == appID
344 InstalledApps.Remove(removed.First());
345 foreach (var item in InstalledApps)
347 DebuggingUtils.Dbg("- " + item.AppID);
350 RemovePinnedApp(appsList);
356 /// A method changes long press state of AppShortcutInfo
358 /// <param name="AppID">The ID of application for showing option menu</param>
359 private void LongPressApp(string AppID)
361 DebuggingUtils.Dbg(" +++++ long press app : " + AppID);
365 /// A method updates state description of applications
367 /// <param name="status">The state name for updating state description</param>
368 public void UpdateStateDescription(AppsStatus status)
370 string tag = status.ToString().ToLower();
372 if (status == AppsStatus.LongPress)
374 AppShortcutInfo focuesedApp = InstalledApps.Find(a => a.IsFocused);
375 if (focuesedApp == null)
377 DebuggingUtils.Dbg("FocusedApp is not exist. Change app status to default");
378 ViewModel.ChangeCurrentStatus(AppsStatus.Default);
383 DebuggingUtils.Dbg("AppsListStateUpdate, status = " + status.ToString() + ", tag = " + tag);
384 foreach (AppShortcutInfo item in InstalledApps)
386 item.CurrentStateDescription = item.StateDescriptions[tag];
389 case AppsStatus.Default:
390 item.IsChecked = false;
392 item.IsShowOptions = false;
395 item.IsChecked = item.IsPinned;
397 case AppsStatus.LongPress:
400 item.IsShowOptions = true;
408 case AppsStatus.Delete:
409 if (!item.IsRemovable)
414 item.IsChecked = false;
418 item.IsPinned = PinnedApps.ContainsKey(item.AppID);
421 ViewModel.OnPropertyChanged("InstalledAppList");
425 /// A method refresh InstalledApps
427 private void RefreshApps()
429 // Only updating elements of InstalledApps is not update the GUI.
430 InstalledApps = new List<AppShortcutInfo>(InstalledApps);
431 ViewModel.OnPropertyChanged("InstalledAppList");
435 /// A method sorts InstalledApps according to parameter
437 /// <param name="sortOption">The option for sorting InstalledApps</param>
438 /// <see cref="SortingOptions"></see>
439 public void SortApps(SortingOptions sortOption)
441 AppsListSorter.GetSortedAppsList(sortOption, ref InstalledApps);
446 /// A method reloads PinnedApps from AppShortcutController
448 public async void ResetPinnedApps()
450 PinnedApps = await TVHomeImpl.GetInstance.AppShortcutControllerInstance.GetPinnedAppsAppIDs();
454 /// A method updates list about pinned application to AppShortcutController
456 public void UpdatePinnedApps()
458 List<AppShortcutInfo> pinnedAppList = new List<AppShortcutInfo>();
459 foreach (var item in PinnedApps)
461 pinnedAppList.Add(new AppShortcutInfo()
467 TVHomeImpl.GetInstance.AppShortcutControllerInstance.UpdatePinnedApps(pinnedAppList);
471 /// A method changes visible state of option menu to true
473 /// <param name="appId">The ID of application for showing option menu</param>
474 public void ShowLongPressOption(string appId)
476 AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
477 if (longPressedApp != null)
479 longPressedApp.IsDim = false;
480 longPressedApp.IsShowOptions = true;
485 /// A method changes visible state of option menu to false
487 /// <param name="appId">The ID of application for hiding option menu</param>
488 public void HideLongPressOption(string appId)
490 AppShortcutInfo longPressedApp = InstalledApps.Find(app => app.AppID.Equals(appId));
491 if (longPressedApp != null)
493 longPressedApp.IsShowOptions = false;