Skip to content

Commit

Permalink
[Files] Implement methods to update the store when going online/offline
Browse files Browse the repository at this point in the history
When the device connection status changes, this status gets updated in
the store along with the `isDisabled` state of ODFS, when relevant.

Bug: b:293547300
Change-Id: I909012211b922530d09990dd9f9781eea5318931
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4790552
Reviewed-by: Luciano Pacheco <lucmult@chromium.org>
Commit-Queue: Jeremie Boulic <jboulic@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1188151}
  • Loading branch information
Jérémie Boulic authored and Chromium LUCI CQ committed Aug 25, 2023
1 parent 5cd22ad commit 13d0563
Show file tree
Hide file tree
Showing 9 changed files with 166 additions and 4 deletions.
4 changes: 4 additions & 0 deletions chrome/browser/ash/file_manager/file_manager_jstest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@ IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ReducerAndroidApps) {
RunTestURL("state/ducks/android_apps_unittest.js");
}

IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ReducerDevice) {
RunTestURL("state/ducks/device_unittest.js");
}

IN_PROC_BROWSER_TEST_F(FileManagerJsTest, ReducerFolderShortcuts) {
RunTestURL("state/ducks/folder_shortcuts_unittest.js");
}
Expand Down
10 changes: 10 additions & 0 deletions ui/file_manager/file_manager/externs/ts/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,11 +374,21 @@ export let Volume;
*/
export let VolumeMap;

/**
* This carries the state related to physical user device.
*
* @typedef {{
* connection: (chrome.fileManagerPrivate.DeviceConnectionState),
* }}
*/
export let Device;

/**
* Files app's state.
* @typedef {{
* allEntries: !Object<!FileKey, !FileData>,
* currentDirectory: (CurrentDirectory|undefined),
* device: !Device,
* search: (!SearchData|undefined),
* navigation: !NavigationTree,
* volumes: !Object<!VolumeId, !Volume>,
Expand Down
5 changes: 3 additions & 2 deletions ui/file_manager/file_manager/foreground/js/file_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ import {FakeEntry, FilesAppDirEntry} from '../../externs/files_app_entry_interfa
import {ForegroundWindow} from '../../externs/foreground_window.js';
import {PropStatus} from '../../externs/ts/state.js';
import {Store} from '../../externs/ts/store.js';
import {updatePreferences} from '../../state/ducks/preferences.js';
import {updateBulkPinProgress} from '../../state/ducks/bulk_pinning.js';
import {updateDeviceConnectionState} from '../../state/ducks/device.js';
import {updatePreferences} from '../../state/ducks/preferences.js';
import {updateSearch} from '../../state/ducks/search.js';
import {addUiEntry, removeUiEntry} from '../../state/ducks/ui_entries.js';
import {trashRootKey} from '../../state/ducks/volumes.js';
Expand Down Expand Up @@ -1810,7 +1811,7 @@ export class FileManager extends EventTarget {
* @private
*/
updateDeviceConnectionState_(state) {
// TODO(jboulic): Update device connection state in the store.
this.store_.dispatch(updateDeviceConnectionState({connection: state}));
}

/**
Expand Down
5 changes: 4 additions & 1 deletion ui/file_manager/file_manager/state/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {AddChildEntriesAction, ClearStaleCachedEntriesAction, UpdateMetadataActi
import {ChangeDirectoryAction, ChangeFileTasksAction, ChangeSelectionAction, UpdateDirectoryContentAction} from './actions/current_directory.js';
import {AddAndroidAppsAction} from './ducks/android_apps.js';
import {UpdateBulkPinProgressAction} from './ducks/bulk_pinning.js';
import {UpdateDeviceConnectionStateAction} from './ducks/device.js';
import {AddFolderShortcutAction, RefreshFolderShortcutAction, RemoveFolderShortcutAction} from './ducks/folder_shortcuts.js';
import {RefreshNavigationRootsAction, UpdateNavigationEntryAction} from './ducks/navigation.js';
import {UpdatePreferencesAction} from './ducks/preferences.js';
Expand All @@ -27,7 +28,8 @@ export type Action = AddVolumeAction|RemoveVolumeAction|
UpdateMetadataAction|RefreshFolderShortcutAction|AddFolderShortcutAction|
RemoveFolderShortcutAction|AddAndroidAppsAction|AddChildEntriesAction|
UpdateNavigationEntryAction|UpdateBulkPinProgressAction|
UpdatePreferencesAction|UpdateIsInteractiveVolumeAction;
UpdatePreferencesAction|UpdateIsInteractiveVolumeAction|
UpdateDeviceConnectionStateAction;


/** Enum to identify every Action in Files app. */
Expand All @@ -53,4 +55,5 @@ export const enum ActionType {
UPDATE_BULK_PIN_PROGRESS = 'update-bulk-pin-progress',
UPDATE_PREFERENCES = 'update-preferences',
UPDATE_IS_INTERACTIVE_VOLUME = 'update-is-interactive-volume',
UPDATE_DEVICE_CONNECTION_STATE = 'update-device-connection-state',
}
76 changes: 76 additions & 0 deletions ui/file_manager/file_manager/state/ducks/device.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {util} from '../../common/js/util.js';
import {State, Volume} from '../../externs/ts/state.js';
import {addReducer, BaseAction, Reducer, ReducersMap} from '../../lib/base_store.js';
import {Action, ActionType} from '../actions.js';

/** Map of actions to reducers for the device slice. */
export const deviceReducersMap: ReducersMap<State, Action> = new Map();

/** Action to update the device connection state in the store. */
export interface UpdateDeviceConnectionStateAction extends BaseAction {
type: ActionType.UPDATE_DEVICE_CONNECTION_STATE;
payload: {
connection: chrome.fileManagerPrivate.DeviceConnectionState,
};
}

function updateDeviceConnectionStateReducer(
currentState: State,
payload: UpdateDeviceConnectionStateAction['payload']): State {
let device: State['device']|undefined;
let volumes: State['volumes']|undefined;

// Device connection.
if (payload.connection !== currentState.device.connection) {
device = {
...currentState.device,
connection: payload.connection,
};
}

// Find ODFS volume(s) and disable it (or them) if offline.
const disableODFS = payload.connection ===
chrome.fileManagerPrivate.DeviceConnectionState.OFFLINE;
for (const volume of Object.values<Volume>(currentState.volumes)) {
if (!util.isOneDriveId(volume.providerId) ||
volume.isDisabled === disableODFS) {
continue;
}
if (!volumes) {
volumes = {
...currentState.volumes,
};
}
volumes[volume.volumeId] = {
...volumes[volume.volumeId],
isDisabled: disableODFS,
};
}

if (!device && !volumes) {
return currentState;
}

const newState = {
...currentState,
};

if (device) {
newState.device = device;
}

if (volumes) {
newState.volumes = volumes;
}

return newState;
}

export const updateDeviceConnectionState = addReducer(
ActionType.UPDATE_DEVICE_CONNECTION_STATE,
updateDeviceConnectionStateReducer as Reducer<State, Action>,
deviceReducersMap);
62 changes: 62 additions & 0 deletions ui/file_manager/file_manager/state/ducks/device_unittest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import {assertEquals, assertFalse} from 'chrome://webui-test/chromeos/chai_assert.js';

import {MockVolumeManager} from '../../background/js/mock_volume_manager.js';
import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
import {State} from '../../externs/ts/state.js';
import {constants} from '../../foreground/js/constants.js';
import {createFakeVolumeMetadata, setupStore, waitDeepEquals} from '../for_tests.js';
import {getEmptyState, getStore, Store} from '../store.js';

import {updateDeviceConnectionState} from './device.js';
import {convertVolumeInfoAndMetadataToVolume} from './volumes.js';

let store: Store;

export function setUp() {
store = getStore();
store.init(getEmptyState());
}

export async function testUpdateDeviceConnection(done: () => void) {
const volumeInfo = MockVolumeManager.createMockVolumeInfo(
VolumeManagerCommon.VolumeType.PROVIDED, 'odfs', 'OneDrive', '',
constants.ODFS_EXTENSION_ID, '');
const ODFSVolume = convertVolumeInfoAndMetadataToVolume(
volumeInfo, createFakeVolumeMetadata(volumeInfo));

const initialState = getEmptyState();
initialState.volumes[ODFSVolume.volumeId] = ODFSVolume;
const store = setupStore(initialState);

assertEquals(
chrome.fileManagerPrivate.DeviceConnectionState.ONLINE,
store.getState().device.connection);
assertFalse(store.getState().volumes[ODFSVolume.volumeId].isDisabled);

// Dispatch an action to set |connection| for the device to OFFLINE.
store.dispatch(updateDeviceConnectionState({
connection: chrome.fileManagerPrivate.DeviceConnectionState.OFFLINE,
}));

// Expect the volume to be set to disabled.
const want: Partial<State> = {
volumes: {
[ODFSVolume.volumeId]: {
...ODFSVolume,
isDisabled: true,
},
},
};
await waitDeepEquals(store, want, (state) => ({
volumes: state.volumes,
}));
assertEquals(
chrome.fileManagerPrivate.DeviceConnectionState.OFFLINE,
store.getState().device.connection);

done();
}
2 changes: 2 additions & 0 deletions ui/file_manager/file_manager/state/reducers/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {State} from '../../externs/ts/state.js';
import {Action, ActionType} from '../actions.js';
import {androidAppsReducersMap} from '../ducks/android_apps.js';
import {bulkPinningReducersMap} from '../ducks/bulk_pinning.js';
import {deviceReducersMap} from '../ducks/device.js';
import {folderShortcutsReducersMap} from '../ducks/folder_shortcuts.js';
import {navigationReducersMap} from '../ducks/navigation.js';
import {preferencesReducersMap} from '../ducks/preferences.js';
Expand All @@ -26,6 +27,7 @@ const rootReducersMap = new Map([
...folderShortcutsReducersMap,
...navigationReducersMap,
...preferencesReducersMap,
...deviceReducersMap,
]);

/**
Expand Down
3 changes: 3 additions & 0 deletions ui/file_manager/file_manager/state/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export function getEmptyState(): State {
return {
allEntries: {},
currentDirectory: undefined,
device: {
connection: chrome.fileManagerPrivate.DeviceConnectionState.ONLINE,
},
search: {
query: undefined,
status: undefined,
Expand Down
3 changes: 2 additions & 1 deletion ui/file_manager/file_names.gni
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,14 @@ ts_files = [
# Ducks.
"file_manager/state/ducks/android_apps.ts",
"file_manager/state/ducks/bulk_pinning.ts",
"file_manager/state/ducks/device.ts",
"file_manager/state/ducks/folder_shortcuts.ts",
"file_manager/state/ducks/navigation.ts",
"file_manager/state/ducks/preferences.ts",
"file_manager/state/ducks/search.ts",
"file_manager/state/ducks/ui_entries.ts",
"file_manager/state/ducks/volumes.ts",


# Containers.
"file_manager/containers/breadcrumb_container.ts",
"file_manager/containers/cloud_panel_container.ts",
Expand Down Expand Up @@ -403,6 +403,7 @@ ts_test_files = [
# Ducks:
"file_manager/state/ducks/android_apps_unittest.ts",
"file_manager/state/ducks/bulk_pinning_unittest.ts",
"file_manager/state/ducks/device_unittest.ts",
"file_manager/state/ducks/folder_shortcuts_unittest.ts",
"file_manager/state/ducks/navigation_unittest.ts",
"file_manager/state/ducks/preferences_unittest.ts",
Expand Down

0 comments on commit 13d0563

Please sign in to comment.